fix subsonic album artist and album list count

This commit is contained in:
Kendall Garner 2025-06-20 18:35:11 -07:00
parent b7fb7c7f94
commit 87c9963354
No known key found for this signature in database
GPG key ID: 9355F387FE765C94
3 changed files with 32 additions and 153 deletions

View file

@ -347,8 +347,8 @@ export const SubsonicController: ControllerEndpoint = {
type = AlbumListSortType.BY_YEAR;
}
let fromYear;
let toYear;
let fromYear: number | undefined;
let toYear: number | undefined;
if (query.minYear) {
fromYear = query.minYear;
@ -398,124 +398,8 @@ export const SubsonicController: ControllerEndpoint = {
totalRecordCount: null,
};
},
getAlbumListCount: async (args) => {
const { apiClientProps, query } = args;
if (query.searchTerm) {
let fetchNextPage = true;
let startIndex = 0;
let totalRecordCount = 0;
while (fetchNextPage) {
const res = await ssApiClient(apiClientProps).search3({
query: {
albumCount: 500,
albumOffset: startIndex,
artistCount: 0,
artistOffset: 0,
query: query.searchTerm || '""',
songCount: 0,
songOffset: 0,
},
});
if (res.status !== 200) {
throw new Error('Failed to get album list count');
}
const albumCount = (res.body.searchResult3?.album || [])?.length;
totalRecordCount += albumCount;
startIndex += albumCount;
// The max limit size for Subsonic is 500
fetchNextPage = albumCount === 500;
}
return totalRecordCount;
}
if (query.favorite) {
const res = await ssApiClient(apiClientProps).getStarred({
query: {
musicFolderId: query.musicFolderId,
},
});
if (res.status !== 200) {
throw new Error('Failed to get album list');
}
return (res.body.starred?.album || []).length || 0;
}
let type = AlbumListSortType.ALPHABETICAL_BY_NAME;
let fetchNextPage = true;
let startIndex = 0;
let totalRecordCount = 0;
if (query.genres?.length) {
type = AlbumListSortType.BY_GENRE;
}
if (query.minYear || query.maxYear) {
type = AlbumListSortType.BY_YEAR;
}
let fromYear;
let toYear;
if (query.minYear) {
fromYear = query.minYear;
toYear = dayjs().year();
}
if (query.maxYear) {
toYear = query.maxYear;
if (!query.minYear) {
fromYear = 0;
}
}
while (fetchNextPage) {
const res = await ssApiClient(apiClientProps).getAlbumList2({
query: {
fromYear,
genre: query.genres?.length ? query.genres[0] : undefined,
musicFolderId: query.musicFolderId,
offset: startIndex,
size: 500,
toYear,
type,
},
});
const headers = res.headers;
// Navidrome returns the total count in the header
if (headers.get('x-total-count')) {
fetchNextPage = false;
totalRecordCount = Number(headers.get('x-total-count'));
break;
}
if (res.status !== 200) {
throw new Error('Failed to get album list count');
}
const albumCount = res.body.albumList2.album.length;
totalRecordCount += albumCount;
startIndex += albumCount;
// The max limit size for Subsonic is 500
fetchNextPage = albumCount === 500;
}
return totalRecordCount;
},
getAlbumListCount: async (args) =>
SubsonicController.getAlbumList(args).then((res) => res!.totalRecordCount!),
getArtistList: async (args) => {
const { apiClientProps, query } = args;

View file

@ -36,40 +36,32 @@ const getCoverArtUrl = (args: {
);
};
const getArtists = (
const getArtistList = (
artists?: typeof ssType._response.song._type.artists,
artistId?: number | string,
artistName?: string,
) => {
return artists
? artists.map((item) => ({
id: item.id.toString(),
imageUrl: null,
name: item.name,
}))
: [
{
id: artistId?.toString() || '',
imageUrl: null,
name: artistName || '',
},
];
};
const getParticipants = (
item:
| z.infer<typeof ssType._response.album>
| z.infer<typeof ssType._response.albumListEntry>
| z.infer<typeof ssType._response.song>,
) => {
const albumArtists: RelatedArtist[] = item.albumArtists
? item.albumArtists.map((item) => ({
id: item.id.toString(),
imageUrl: null,
name: item.name,
}))
: [
{
id: item.artistId?.toString() || '',
imageUrl: null,
name: item.artist || '',
},
];
const artists: RelatedArtist[] = item.artists
? item.artists.map((item) => ({
id: item.id.toString(),
imageUrl: null,
name: item.name,
}))
: [
{
id: item.artistId?.toString() || '',
imageUrl: null,
name: item.artist || '',
},
];
let participants: null | Record<string, RelatedArtist[]> = null;
if (item.contributors) {
@ -94,7 +86,7 @@ const getArtists = (
}
}
return { albumArtists, artists, participants };
return participants;
};
const getGenres = (
@ -139,9 +131,10 @@ const normalizeSong = (
return {
album: item.album || '',
albumArtists: getArtistList(item.albumArtists, item.artistId, item.artist),
albumId: item.albumId?.toString() || '',
artistName: item.artist || '',
...getArtists(item),
artists: getArtistList(item.artists, item.artistId, item.artist),
bitRate: item.bitRate || 0,
bpm: item.bpm || null,
channels: null,
@ -167,6 +160,7 @@ const normalizeSong = (
lastPlayedAt: null,
lyrics: null,
name: item.title,
participants: getParticipants(item),
path: item.path,
peak:
item.replayGain && (item.replayGain.albumPeak || item.replayGain.trackPeak)
@ -243,7 +237,8 @@ const normalizeAlbum = (
return {
albumArtist: item.artist,
...getArtists(item),
albumArtists: getArtistList(item.artists, item.artistId, item.artist),
artists: [],
backdropImageUrl: null,
comment: null,
createdAt: item.created,
@ -258,6 +253,7 @@ const normalizeAlbum = (
mbzId: null,
name: item.name,
originalDate: null,
participants: getParticipants(item),
playCount: null,
releaseDate: item.year ? new Date(Date.UTC(item.year, 0, 1)).toISOString() : null,
releaseYear: item.year ? Number(item.year) : null,

View file

@ -115,7 +115,6 @@ const song = z.object({
const album = z.object({
album: z.string(),
albumArtists: z.array(simpleArtist),
artist: z.string(),
artistId: id,
artists: z.array(simpleArtist),