Scrobbling on play

This commit is contained in:
simojenki
2021-03-17 18:40:24 +11:00
parent 5ee9dd5d5b
commit 19953bddcf
6 changed files with 230 additions and 40 deletions

View File

@@ -146,4 +146,5 @@ export interface MusicLibrary {
range: string | undefined;
}): Promise<Stream>;
coverArt(id: string, type: "album" | "artist", size?: number): Promise<CoverArt | undefined>;
scrobble(id: string): Promise<boolean>
}

View File

@@ -118,12 +118,12 @@ export type artistInfo = {
smallImageUrl: string | undefined;
mediumImageUrl: string | undefined;
largeImageUrl: string | undefined;
similarArtist: artistSummary[]
similarArtist: artistSummary[];
};
export type ArtistInfo = {
image: Images;
similarArtist: {id:string, name:string}[]
similarArtist: { id: string; name: string }[];
};
export type GetArtistInfoResponse = SubsonicResponse & {
@@ -244,6 +244,32 @@ export class Navidrome implements MusicService {
else return response;
});
post = async (
{ username, password }: Credentials,
path: string,
q: {} = {},
config: AxiosRequestConfig | undefined = {}
) =>
axios
.post(`${this.url}${path}`, {
params: {
...q,
u: username,
...t_and_s(password),
v: "1.16.1",
c: "bonob",
},
headers: {
"User-Agent": "bonob",
},
...config,
})
.then((response) => {
if (response.status != 200 && response.status != 206)
throw `Navidrome failed with a ${response.status}`;
else return response;
});
getJSON = async <T>(
{ username, password }: Credentials,
path: string,
@@ -258,7 +284,7 @@ export class Navidrome implements MusicService {
"subsonic-response.albumList.album",
"subsonic-response.album.song",
"subsonic-response.genres.genre",
"subsonic-response.artistInfo.similarArtist"
"subsonic-response.artistInfo.similarArtist",
],
}).xml2js(response.data) as SubconicEnvelope
)
@@ -305,7 +331,10 @@ export class Navidrome implements MusicService {
medium: validate(it.artistInfo.mediumImageUrl),
large: validate(it.artistInfo.largeImageUrl),
},
similarArtist: (it.artistInfo.similarArtist || []).map(artist => ({id: artist._id, name: artist._name}))
similarArtist: (it.artistInfo.similarArtist || []).map((artist) => ({
id: artist._id,
name: artist._name,
})),
}));
getAlbum = (credentials: Credentials, id: string): Promise<Album> =>
@@ -346,7 +375,7 @@ export class Navidrome implements MusicService {
name: artist.name,
image: artistInfo.image,
albums: artist.albums,
similarArtists: artistInfo.similarArtist
similarArtists: artistInfo.similarArtist,
}));
getCoverArt = (credentials: Credentials, id: string, size?: number) =>
@@ -517,6 +546,11 @@ export class Navidrome implements MusicService {
});
}
},
scrobble: async (id: string) =>
navidrome
.post(credentials, `/rest/scrobble`, { id })
.then((_) => true)
.catch(() => false),
};
return Promise.resolve(musicLibrary);

View File

@@ -14,6 +14,7 @@ import { LinkCodes, InMemoryLinkCodes } from "./link_codes";
import { MusicService, isSuccess } from "./music_service";
import bindSmapiSoapServiceToExpress from "./smapi";
import { AccessTokens, AccessTokenPerAuthToken } from "./access_tokens";
import logger from "./logger";
export const BONOB_ACCESS_TOKEN_HEADER = "bonob-access-token";
@@ -136,6 +137,14 @@ function server(
} else {
return musicService
.login(authToken)
.then((it) =>
it.scrobble(id).then((scrobbleSuccess) => {
if(!scrobbleSuccess) {
logger.warn("Failed to scrobble....")
}
return it;
})
)
.then((it) =>
it.stream({ trackId: id, range: req.headers["range"] || undefined })
)