mirror of
https://github.com/wkulhanek/bonob.git
synced 2025-12-21 17:33:29 +01:00
getJSON private
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { option as O } from "fp-ts";
|
import { option as O, taskEither as TE } from "fp-ts";
|
||||||
import * as A from "fp-ts/Array";
|
import * as A from "fp-ts/Array";
|
||||||
import { ordString } from "fp-ts/lib/Ord";
|
import { ordString } from "fp-ts/lib/Ord";
|
||||||
import { pipe } from "fp-ts/lib/function";
|
import { pipe } from "fp-ts/lib/function";
|
||||||
@@ -15,6 +15,7 @@ import {
|
|||||||
Encoding,
|
Encoding,
|
||||||
albumToAlbumSummary,
|
albumToAlbumSummary,
|
||||||
TrackSummary,
|
TrackSummary,
|
||||||
|
AuthFailure
|
||||||
} from "./music_library";
|
} from "./music_library";
|
||||||
import sharp from "sharp";
|
import sharp from "sharp";
|
||||||
import _ from "underscore";
|
import _ from "underscore";
|
||||||
@@ -531,10 +532,9 @@ export class Subsonic {
|
|||||||
} else return response;
|
} else return response;
|
||||||
});
|
});
|
||||||
|
|
||||||
// todo: make private
|
|
||||||
// todo: should I put a catch in here and force a subsonic fail status?
|
// todo: should I put a catch in here and force a subsonic fail status?
|
||||||
// or there is a catch above, that then throws, perhaps can go in there?
|
// or there is a catch above, that then throws, perhaps can go in there?
|
||||||
getJSON = async <T>(
|
private getJSON = async <T>(
|
||||||
{ username, password }: Credentials,
|
{ username, password }: Credentials,
|
||||||
path: string,
|
path: string,
|
||||||
q: {} = {}
|
q: {} = {}
|
||||||
@@ -547,6 +547,17 @@ export class Subsonic {
|
|||||||
else return json as unknown as T;
|
else return json as unknown as T;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ping = (credentials: Credentials): TE.TaskEither<AuthFailure, { authenticated: Boolean, type: string}> =>
|
||||||
|
TE.tryCatch(
|
||||||
|
() => this.getJSON<PingResponse>(credentials, "/rest/ping.view")
|
||||||
|
.then(it => ({
|
||||||
|
authenticated: it.status == "ok",
|
||||||
|
type: it.type
|
||||||
|
})),
|
||||||
|
(e) => new AuthFailure(e as string)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
getArtists = (
|
getArtists = (
|
||||||
credentials: Credentials
|
credentials: Credentials
|
||||||
): Promise<(IdName & { albumCount: number; image: BUrn | undefined })[]> =>
|
): Promise<(IdName & { albumCount: number; image: BUrn | undefined })[]> =>
|
||||||
@@ -861,5 +872,19 @@ export class Subsonic {
|
|||||||
.then((it) =>
|
.then((it) =>
|
||||||
(it.topSongs.song || []).map(it => asTrackSummary(it, this.customPlayers))
|
(it.topSongs.song || []).map(it => asTrackSummary(it, this.customPlayers))
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
getInternetRadioStations = (credentials: Credentials) =>
|
||||||
|
this.getJSON<GetInternetRadioStationsResponse>(
|
||||||
|
credentials,
|
||||||
|
"/rest/getInternetRadioStations"
|
||||||
|
)
|
||||||
|
.then((it) => it.internetRadioStations.internetRadioStation || [])
|
||||||
|
.then((stations) =>
|
||||||
|
stations.map((it) => ({
|
||||||
|
id: it.id,
|
||||||
|
name: it.name,
|
||||||
|
url: it.streamUrl,
|
||||||
|
homePage: it.homePageUrl,
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|||||||
@@ -19,12 +19,10 @@ import {
|
|||||||
import {
|
import {
|
||||||
Subsonic,
|
Subsonic,
|
||||||
CustomPlayers,
|
CustomPlayers,
|
||||||
PingResponse,
|
|
||||||
NO_CUSTOM_PLAYERS,
|
NO_CUSTOM_PLAYERS,
|
||||||
asToken,
|
asToken,
|
||||||
parseToken,
|
parseToken,
|
||||||
artistImageURN,
|
artistImageURN,
|
||||||
GetInternetRadioStationsResponse,
|
|
||||||
asYear,
|
asYear,
|
||||||
isValidImage
|
isValidImage
|
||||||
} from "./subsonic";
|
} from "./subsonic";
|
||||||
@@ -48,39 +46,23 @@ export class SubsonicMusicService implements MusicService {
|
|||||||
|
|
||||||
generateToken = (
|
generateToken = (
|
||||||
credentials: Credentials
|
credentials: Credentials
|
||||||
): TE.TaskEither<AuthFailure, AuthSuccess> => {
|
): TE.TaskEither<AuthFailure, AuthSuccess> =>
|
||||||
const x: TE.TaskEither<AuthFailure, PingResponse> = TE.tryCatch(
|
pipe(
|
||||||
() =>
|
this.subsonic.ping(credentials),
|
||||||
this.subsonic.getJSON<PingResponse>(
|
TE.flatMap(({ type }) => TE.tryCatch(
|
||||||
_.pick(credentials, "username", "password"),
|
() => this.libraryFor({ ...credentials, type }).then(library => ({ type, library })),
|
||||||
"/rest/ping.view"
|
() => new AuthFailure("Failed to get library")
|
||||||
),
|
)),
|
||||||
(e) => new AuthFailure(e as string)
|
TE.flatMap(({ library, type }) => pipe(
|
||||||
);
|
library.bearerToken(credentials),
|
||||||
return pipe(
|
TE.map(bearer => ({ bearer, type }))
|
||||||
x,
|
)),
|
||||||
TE.flatMap(({ type }) =>
|
TE.map(({ bearer, type}) => ({
|
||||||
pipe(
|
|
||||||
TE.tryCatch(
|
|
||||||
() => this.libraryFor({ ...credentials, type }),
|
|
||||||
() => new AuthFailure("Failed to get library")
|
|
||||||
),
|
|
||||||
TE.map((library) => ({ type, library }))
|
|
||||||
)
|
|
||||||
),
|
|
||||||
TE.flatMap(({ library, type }) =>
|
|
||||||
pipe(
|
|
||||||
library.bearerToken(credentials),
|
|
||||||
TE.map((bearer) => ({ bearer, type }))
|
|
||||||
)
|
|
||||||
),
|
|
||||||
TE.map(({ bearer, type }) => ({
|
|
||||||
serviceToken: asToken({ ...credentials, bearer, type }),
|
serviceToken: asToken({ ...credentials, bearer, type }),
|
||||||
userId: credentials.username,
|
userId: credentials.username,
|
||||||
nickname: credentials.username,
|
nickname: credentials.username,
|
||||||
}))
|
}))
|
||||||
);
|
);
|
||||||
};
|
|
||||||
|
|
||||||
refreshToken = (serviceToken: string) =>
|
refreshToken = (serviceToken: string) =>
|
||||||
this.generateToken(parseToken(serviceToken));
|
this.generateToken(parseToken(serviceToken));
|
||||||
@@ -310,20 +292,7 @@ export class SubsonicMusicLibrary implements MusicLibrary {
|
|||||||
);
|
);
|
||||||
|
|
||||||
radioStations = async () =>
|
radioStations = async () =>
|
||||||
this.subsonic
|
this.subsonic.getInternetRadioStations(this.credentials);
|
||||||
.getJSON<GetInternetRadioStationsResponse>(
|
|
||||||
this.credentials,
|
|
||||||
"/rest/getInternetRadioStations"
|
|
||||||
)
|
|
||||||
.then((it) => it.internetRadioStations.internetRadioStation || [])
|
|
||||||
.then((stations) =>
|
|
||||||
stations.map((it) => ({
|
|
||||||
id: it.id,
|
|
||||||
name: it.name,
|
|
||||||
url: it.streamUrl,
|
|
||||||
homePage: it.homePageUrl,
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
|
|
||||||
radioStation = async (id: string) =>
|
radioStation = async (id: string) =>
|
||||||
this.radioStations().then((it) => it.find((station) => station.id === id)!);
|
this.radioStations().then((it) => it.find((station) => station.id === id)!);
|
||||||
|
|||||||
Reference in New Issue
Block a user