mirror of
https://github.com/jeffvli/feishin.git
synced 2026-06-13 15:53:18 +02:00
progress on subsonic api
This commit is contained in:
@@ -1,18 +1,49 @@
|
||||
import { components } from './subsonic-schema.d';
|
||||
import { components, paths } from './subsonic-schema.d';
|
||||
|
||||
import { ssType } from '/@/shared/api/subsonic/subsonic-types';
|
||||
import { Album } from '/@/shared/types/domain/album-domain-types';
|
||||
import { Album, AlbumListSortOptions } from '/@/shared/types/domain/album-domain-types';
|
||||
import { Artist, RelatedArtist } from '/@/shared/types/domain/artist-domain-types';
|
||||
import { Genre, RelatedGenre } from '/@/shared/types/domain/genre-domain-types';
|
||||
import { Playlist } from '/@/shared/types/domain/playlist-domain-types';
|
||||
import { ServerListItem, ServerType } from '/@/shared/types/domain/server-domain-types';
|
||||
import { LibraryItem } from '/@/shared/types/domain/shared-domain-types';
|
||||
import { Song } from '/@/shared/types/domain/song-domain-types';
|
||||
import { User } from '/@/shared/types/domain/user-domain-types';
|
||||
import { formatDate } from '/@/shared/utils/format-date';
|
||||
|
||||
type AlbumSortType = paths['/rest/getAlbumList2']['get']['parameters']['query']['type'];
|
||||
|
||||
const defaultSortType: AlbumSortType = 'alphabeticalByName';
|
||||
|
||||
const albumSortByMap: Record<AlbumListSortOptions, AlbumSortType> = {
|
||||
[AlbumListSortOptions.ALBUM_ARTIST]: 'alphabeticalByArtist',
|
||||
[AlbumListSortOptions.ARTIST]: defaultSortType,
|
||||
[AlbumListSortOptions.COMMUNITY_RATING]: defaultSortType,
|
||||
[AlbumListSortOptions.CRITIC_RATING]: defaultSortType,
|
||||
[AlbumListSortOptions.DATE_ADDED]: 'newest',
|
||||
[AlbumListSortOptions.DATE_PLAYED]: 'recent',
|
||||
[AlbumListSortOptions.DURATION]: defaultSortType,
|
||||
[AlbumListSortOptions.IS_FAVORITE]: defaultSortType,
|
||||
[AlbumListSortOptions.NAME]: 'alphabeticalByName',
|
||||
[AlbumListSortOptions.PLAY_COUNT]: 'frequent',
|
||||
[AlbumListSortOptions.RANDOM]: defaultSortType,
|
||||
[AlbumListSortOptions.RATING]: 'highest',
|
||||
[AlbumListSortOptions.RELEASE_DATE]: defaultSortType,
|
||||
[AlbumListSortOptions.TRACK_COUNT]: defaultSortType,
|
||||
[AlbumListSortOptions.YEAR]: defaultSortType,
|
||||
};
|
||||
|
||||
export const normalize = {
|
||||
_sort: {
|
||||
album: (option: AlbumListSortOptions) => {
|
||||
return albumSortByMap[option] || defaultSortType;
|
||||
},
|
||||
},
|
||||
album: (
|
||||
item: components['schemas']['AlbumID3'] | components['schemas']['AlbumID3WithSongs'],
|
||||
item:
|
||||
| components['schemas']['AlbumID3']
|
||||
| components['schemas']['AlbumID3WithSongs']
|
||||
| components['schemas']['Child'],
|
||||
server: ServerListItem,
|
||||
): Album => {
|
||||
const imageUrl = item.coverArt ? getCoverArtUrl(item.coverArt, server) : null;
|
||||
@@ -24,7 +55,7 @@ export const normalize = {
|
||||
artistName: item.artist || null,
|
||||
artists: getArtistList(item.artists, item.artistId, item.artist),
|
||||
comment: null,
|
||||
createdDate: item.created,
|
||||
createdDate: item.created || null,
|
||||
discTitles: getDiscTitles(item),
|
||||
displayArtist: null,
|
||||
duration: getDuration(item.duration),
|
||||
@@ -33,12 +64,12 @@ export const normalize = {
|
||||
id: item.id.toString(),
|
||||
imagePlaceholderUrl: null,
|
||||
imageUrl,
|
||||
isCompilation: item.isCompilation || null,
|
||||
isCompilation: getIsCompilation(item),
|
||||
mbzId: item.musicBrainzId || null,
|
||||
mbzReleaseGroupId: null,
|
||||
missing: null,
|
||||
moods: getMoods(item),
|
||||
name: item.name,
|
||||
name: getName(item),
|
||||
originalReleaseDate: getOriginalReleaseDate(item),
|
||||
participants: {},
|
||||
recordLabels: getRecordLabels(item),
|
||||
@@ -46,8 +77,8 @@ export const normalize = {
|
||||
releaseTypes: getReleaseTypes(item),
|
||||
releaseYear: item.year || null,
|
||||
size: null,
|
||||
songCount: item.songCount,
|
||||
sortName: item.sortName || item.name,
|
||||
songCount: 'songCount' in item ? item.songCount : null,
|
||||
sortName: getSortName(item),
|
||||
tags: {},
|
||||
updatedDate: null,
|
||||
userFavorite: Boolean(item.starred),
|
||||
@@ -55,7 +86,7 @@ export const normalize = {
|
||||
userLastPlayedDate: item.played || null,
|
||||
userPlayCount: item.playCount ?? null,
|
||||
userRating: item.userRating || null,
|
||||
version: item.version || null,
|
||||
version: 'version' in item ? item.version || null : null,
|
||||
};
|
||||
},
|
||||
albumArtist: (
|
||||
@@ -167,6 +198,28 @@ export const normalize = {
|
||||
userRating: item.userRating || null,
|
||||
};
|
||||
},
|
||||
user: (item: components['schemas']['User'], server: ServerListItem): User => {
|
||||
return {
|
||||
_itemType: LibraryItem.USER,
|
||||
_serverId: server.id,
|
||||
_serverType: ServerType.SUBSONIC,
|
||||
id: item.username,
|
||||
permissions: {
|
||||
'jukebox.manage': item.jukeboxRole,
|
||||
'media.download': item.downloadRole,
|
||||
'media.folder': item.folder?.map((folder) => folder.toString()) || [],
|
||||
'media.share': item.shareRole,
|
||||
'media.stream': item.streamRole,
|
||||
'media.upload': item.uploadRole,
|
||||
'playlist.create': item.playlistRole,
|
||||
'playlist.delete': item.playlistRole,
|
||||
'playlist.edit': item.playlistRole,
|
||||
'server.admin': item.adminRole,
|
||||
'user.edit': item.settingsRole,
|
||||
},
|
||||
username: item.username,
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
function getArtistList(
|
||||
@@ -200,12 +253,19 @@ function getCoverArtUrl(id: string, server: ServerListItem) {
|
||||
}
|
||||
|
||||
function getDiscTitles(
|
||||
item: components['schemas']['AlbumID3'] | components['schemas']['AlbumID3WithSongs'],
|
||||
item:
|
||||
| components['schemas']['AlbumID3']
|
||||
| components['schemas']['AlbumID3WithSongs']
|
||||
| components['schemas']['Child'],
|
||||
) {
|
||||
return (item.discTitles || []).map((discTitle) => ({
|
||||
disc: discTitle.disc,
|
||||
title: discTitle.title,
|
||||
}));
|
||||
if ('discTitles' in item) {
|
||||
return (item.discTitles || []).map((discTitle) => ({
|
||||
disc: discTitle.disc,
|
||||
title: discTitle.title,
|
||||
}));
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
function getDuration(duration?: number) {
|
||||
@@ -214,12 +274,16 @@ function getDuration(duration?: number) {
|
||||
}
|
||||
|
||||
function getGainInfo(item: components['schemas']['Child']) {
|
||||
return item.replayGain && (item.replayGain.albumGain || item.replayGain.trackGain)
|
||||
? {
|
||||
album: item.replayGain.albumGain,
|
||||
track: item.replayGain.trackGain,
|
||||
}
|
||||
: null;
|
||||
if ('replayGain' in item) {
|
||||
return item.replayGain && (item.replayGain.albumGain || item.replayGain.trackGain)
|
||||
? {
|
||||
album: item.replayGain.albumGain,
|
||||
track: item.replayGain.trackGain,
|
||||
}
|
||||
: null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function getGenres(
|
||||
@@ -228,15 +292,19 @@ function getGenres(
|
||||
| components['schemas']['AlbumID3WithSongs']
|
||||
| components['schemas']['Child'],
|
||||
): RelatedGenre[] {
|
||||
if (item.genres) {
|
||||
return item.genres.map((genre) => ({
|
||||
if ('genres' in item) {
|
||||
return (item.genres || []).map((genre) => ({
|
||||
id: genre.name,
|
||||
imageUrl: null,
|
||||
name: genre.name,
|
||||
}));
|
||||
}
|
||||
|
||||
if (item.genre) {
|
||||
if ('genre' in item) {
|
||||
if (!item.genre) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return [
|
||||
{
|
||||
id: item.genre,
|
||||
@@ -249,26 +317,67 @@ function getGenres(
|
||||
return [];
|
||||
}
|
||||
|
||||
function getIsCompilation(
|
||||
item:
|
||||
| components['schemas']['AlbumID3']
|
||||
| components['schemas']['AlbumID3WithSongs']
|
||||
| components['schemas']['Child'],
|
||||
) {
|
||||
if ('isCompilation' in item) {
|
||||
return item.isCompilation || null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function getMoods(
|
||||
item:
|
||||
| components['schemas']['AlbumID3']
|
||||
| components['schemas']['AlbumID3WithSongs']
|
||||
| components['schemas']['Child'],
|
||||
) {
|
||||
return (item.moods || []).map((mood) => ({
|
||||
id: mood,
|
||||
name: mood,
|
||||
}));
|
||||
if ('moods' in item) {
|
||||
return (item.moods || []).map((mood) => ({
|
||||
id: mood,
|
||||
name: mood,
|
||||
}));
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
function getName(
|
||||
item:
|
||||
| components['schemas']['AlbumID3']
|
||||
| components['schemas']['AlbumID3WithSongs']
|
||||
| components['schemas']['Child'],
|
||||
) {
|
||||
if ('name' in item) {
|
||||
return item.name || '';
|
||||
}
|
||||
|
||||
if ('title' in item) {
|
||||
return item.title || '';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
function getOriginalReleaseDate(
|
||||
item: components['schemas']['AlbumID3'] | components['schemas']['AlbumID3WithSongs'],
|
||||
item:
|
||||
| components['schemas']['AlbumID3']
|
||||
| components['schemas']['AlbumID3WithSongs']
|
||||
| components['schemas']['Child'],
|
||||
) {
|
||||
return item.originalReleaseDate
|
||||
? formatDate.toUTCDate(
|
||||
`${item.originalReleaseDate.year}-${item.originalReleaseDate.month}-${item.originalReleaseDate.day}`,
|
||||
)
|
||||
: null;
|
||||
if ('originalReleaseDate' in item) {
|
||||
return item.originalReleaseDate
|
||||
? formatDate.toUTCDate(
|
||||
`${item.originalReleaseDate.year}-${item.originalReleaseDate.month}-${item.originalReleaseDate.day}`,
|
||||
)
|
||||
: null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function getParticipants(item: components['schemas']['Child']) {
|
||||
@@ -298,40 +407,86 @@ function getParticipants(item: components['schemas']['Child']) {
|
||||
}
|
||||
|
||||
function getPeakInfo(item: components['schemas']['Child']) {
|
||||
return item.replayGain && (item.replayGain.albumPeak || item.replayGain.trackPeak)
|
||||
? {
|
||||
album: item.replayGain.albumPeak,
|
||||
track: item.replayGain.trackPeak,
|
||||
}
|
||||
: null;
|
||||
if ('replayGain' in item) {
|
||||
return item.replayGain && (item.replayGain.albumPeak || item.replayGain.trackPeak)
|
||||
? {
|
||||
album: item.replayGain.albumPeak,
|
||||
track: item.replayGain.trackPeak,
|
||||
}
|
||||
: null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function getRecordLabels(
|
||||
item: components['schemas']['AlbumID3'] | components['schemas']['AlbumID3WithSongs'],
|
||||
item:
|
||||
| components['schemas']['AlbumID3']
|
||||
| components['schemas']['AlbumID3WithSongs']
|
||||
| components['schemas']['Child'],
|
||||
) {
|
||||
return (item.recordLabels || []).map((recordLabel) => ({
|
||||
id: recordLabel.name,
|
||||
name: recordLabel.name,
|
||||
}));
|
||||
if ('recordLabels' in item) {
|
||||
return (item.recordLabels || []).map((recordLabel) => ({
|
||||
id: recordLabel.name,
|
||||
name: recordLabel.name,
|
||||
}));
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
function getReleaseDate(
|
||||
item: components['schemas']['AlbumID3'] | components['schemas']['AlbumID3WithSongs'],
|
||||
item:
|
||||
| components['schemas']['AlbumID3']
|
||||
| components['schemas']['AlbumID3WithSongs']
|
||||
| components['schemas']['Child'],
|
||||
) {
|
||||
return item.releaseDate
|
||||
? formatDate.toUTCDate(
|
||||
`${item.releaseDate.year}-${item.releaseDate.month}-${item.releaseDate.day}`,
|
||||
)
|
||||
: null;
|
||||
if ('releaseDate' in item) {
|
||||
return item.releaseDate
|
||||
? formatDate.toUTCDate(
|
||||
`${item.releaseDate.year}-${item.releaseDate.month}-${item.releaseDate.day}`,
|
||||
)
|
||||
: null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function getReleaseTypes(
|
||||
item: components['schemas']['AlbumID3'] | components['schemas']['AlbumID3WithSongs'],
|
||||
item:
|
||||
| components['schemas']['AlbumID3']
|
||||
| components['schemas']['AlbumID3WithSongs']
|
||||
| components['schemas']['Child'],
|
||||
) {
|
||||
return (item.releaseTypes || []).map((releaseType) => ({
|
||||
id: releaseType,
|
||||
name: releaseType,
|
||||
}));
|
||||
if ('releaseTypes' in item) {
|
||||
return (item.releaseTypes || []).map((releaseType) => ({
|
||||
id: releaseType,
|
||||
name: releaseType,
|
||||
}));
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
function getSortName(
|
||||
item:
|
||||
| components['schemas']['AlbumID3']
|
||||
| components['schemas']['AlbumID3WithSongs']
|
||||
| components['schemas']['Child'],
|
||||
) {
|
||||
if ('sortName' in item) {
|
||||
return item.sortName || '';
|
||||
}
|
||||
|
||||
if ('name' in item) {
|
||||
return item.name || '';
|
||||
}
|
||||
|
||||
if ('title' in item) {
|
||||
return item.title || '';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
function getStreamUrl(id: string, server: ServerListItem) {
|
||||
|
||||
Reference in New Issue
Block a user