mirror of
https://github.com/wkulhanek/bonob.git
synced 2025-12-22 01:43:29 +01:00
Query albums by genre
This commit is contained in:
@@ -74,7 +74,26 @@ export type ArtistQuery = Paging
|
||||
|
||||
export type AlbumQuery = Paging & {
|
||||
artistId?: string
|
||||
genre?: string
|
||||
}
|
||||
|
||||
export const artistToArtistSummary = (
|
||||
it: Artist
|
||||
): ArtistSummary => ({
|
||||
id: it.id,
|
||||
name: it.name,
|
||||
image: it.image,
|
||||
});
|
||||
|
||||
export const albumToAlbumSummary = (
|
||||
it: Album
|
||||
): AlbumSummary => ({
|
||||
id: it.id,
|
||||
name: it.name,
|
||||
year: it.year,
|
||||
genre: it.genre,
|
||||
});
|
||||
|
||||
export interface MusicService {
|
||||
generateToken(credentials: Credentials): Promise<AuthSuccess | AuthFailure>;
|
||||
login(authToken: string): Promise<MusicLibrary>;
|
||||
@@ -84,5 +103,5 @@ export interface MusicLibrary {
|
||||
artists(q: ArtistQuery): Promise<Result<ArtistSummary>>;
|
||||
artist(id: string): Promise<Artist>;
|
||||
albums(q: AlbumQuery): Promise<Result<AlbumSummary>>;
|
||||
// album(id: string): Promise<Album>;
|
||||
album(id: string): Promise<Album>;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { option as O } from "fp-ts";
|
||||
import { pipe } from "fp-ts/lib/function";
|
||||
import { Md5 } from "ts-md5/dist/md5";
|
||||
import {
|
||||
Credentials,
|
||||
@@ -19,6 +21,7 @@ import axios from "axios";
|
||||
import { Encryption } from "./encryption";
|
||||
import randomString from "./random_string";
|
||||
|
||||
|
||||
export const t = (password: string, s: string) =>
|
||||
Md5.hashStr(`${password}${s}`);
|
||||
|
||||
@@ -66,6 +69,12 @@ export type GetArtistsResponse = SubsonicResponse & {
|
||||
};
|
||||
};
|
||||
|
||||
export type GetAlbumListResponse = SubsonicResponse & {
|
||||
albumList: {
|
||||
album: album[];
|
||||
};
|
||||
};
|
||||
|
||||
export type SubsonicError = SubsonicResponse & {
|
||||
error: {
|
||||
_code: string;
|
||||
@@ -105,6 +114,17 @@ export type IdName = {
|
||||
name: string;
|
||||
};
|
||||
|
||||
export type getAlbumListParams = {
|
||||
type: string,
|
||||
size?: number;
|
||||
offet?: number;
|
||||
fromYear?: string,
|
||||
toYear?: string,
|
||||
genre?: string
|
||||
}
|
||||
|
||||
const MAX_ALBUM_LIST = 500;
|
||||
|
||||
export class Navidrome implements MusicService {
|
||||
url: string;
|
||||
encryption: Encryption;
|
||||
@@ -235,8 +255,36 @@ export class Navidrome implements MusicService {
|
||||
image: artistInfo.image,
|
||||
albums: artist.albums,
|
||||
})),
|
||||
albums: (_: AlbumQuery): Promise<Result<AlbumSummary>> => {
|
||||
return Promise.resolve({ results: [], total: 0 });
|
||||
albums: (q: AlbumQuery): Promise<Result<AlbumSummary>> => {
|
||||
const p = pipe(
|
||||
O.fromNullable(q.genre),
|
||||
O.map<string, getAlbumListParams>(genre => ({ type: "byGenre", genre })),
|
||||
O.getOrElse<getAlbumListParams>(() => ({ type: "alphabeticalByArtist" })),
|
||||
)
|
||||
|
||||
return navidrome
|
||||
.get<GetAlbumListResponse>(credentials, "/rest/getAlbumList", {
|
||||
...p,
|
||||
size: MAX_ALBUM_LIST,
|
||||
offset: 0,
|
||||
})
|
||||
.then((response) => response.albumList.album)
|
||||
.then((albumList) =>
|
||||
albumList.map((album) => ({
|
||||
id: album._id,
|
||||
name: album._name,
|
||||
year: album._year,
|
||||
genre: album._genre,
|
||||
}))
|
||||
)
|
||||
.then(slice2(q))
|
||||
.then(([page, total]) => ({
|
||||
results: page,
|
||||
total: Math.min(MAX_ALBUM_LIST, total),
|
||||
}));
|
||||
},
|
||||
album: (_: string): Promise<Album> => {
|
||||
return Promise.reject("not implemented");
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
23
src/smapi.ts
23
src/smapi.ts
@@ -6,7 +6,12 @@ import path from "path";
|
||||
import logger from "./logger";
|
||||
|
||||
import { LinkCodes } from "./link_codes";
|
||||
import { AlbumSummary, MusicLibrary, MusicService, slice2 } from "./music_service";
|
||||
import {
|
||||
AlbumSummary,
|
||||
MusicLibrary,
|
||||
MusicService,
|
||||
slice2,
|
||||
} from "./music_service";
|
||||
|
||||
export const LOGIN_ROUTE = "/login";
|
||||
export const SOAP_PATH = "/ws/sonos";
|
||||
@@ -250,14 +255,14 @@ function bindSmapiSoapServiceToExpress(
|
||||
total: result.total,
|
||||
})
|
||||
);
|
||||
case "albums":
|
||||
return await musicLibrary.albums(paging).then((result) =>
|
||||
getMetadataResult({
|
||||
mediaCollection: result.results.map(album),
|
||||
index: paging._index,
|
||||
total: result.total,
|
||||
})
|
||||
);
|
||||
case "albums":
|
||||
return await musicLibrary.albums(paging).then((result) =>
|
||||
getMetadataResult({
|
||||
mediaCollection: result.results.map(album),
|
||||
index: paging._index,
|
||||
total: result.total,
|
||||
})
|
||||
);
|
||||
case "artist":
|
||||
return await musicLibrary
|
||||
.artist(typeId!)
|
||||
|
||||
Reference in New Issue
Block a user