2023-04-24 01:21:29 -07:00
|
|
|
import { nanoid } from 'nanoid';
|
|
|
|
|
import { z } from 'zod';
|
|
|
|
|
import { ssType } from '/@/renderer/api/subsonic/subsonic-types';
|
2023-05-19 00:14:41 -07:00
|
|
|
import { QueueSong, LibraryItem, AlbumArtist, Album } from '/@/renderer/api/types';
|
2023-04-24 01:21:29 -07:00
|
|
|
import { ServerListItem, ServerType } from '/@/renderer/types';
|
|
|
|
|
|
|
|
|
|
const getCoverArtUrl = (args: {
|
2023-07-01 19:10:05 -07:00
|
|
|
baseUrl: string | undefined;
|
|
|
|
|
coverArtId?: string;
|
|
|
|
|
credential: string | undefined;
|
|
|
|
|
size: number;
|
2023-04-24 01:21:29 -07:00
|
|
|
}) => {
|
2023-07-01 19:10:05 -07:00
|
|
|
const size = args.size ? args.size : 250;
|
2023-04-24 01:21:29 -07:00
|
|
|
|
2023-07-01 19:10:05 -07:00
|
|
|
if (!args.coverArtId || args.coverArtId.match('2a96cbd8b46e442fc41c2b86b821562f')) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2023-04-24 01:21:29 -07:00
|
|
|
|
2023-07-01 19:10:05 -07:00
|
|
|
return (
|
|
|
|
|
`${args.baseUrl}/rest/getCoverArt.view` +
|
|
|
|
|
`?id=${args.coverArtId}` +
|
|
|
|
|
`&${args.credential}` +
|
|
|
|
|
'&v=1.13.0' +
|
|
|
|
|
'&c=feishin' +
|
|
|
|
|
`&size=${size}`
|
|
|
|
|
);
|
2023-04-24 01:21:29 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const normalizeSong = (
|
2023-07-01 19:10:05 -07:00
|
|
|
item: z.infer<typeof ssType._response.song>,
|
|
|
|
|
server: ServerListItem | null,
|
|
|
|
|
deviceId: string,
|
2023-04-24 01:21:29 -07:00
|
|
|
): QueueSong => {
|
2023-07-01 19:10:05 -07:00
|
|
|
const imageUrl =
|
|
|
|
|
getCoverArtUrl({
|
|
|
|
|
baseUrl: server?.url,
|
|
|
|
|
coverArtId: item.coverArt,
|
|
|
|
|
credential: server?.credential,
|
|
|
|
|
size: 100,
|
|
|
|
|
}) || null;
|
2023-04-24 01:21:29 -07:00
|
|
|
|
2023-07-01 19:10:05 -07:00
|
|
|
const streamUrl = `${server?.url}/rest/stream.view?id=${item.id}&v=1.13.0&c=feishin_${deviceId}&${server?.credential}`;
|
2023-04-24 01:21:29 -07:00
|
|
|
|
2023-07-01 19:10:05 -07:00
|
|
|
return {
|
|
|
|
|
album: item.album || '',
|
|
|
|
|
albumArtists: [
|
|
|
|
|
{
|
|
|
|
|
id: item.artistId || '',
|
|
|
|
|
imageUrl: null,
|
|
|
|
|
name: item.artist || '',
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
albumId: item.albumId || '',
|
|
|
|
|
artistName: item.artist || '',
|
|
|
|
|
artists: [
|
|
|
|
|
{
|
|
|
|
|
id: item.artistId || '',
|
|
|
|
|
imageUrl: null,
|
|
|
|
|
name: item.artist || '',
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
bitRate: item.bitRate || 0,
|
|
|
|
|
bpm: null,
|
|
|
|
|
channels: null,
|
|
|
|
|
comment: null,
|
|
|
|
|
compilation: null,
|
|
|
|
|
container: item.contentType,
|
|
|
|
|
createdAt: item.created,
|
|
|
|
|
discNumber: item.discNumber || 1,
|
2023-09-22 15:12:23 -07:00
|
|
|
discSubtitle: null,
|
2023-09-21 17:22:42 -07:00
|
|
|
duration: item.duration ? item.duration * 1000 : 0,
|
2023-09-22 00:06:13 +00:00
|
|
|
gain: null,
|
2023-07-01 19:10:05 -07:00
|
|
|
genres: item.genre
|
|
|
|
|
? [
|
|
|
|
|
{
|
|
|
|
|
id: item.genre,
|
2023-08-04 10:32:35 -07:00
|
|
|
imageUrl: null,
|
|
|
|
|
itemType: LibraryItem.GENRE,
|
2023-07-01 19:10:05 -07:00
|
|
|
name: item.genre,
|
|
|
|
|
},
|
|
|
|
|
]
|
|
|
|
|
: [],
|
|
|
|
|
id: item.id,
|
|
|
|
|
imagePlaceholderUrl: null,
|
|
|
|
|
imageUrl,
|
|
|
|
|
itemType: LibraryItem.SONG,
|
|
|
|
|
lastPlayedAt: null,
|
|
|
|
|
lyrics: null,
|
|
|
|
|
name: item.title,
|
|
|
|
|
path: item.path,
|
2023-09-22 00:06:13 +00:00
|
|
|
peak: null,
|
2023-07-01 19:10:05 -07:00
|
|
|
playCount: item?.playCount || 0,
|
|
|
|
|
releaseDate: null,
|
|
|
|
|
releaseYear: item.year ? String(item.year) : null,
|
|
|
|
|
serverId: server?.id || 'unknown',
|
|
|
|
|
serverType: ServerType.SUBSONIC,
|
|
|
|
|
size: item.size,
|
|
|
|
|
streamUrl,
|
|
|
|
|
trackNumber: item.track || 1,
|
|
|
|
|
uniqueId: nanoid(),
|
|
|
|
|
updatedAt: '',
|
|
|
|
|
userFavorite: item.starred || false,
|
|
|
|
|
userRating: item.userRating || null,
|
|
|
|
|
};
|
2023-04-24 01:21:29 -07:00
|
|
|
};
|
|
|
|
|
|
2023-05-19 00:14:41 -07:00
|
|
|
const normalizeAlbumArtist = (
|
2023-07-01 19:10:05 -07:00
|
|
|
item: z.infer<typeof ssType._response.albumArtist>,
|
|
|
|
|
server: ServerListItem | null,
|
2023-05-19 00:14:41 -07:00
|
|
|
): AlbumArtist => {
|
2023-07-01 19:10:05 -07:00
|
|
|
const imageUrl =
|
|
|
|
|
getCoverArtUrl({
|
|
|
|
|
baseUrl: server?.url,
|
|
|
|
|
coverArtId: item.coverArt,
|
|
|
|
|
credential: server?.credential,
|
|
|
|
|
size: 100,
|
|
|
|
|
}) || null;
|
2023-05-19 00:14:41 -07:00
|
|
|
|
2023-07-01 19:10:05 -07:00
|
|
|
return {
|
|
|
|
|
albumCount: item.albumCount ? Number(item.albumCount) : 0,
|
|
|
|
|
backgroundImageUrl: null,
|
|
|
|
|
biography: null,
|
|
|
|
|
duration: null,
|
|
|
|
|
genres: [],
|
|
|
|
|
id: item.id,
|
|
|
|
|
imageUrl,
|
|
|
|
|
itemType: LibraryItem.ALBUM_ARTIST,
|
|
|
|
|
lastPlayedAt: null,
|
2024-01-15 22:10:50 -08:00
|
|
|
mbz: null,
|
2023-07-01 19:10:05 -07:00
|
|
|
name: item.name,
|
|
|
|
|
playCount: null,
|
|
|
|
|
serverId: server?.id || 'unknown',
|
|
|
|
|
serverType: ServerType.SUBSONIC,
|
|
|
|
|
similarArtists: [],
|
|
|
|
|
songCount: null,
|
|
|
|
|
userFavorite: false,
|
|
|
|
|
userRating: null,
|
|
|
|
|
};
|
2023-05-19 00:14:41 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const normalizeAlbum = (
|
2023-07-01 19:10:05 -07:00
|
|
|
item: z.infer<typeof ssType._response.album>,
|
|
|
|
|
server: ServerListItem | null,
|
2023-05-19 00:14:41 -07:00
|
|
|
): Album => {
|
2023-07-01 19:10:05 -07:00
|
|
|
const imageUrl =
|
|
|
|
|
getCoverArtUrl({
|
|
|
|
|
baseUrl: server?.url,
|
|
|
|
|
coverArtId: item.coverArt,
|
|
|
|
|
credential: server?.credential,
|
|
|
|
|
size: 300,
|
|
|
|
|
}) || null;
|
2023-05-19 00:14:41 -07:00
|
|
|
|
2023-07-01 19:10:05 -07:00
|
|
|
return {
|
2024-01-15 22:10:50 -08:00
|
|
|
albumArtist: item.artist,
|
2023-07-01 19:10:05 -07:00
|
|
|
albumArtists: item.artistId
|
|
|
|
|
? [{ id: item.artistId, imageUrl: null, name: item.artist }]
|
|
|
|
|
: [],
|
|
|
|
|
artists: item.artistId ? [{ id: item.artistId, imageUrl: null, name: item.artist }] : [],
|
|
|
|
|
backdropImageUrl: null,
|
2024-01-15 20:46:06 -08:00
|
|
|
comment: null,
|
2023-07-01 19:10:05 -07:00
|
|
|
createdAt: item.created,
|
|
|
|
|
duration: item.duration,
|
2023-08-04 10:32:35 -07:00
|
|
|
genres: item.genre
|
|
|
|
|
? [
|
|
|
|
|
{
|
|
|
|
|
id: item.genre,
|
|
|
|
|
imageUrl: null,
|
|
|
|
|
itemType: LibraryItem.GENRE,
|
|
|
|
|
name: item.genre,
|
|
|
|
|
},
|
|
|
|
|
]
|
|
|
|
|
: [],
|
2023-07-01 19:10:05 -07:00
|
|
|
id: item.id,
|
|
|
|
|
imagePlaceholderUrl: null,
|
|
|
|
|
imageUrl,
|
|
|
|
|
isCompilation: null,
|
|
|
|
|
itemType: LibraryItem.ALBUM,
|
|
|
|
|
lastPlayedAt: null,
|
2024-01-15 22:10:50 -08:00
|
|
|
mbzId: null,
|
2023-07-01 19:10:05 -07:00
|
|
|
name: item.name,
|
|
|
|
|
playCount: null,
|
|
|
|
|
releaseDate: item.year ? new Date(item.year, 0, 1).toISOString() : null,
|
|
|
|
|
releaseYear: item.year ? Number(item.year) : null,
|
|
|
|
|
serverId: server?.id || 'unknown',
|
|
|
|
|
serverType: ServerType.SUBSONIC,
|
|
|
|
|
size: null,
|
|
|
|
|
songCount: item.songCount,
|
|
|
|
|
songs: [],
|
|
|
|
|
uniqueId: nanoid(),
|
|
|
|
|
updatedAt: item.created,
|
|
|
|
|
userFavorite: item.starred || false,
|
|
|
|
|
userRating: item.userRating || null,
|
|
|
|
|
};
|
2023-05-19 00:14:41 -07:00
|
|
|
};
|
|
|
|
|
|
2023-04-24 01:21:29 -07:00
|
|
|
export const ssNormalize = {
|
2023-07-01 19:10:05 -07:00
|
|
|
album: normalizeAlbum,
|
|
|
|
|
albumArtist: normalizeAlbumArtist,
|
|
|
|
|
song: normalizeSong,
|
2023-04-24 01:21:29 -07:00
|
|
|
};
|