mirror of
https://github.com/wkulhanek/bonob.git
synced 2025-12-21 17:33:29 +01:00
refactor
This commit is contained in:
402
src/subsonic.ts
402
src/subsonic.ts
@@ -203,13 +203,6 @@ type GetSongResponse = {
|
|||||||
song: song;
|
song: song;
|
||||||
};
|
};
|
||||||
|
|
||||||
type GetStarredResponse = {
|
|
||||||
starred2: {
|
|
||||||
song: song[];
|
|
||||||
album: album[];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export type PingResponse = {
|
export type PingResponse = {
|
||||||
status: string;
|
status: string;
|
||||||
version: string;
|
version: string;
|
||||||
@@ -445,8 +438,7 @@ export class SubsonicGenericMusicLibrary implements SubsonicMusicLibrary {
|
|||||||
bearerToken = (_: Credentials) => TE.right(undefined);
|
bearerToken = (_: Credentials) => TE.right(undefined);
|
||||||
|
|
||||||
artists = (q: ArtistQuery): Promise<Result<ArtistSummary & Sortable>> =>
|
artists = (q: ArtistQuery): Promise<Result<ArtistSummary & Sortable>> =>
|
||||||
this.subsonic
|
this.getArtists()
|
||||||
.getArtists(this.credentials)
|
|
||||||
.then(slice2(q))
|
.then(slice2(q))
|
||||||
.then(([page, total]) => ({
|
.then(([page, total]) => ({
|
||||||
total,
|
total,
|
||||||
@@ -459,13 +451,12 @@ export class SubsonicGenericMusicLibrary implements SubsonicMusicLibrary {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
artist = async (id: string): Promise<Artist> =>
|
artist = async (id: string): Promise<Artist> =>
|
||||||
this.subsonic.getArtistWithInfo(this.credentials, id);
|
this.getArtistWithInfo(id);
|
||||||
|
|
||||||
albums = async (q: AlbumQuery): Promise<Result<AlbumSummary>> =>
|
albums = async (q: AlbumQuery): Promise<Result<AlbumSummary>> =>
|
||||||
this.subsonic.getAlbumList2(this.credentials, q);
|
this.getAlbumList2(q);
|
||||||
|
|
||||||
album = (id: string): Promise<Album> =>
|
album = (id: string): Promise<Album> => this.getAlbum(id);
|
||||||
this.subsonic.getAlbum(this.credentials, id);
|
|
||||||
|
|
||||||
genres = () =>
|
genres = () =>
|
||||||
this.subsonic
|
this.subsonic
|
||||||
@@ -490,14 +481,13 @@ export class SubsonicGenericMusicLibrary implements SubsonicMusicLibrary {
|
|||||||
(album.song || []).map((song) => asTrack(asAlbum(album), song))
|
(album.song || []).map((song) => asTrack(asAlbum(album), song))
|
||||||
);
|
);
|
||||||
|
|
||||||
track = (trackId: string) =>
|
track = (trackId: string) => this.getTrack(trackId);
|
||||||
this.subsonic.getTrack(this.credentials, trackId);
|
|
||||||
|
|
||||||
rate = (trackId: string, rating: Rating) =>
|
rate = (trackId: string, rating: Rating) =>
|
||||||
Promise.resolve(true)
|
Promise.resolve(true)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
if (rating.stars >= 0 && rating.stars <= 5) {
|
if (rating.stars >= 0 && rating.stars <= 5) {
|
||||||
return this.subsonic.getTrack(this.credentials, trackId);
|
return this.getTrack(trackId);
|
||||||
} else {
|
} else {
|
||||||
throw `Invalid rating.stars value of ${rating.stars}`;
|
throw `Invalid rating.stars value of ${rating.stars}`;
|
||||||
}
|
}
|
||||||
@@ -535,7 +525,7 @@ export class SubsonicGenericMusicLibrary implements SubsonicMusicLibrary {
|
|||||||
trackId: string;
|
trackId: string;
|
||||||
range: string | undefined;
|
range: string | undefined;
|
||||||
}) =>
|
}) =>
|
||||||
this.subsonic.getTrack(this.credentials, trackId).then((track) =>
|
this.getTrack(trackId).then((track) =>
|
||||||
this.subsonic
|
this.subsonic
|
||||||
.get(
|
.get(
|
||||||
this.credentials,
|
this.credentials,
|
||||||
@@ -575,7 +565,7 @@ export class SubsonicGenericMusicLibrary implements SubsonicMusicLibrary {
|
|||||||
Promise.resolve(coverArtURN)
|
Promise.resolve(coverArtURN)
|
||||||
.then((it) => assertSystem(it, "subsonic"))
|
.then((it) => assertSystem(it, "subsonic"))
|
||||||
.then((it) => it.resource.split(":")[1]!)
|
.then((it) => it.resource.split(":")[1]!)
|
||||||
.then((it) => this.subsonic.getCoverArt(this.credentials, it, size))
|
.then((it) => this.getCoverArt(this.credentials, it, size))
|
||||||
.then((res) => ({
|
.then((res) => ({
|
||||||
contentType: res.headers["content-type"],
|
contentType: res.headers["content-type"],
|
||||||
data: Buffer.from(res.data, "binary"),
|
data: Buffer.from(res.data, "binary"),
|
||||||
@@ -604,9 +594,8 @@ export class SubsonicGenericMusicLibrary implements SubsonicMusicLibrary {
|
|||||||
.catch(() => false);
|
.catch(() => false);
|
||||||
|
|
||||||
searchArtists = async (query: string) =>
|
searchArtists = async (query: string) =>
|
||||||
this.subsonic
|
this.search3({ query, artistCount: 20 }).then(
|
||||||
.search3(this.credentials, { query, artistCount: 20 })
|
({ artists }) =>
|
||||||
.then(({ artists }) =>
|
|
||||||
artists.map((artist) => ({
|
artists.map((artist) => ({
|
||||||
id: artist.id,
|
id: artist.id,
|
||||||
name: artist.name,
|
name: artist.name,
|
||||||
@@ -615,21 +604,17 @@ export class SubsonicGenericMusicLibrary implements SubsonicMusicLibrary {
|
|||||||
artistImageURL: artist.artistImageUrl,
|
artistImageURL: artist.artistImageUrl,
|
||||||
}),
|
}),
|
||||||
}))
|
}))
|
||||||
);
|
);
|
||||||
|
|
||||||
searchAlbums = async (query: string) =>
|
searchAlbums = async (query: string) =>
|
||||||
this.subsonic
|
this.search3({ query, albumCount: 20 }).then(
|
||||||
.search3(this.credentials, { query, albumCount: 20 })
|
({ albums }) => this.toAlbumSummary(albums)
|
||||||
.then(({ albums }) => this.subsonic.toAlbumSummary(albums));
|
);
|
||||||
|
|
||||||
searchTracks = async (query: string) =>
|
searchTracks = async (query: string) =>
|
||||||
this.subsonic
|
this.search3({ query, songCount: 20 }).then(({ songs }) =>
|
||||||
.search3(this.credentials, { query, songCount: 20 })
|
Promise.all(songs.map((it) => this.getTrack(it.id)))
|
||||||
.then(({ songs }) =>
|
);
|
||||||
Promise.all(
|
|
||||||
songs.map((it) => this.subsonic.getTrack(this.credentials, it.id))
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
playlists = async () =>
|
playlists = async () =>
|
||||||
this.subsonic
|
this.subsonic
|
||||||
@@ -710,15 +695,15 @@ export class SubsonicGenericMusicLibrary implements SubsonicMusicLibrary {
|
|||||||
.then((songs) =>
|
.then((songs) =>
|
||||||
Promise.all(
|
Promise.all(
|
||||||
songs.map((song) =>
|
songs.map((song) =>
|
||||||
this.subsonic
|
this.getAlbum(song.albumId!).then((album) =>
|
||||||
.getAlbum(this.credentials, song.albumId!)
|
asTrack(album, song)
|
||||||
.then((album) => asTrack(album, song))
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
topSongs = async (artistId: string) =>
|
topSongs = async (artistId: string) =>
|
||||||
this.subsonic.getArtist(this.credentials, artistId).then(({ name }) =>
|
this.getArtist(artistId).then(({ name }) =>
|
||||||
this.subsonic
|
this.subsonic
|
||||||
.getJSON<GetTopSongsResponse>(this.credentials, "/rest/getTopSongs", {
|
.getJSON<GetTopSongsResponse>(this.credentials, "/rest/getTopSongs", {
|
||||||
artist: name,
|
artist: name,
|
||||||
@@ -728,13 +713,181 @@ export class SubsonicGenericMusicLibrary implements SubsonicMusicLibrary {
|
|||||||
.then((songs) =>
|
.then((songs) =>
|
||||||
Promise.all(
|
Promise.all(
|
||||||
songs.map((song) =>
|
songs.map((song) =>
|
||||||
this.subsonic
|
this.getAlbum(song.albumId!).then((album) =>
|
||||||
.getAlbum(this.credentials, song.albumId!)
|
asTrack(album, song)
|
||||||
.then((album) => asTrack(album, song))
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
private getArtists = (): Promise<(IdName & { albumCount: number; image: BUrn | undefined })[]> =>
|
||||||
|
this.subsonic
|
||||||
|
.getJSON<GetArtistsResponse>(this.credentials, "/rest/getArtists")
|
||||||
|
.then((it) => (it.artists.index || []).flatMap((it) => it.artist || []))
|
||||||
|
.then((artists) =>
|
||||||
|
artists.map((artist) => ({
|
||||||
|
id: `${artist.id}`,
|
||||||
|
name: artist.name,
|
||||||
|
albumCount: artist.albumCount,
|
||||||
|
image: artistImageURN({
|
||||||
|
artistId: artist.id,
|
||||||
|
artistImageURL: artist.artistImageUrl,
|
||||||
|
}),
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
|
||||||
|
private getArtistInfo = (
|
||||||
|
id: string
|
||||||
|
): Promise<{
|
||||||
|
similarArtist: (ArtistSummary & { inLibrary: boolean })[];
|
||||||
|
images: {
|
||||||
|
s: string | undefined;
|
||||||
|
m: string | undefined;
|
||||||
|
l: string | undefined;
|
||||||
|
};
|
||||||
|
}> =>
|
||||||
|
this.subsonic
|
||||||
|
.getJSON<GetArtistInfoResponse>(this.credentials, "/rest/getArtistInfo2", {
|
||||||
|
id,
|
||||||
|
count: 50,
|
||||||
|
includeNotPresent: true,
|
||||||
|
})
|
||||||
|
.then((it) => it.artistInfo2)
|
||||||
|
.then((it) => ({
|
||||||
|
images: {
|
||||||
|
s: it.smallImageUrl,
|
||||||
|
m: it.mediumImageUrl,
|
||||||
|
l: it.largeImageUrl,
|
||||||
|
},
|
||||||
|
similarArtist: (it.similarArtist || []).map((artist) => ({
|
||||||
|
id: `${artist.id}`,
|
||||||
|
name: artist.name,
|
||||||
|
inLibrary: artistIsInLibrary(artist.id),
|
||||||
|
image: artistImageURN({
|
||||||
|
artistId: artist.id,
|
||||||
|
artistImageURL: artist.artistImageUrl,
|
||||||
|
}),
|
||||||
|
})),
|
||||||
|
}));
|
||||||
|
|
||||||
|
private getAlbum = (id: string): Promise<Album> =>
|
||||||
|
this.subsonic
|
||||||
|
.getJSON<GetAlbumResponse>(this.credentials, "/rest/getAlbum", { id })
|
||||||
|
.then((it) => it.album)
|
||||||
|
.then((album) => ({
|
||||||
|
id: album.id,
|
||||||
|
name: album.name,
|
||||||
|
year: album.year,
|
||||||
|
genre: maybeAsGenre(album.genre),
|
||||||
|
artistId: album.artistId,
|
||||||
|
artistName: album.artist,
|
||||||
|
coverArt: coverArtURN(album.coverArt),
|
||||||
|
}));
|
||||||
|
|
||||||
|
private getArtist = (
|
||||||
|
id: string
|
||||||
|
): Promise<
|
||||||
|
IdName & { artistImageUrl: string | undefined; albums: AlbumSummary[] }
|
||||||
|
> =>
|
||||||
|
this.subsonic
|
||||||
|
.getJSON<GetArtistResponse>(this.credentials, "/rest/getArtist", {
|
||||||
|
id,
|
||||||
|
})
|
||||||
|
.then((it) => it.artist)
|
||||||
|
.then((it) => ({
|
||||||
|
id: it.id,
|
||||||
|
name: it.name,
|
||||||
|
artistImageUrl: it.artistImageUrl,
|
||||||
|
albums: this.toAlbumSummary(it.album || []),
|
||||||
|
}));
|
||||||
|
|
||||||
|
private getArtistWithInfo = (id: string) =>
|
||||||
|
Promise.all([
|
||||||
|
this.getArtist(id),
|
||||||
|
this.getArtistInfo(id),
|
||||||
|
]).then(([artist, artistInfo]) => ({
|
||||||
|
id: artist.id,
|
||||||
|
name: artist.name,
|
||||||
|
image: artistImageURN({
|
||||||
|
artistId: artist.id,
|
||||||
|
artistImageURL: [
|
||||||
|
artist.artistImageUrl,
|
||||||
|
artistInfo.images.l,
|
||||||
|
artistInfo.images.m,
|
||||||
|
artistInfo.images.s,
|
||||||
|
].find(isValidImage),
|
||||||
|
}),
|
||||||
|
albums: artist.albums,
|
||||||
|
similarArtists: artistInfo.similarArtist,
|
||||||
|
}));
|
||||||
|
|
||||||
|
private getCoverArt = (credentials: Credentials, id: string, size?: number) =>
|
||||||
|
this.subsonic.get(
|
||||||
|
credentials,
|
||||||
|
"/rest/getCoverArt",
|
||||||
|
size ? { id, size } : { id },
|
||||||
|
{
|
||||||
|
headers: { "User-Agent": "bonob" },
|
||||||
|
responseType: "arraybuffer",
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
private getTrack = (id: string) =>
|
||||||
|
this.subsonic
|
||||||
|
.getJSON<GetSongResponse>(this.credentials, "/rest/getSong", {
|
||||||
|
id,
|
||||||
|
})
|
||||||
|
.then((it) => it.song)
|
||||||
|
.then((song) =>
|
||||||
|
this.getAlbum(song.albumId!).then((album) =>
|
||||||
|
asTrack(album, song)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
private toAlbumSummary = (albumList: album[]): AlbumSummary[] =>
|
||||||
|
albumList.map((album) => ({
|
||||||
|
id: album.id,
|
||||||
|
name: album.name,
|
||||||
|
year: album.year,
|
||||||
|
genre: maybeAsGenre(album.genre),
|
||||||
|
artistId: album.artistId,
|
||||||
|
artistName: album.artist,
|
||||||
|
coverArt: coverArtURN(album.coverArt),
|
||||||
|
}));
|
||||||
|
|
||||||
|
private search3 = (q: any) =>
|
||||||
|
this.subsonic
|
||||||
|
.getJSON<Search3Response>(this.credentials, "/rest/search3", {
|
||||||
|
artistCount: 0,
|
||||||
|
albumCount: 0,
|
||||||
|
songCount: 0,
|
||||||
|
...q,
|
||||||
|
})
|
||||||
|
.then((it) => ({
|
||||||
|
artists: it.searchResult3.artist || [],
|
||||||
|
albums: it.searchResult3.album || [],
|
||||||
|
songs: it.searchResult3.song || [],
|
||||||
|
}));
|
||||||
|
|
||||||
|
private getAlbumList2 = (q: AlbumQuery) =>
|
||||||
|
Promise.all([
|
||||||
|
this.getArtists().then((it) =>
|
||||||
|
_.inject(it, (total, artist) => total + artist.albumCount, 0)
|
||||||
|
),
|
||||||
|
this.subsonic
|
||||||
|
.getJSON<GetAlbumListResponse>(this.credentials, "/rest/getAlbumList2", {
|
||||||
|
type: AlbumQueryTypeToSubsonicType[q.type],
|
||||||
|
...(q.genre ? { genre: b64Decode(q.genre) } : {}),
|
||||||
|
size: 500,
|
||||||
|
offset: q._index,
|
||||||
|
})
|
||||||
|
.then((response) => response.albumList2.album || [])
|
||||||
|
.then(this.toAlbumSummary),
|
||||||
|
]).then(([total, albums]) => ({
|
||||||
|
results: albums.slice(0, q._count),
|
||||||
|
total: albums.length == 500 ? total : (q._index || 0) + albums.length,
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Subsonic implements MusicService {
|
export class Subsonic implements MusicService {
|
||||||
@@ -829,177 +982,6 @@ export class Subsonic implements MusicService {
|
|||||||
refreshToken = (serviceToken: string) =>
|
refreshToken = (serviceToken: string) =>
|
||||||
this.generateToken(parseToken(serviceToken));
|
this.generateToken(parseToken(serviceToken));
|
||||||
|
|
||||||
getArtists = (
|
|
||||||
credentials: Credentials
|
|
||||||
): Promise<(IdName & { albumCount: number; image: BUrn | undefined })[]> =>
|
|
||||||
this.getJSON<GetArtistsResponse>(credentials, "/rest/getArtists")
|
|
||||||
.then((it) => (it.artists.index || []).flatMap((it) => it.artist || []))
|
|
||||||
.then((artists) =>
|
|
||||||
artists.map((artist) => ({
|
|
||||||
id: `${artist.id}`,
|
|
||||||
name: artist.name,
|
|
||||||
albumCount: artist.albumCount,
|
|
||||||
image: artistImageURN({
|
|
||||||
artistId: artist.id,
|
|
||||||
artistImageURL: artist.artistImageUrl,
|
|
||||||
}),
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
|
|
||||||
getArtistInfo = (
|
|
||||||
credentials: Credentials,
|
|
||||||
id: string
|
|
||||||
): Promise<{
|
|
||||||
similarArtist: (ArtistSummary & { inLibrary: boolean })[];
|
|
||||||
images: {
|
|
||||||
s: string | undefined;
|
|
||||||
m: string | undefined;
|
|
||||||
l: string | undefined;
|
|
||||||
};
|
|
||||||
}> =>
|
|
||||||
this.getJSON<GetArtistInfoResponse>(credentials, "/rest/getArtistInfo2", {
|
|
||||||
id,
|
|
||||||
count: 50,
|
|
||||||
includeNotPresent: true,
|
|
||||||
})
|
|
||||||
.then((it) => it.artistInfo2)
|
|
||||||
.then((it) => ({
|
|
||||||
images: {
|
|
||||||
s: it.smallImageUrl,
|
|
||||||
m: it.mediumImageUrl,
|
|
||||||
l: it.largeImageUrl,
|
|
||||||
},
|
|
||||||
similarArtist: (it.similarArtist || []).map((artist) => ({
|
|
||||||
id: `${artist.id}`,
|
|
||||||
name: artist.name,
|
|
||||||
inLibrary: artistIsInLibrary(artist.id),
|
|
||||||
image: artistImageURN({
|
|
||||||
artistId: artist.id,
|
|
||||||
artistImageURL: artist.artistImageUrl,
|
|
||||||
}),
|
|
||||||
})),
|
|
||||||
}));
|
|
||||||
|
|
||||||
getAlbum = (credentials: Credentials, id: string): Promise<Album> =>
|
|
||||||
this.getJSON<GetAlbumResponse>(credentials, "/rest/getAlbum", { id })
|
|
||||||
.then((it) => it.album)
|
|
||||||
.then((album) => ({
|
|
||||||
id: album.id,
|
|
||||||
name: album.name,
|
|
||||||
year: album.year,
|
|
||||||
genre: maybeAsGenre(album.genre),
|
|
||||||
artistId: album.artistId,
|
|
||||||
artistName: album.artist,
|
|
||||||
coverArt: coverArtURN(album.coverArt),
|
|
||||||
}));
|
|
||||||
|
|
||||||
getArtist = (
|
|
||||||
credentials: Credentials,
|
|
||||||
id: string
|
|
||||||
): Promise<
|
|
||||||
IdName & { artistImageUrl: string | undefined; albums: AlbumSummary[] }
|
|
||||||
> =>
|
|
||||||
this.getJSON<GetArtistResponse>(credentials, "/rest/getArtist", {
|
|
||||||
id,
|
|
||||||
})
|
|
||||||
.then((it) => it.artist)
|
|
||||||
.then((it) => ({
|
|
||||||
id: it.id,
|
|
||||||
name: it.name,
|
|
||||||
artistImageUrl: it.artistImageUrl,
|
|
||||||
albums: this.toAlbumSummary(it.album || []),
|
|
||||||
}));
|
|
||||||
|
|
||||||
getArtistWithInfo = (credentials: Credentials, id: string) =>
|
|
||||||
Promise.all([
|
|
||||||
this.getArtist(credentials, id),
|
|
||||||
this.getArtistInfo(credentials, id),
|
|
||||||
]).then(([artist, artistInfo]) => ({
|
|
||||||
id: artist.id,
|
|
||||||
name: artist.name,
|
|
||||||
image: artistImageURN({
|
|
||||||
artistId: artist.id,
|
|
||||||
artistImageURL: [
|
|
||||||
artist.artistImageUrl,
|
|
||||||
artistInfo.images.l,
|
|
||||||
artistInfo.images.m,
|
|
||||||
artistInfo.images.s,
|
|
||||||
].find(isValidImage),
|
|
||||||
}),
|
|
||||||
albums: artist.albums,
|
|
||||||
similarArtists: artistInfo.similarArtist,
|
|
||||||
}));
|
|
||||||
|
|
||||||
getCoverArt = (credentials: Credentials, id: string, size?: number) =>
|
|
||||||
this.get(credentials, "/rest/getCoverArt", size ? { id, size } : { id }, {
|
|
||||||
headers: { "User-Agent": "bonob" },
|
|
||||||
responseType: "arraybuffer",
|
|
||||||
});
|
|
||||||
|
|
||||||
getTrack = (credentials: Credentials, id: string) =>
|
|
||||||
this.getJSON<GetSongResponse>(credentials, "/rest/getSong", {
|
|
||||||
id,
|
|
||||||
})
|
|
||||||
.then((it) => it.song)
|
|
||||||
.then((song) =>
|
|
||||||
this.getAlbum(credentials, song.albumId!).then((album) =>
|
|
||||||
asTrack(album, song)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
getStarred = (credentials: Credentials) =>
|
|
||||||
this.getJSON<GetStarredResponse>(credentials, "/rest/getStarred2").then(
|
|
||||||
(it) => new Set(it.starred2.song.map((it) => it.id))
|
|
||||||
);
|
|
||||||
|
|
||||||
toAlbumSummary = (albumList: album[]): AlbumSummary[] =>
|
|
||||||
albumList.map((album) => ({
|
|
||||||
id: album.id,
|
|
||||||
name: album.name,
|
|
||||||
year: album.year,
|
|
||||||
genre: maybeAsGenre(album.genre),
|
|
||||||
artistId: album.artistId,
|
|
||||||
artistName: album.artist,
|
|
||||||
coverArt: coverArtURN(album.coverArt),
|
|
||||||
}));
|
|
||||||
|
|
||||||
search3 = (credentials: Credentials, q: any) =>
|
|
||||||
this.getJSON<Search3Response>(credentials, "/rest/search3", {
|
|
||||||
artistCount: 0,
|
|
||||||
albumCount: 0,
|
|
||||||
songCount: 0,
|
|
||||||
...q,
|
|
||||||
}).then((it) => ({
|
|
||||||
artists: it.searchResult3.artist || [],
|
|
||||||
albums: it.searchResult3.album || [],
|
|
||||||
songs: it.searchResult3.song || [],
|
|
||||||
}));
|
|
||||||
|
|
||||||
getAlbumList2 = (credentials: Credentials, q: AlbumQuery) =>
|
|
||||||
Promise.all([
|
|
||||||
this.getArtists(credentials).then((it) =>
|
|
||||||
_.inject(it, (total, artist) => total + artist.albumCount, 0)
|
|
||||||
),
|
|
||||||
this.getJSON<GetAlbumListResponse>(credentials, "/rest/getAlbumList2", {
|
|
||||||
type: AlbumQueryTypeToSubsonicType[q.type],
|
|
||||||
...(q.genre ? { genre: b64Decode(q.genre) } : {}),
|
|
||||||
size: 500,
|
|
||||||
offset: q._index,
|
|
||||||
})
|
|
||||||
.then((response) => response.albumList2.album || [])
|
|
||||||
.then(this.toAlbumSummary),
|
|
||||||
]).then(([total, albums]) => ({
|
|
||||||
results: albums.slice(0, q._count),
|
|
||||||
total: albums.length == 500 ? total : (q._index || 0) + albums.length,
|
|
||||||
}));
|
|
||||||
|
|
||||||
// getStarred2 = (credentials: Credentials): Promise<{ albums: Album[] }> =>
|
|
||||||
// this.getJSON<GetStarredResponse>(credentials, "/rest/getStarred2")
|
|
||||||
// .then((it) => it.starred2)
|
|
||||||
// .then((it) => ({
|
|
||||||
// albums: it.album.map(asAlbum),
|
|
||||||
// }));
|
|
||||||
|
|
||||||
login = async (token: string) => this.libraryFor(parseToken(token));
|
login = async (token: string) => this.libraryFor(parseToken(token));
|
||||||
|
|
||||||
private libraryFor = (
|
private libraryFor = (
|
||||||
|
|||||||
@@ -375,11 +375,6 @@ const getAlbumJson = (artist: Artist, album: Album, tracks: Track[]) =>
|
|||||||
|
|
||||||
const getSongJson = (track: Track) => subsonicOK({ song: asSongJson(track) });
|
const getSongJson = (track: Track) => subsonicOK({ song: asSongJson(track) });
|
||||||
|
|
||||||
// const getStarredJson = ({ albums }: { albums: Album[] }) => subsonicOK({starred2: {
|
|
||||||
// album: albums.map(it => asAlbumJson({ id: it.artistId, name: it.artistName }, it, [])),
|
|
||||||
// song: [],
|
|
||||||
// }})
|
|
||||||
|
|
||||||
const subsonicOK = (body: any = {}) => ({
|
const subsonicOK = (body: any = {}) => ({
|
||||||
"subsonic-response": {
|
"subsonic-response": {
|
||||||
status: "ok",
|
status: "ok",
|
||||||
|
|||||||
Reference in New Issue
Block a user