mirror of
https://github.com/austinried/subtracks.git
synced 2026-02-10 06:52:43 +01:00
refactor api client to use string method
hoping to use this for requestKey/deduping next
This commit is contained in:
@@ -20,10 +20,9 @@ import {
|
|||||||
GetSongResponse,
|
GetSongResponse,
|
||||||
GetTopSongsResponse,
|
GetTopSongsResponse,
|
||||||
Search3Response,
|
Search3Response,
|
||||||
SubsonicResponse,
|
|
||||||
} from '@app/subsonic/responses'
|
} from '@app/subsonic/responses'
|
||||||
import PromiseQueue from '@app/util/PromiseQueue'
|
import PromiseQueue from '@app/util/PromiseQueue'
|
||||||
import { reduceById, mergeById } from '@app/util/state'
|
import { mergeById, reduceById } from '@app/util/state'
|
||||||
import { WritableDraft } from 'immer/dist/types/types-external'
|
import { WritableDraft } from 'immer/dist/types/types-external'
|
||||||
import pick from 'lodash.pick'
|
import pick from 'lodash.pick'
|
||||||
|
|
||||||
@@ -99,9 +98,9 @@ export const createLibrarySlice = (set: SetStore, get: GetStore): LibrarySlice =
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let response: SubsonicResponse<GetArtistsResponse>
|
let response: GetArtistsResponse
|
||||||
try {
|
try {
|
||||||
response = await client.getArtists()
|
response = await client.fetch('getArtists')
|
||||||
} catch {
|
} catch {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -121,9 +120,9 @@ export const createLibrarySlice = (set: SetStore, get: GetStore): LibrarySlice =
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let response: SubsonicResponse<GetArtistResponse>
|
let response: GetArtistResponse
|
||||||
try {
|
try {
|
||||||
response = await client.getArtist({ id })
|
response = await client.fetch('getArtist', { id })
|
||||||
} catch {
|
} catch {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -145,9 +144,9 @@ export const createLibrarySlice = (set: SetStore, get: GetStore): LibrarySlice =
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let response: SubsonicResponse<GetArtistInfo2Response>
|
let response: GetArtistInfo2Response
|
||||||
try {
|
try {
|
||||||
response = await client.getArtistInfo2({ id })
|
response = await client.fetch('getArtistInfo2', { id })
|
||||||
} catch {
|
} catch {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -165,9 +164,9 @@ export const createLibrarySlice = (set: SetStore, get: GetStore): LibrarySlice =
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let response: SubsonicResponse<GetTopSongsResponse>
|
let response: GetTopSongsResponse
|
||||||
try {
|
try {
|
||||||
response = await client.getTopSongs({ artist: artistName, count: 50 })
|
response = await client.fetch('getTopSongs', { artist: artistName, count: 50 })
|
||||||
} catch {
|
} catch {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -189,9 +188,9 @@ export const createLibrarySlice = (set: SetStore, get: GetStore): LibrarySlice =
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let response: SubsonicResponse<GetAlbumResponse>
|
let response: GetAlbumResponse
|
||||||
try {
|
try {
|
||||||
response = await client.getAlbum({ id })
|
response = await client.fetch('getAlbum', { id })
|
||||||
} catch {
|
} catch {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -215,9 +214,9 @@ export const createLibrarySlice = (set: SetStore, get: GetStore): LibrarySlice =
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let response: SubsonicResponse<GetPlaylistsResponse>
|
let response: GetPlaylistsResponse
|
||||||
try {
|
try {
|
||||||
response = await client.getPlaylists()
|
response = await client.fetch('getPlaylists', {})
|
||||||
} catch {
|
} catch {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -237,9 +236,9 @@ export const createLibrarySlice = (set: SetStore, get: GetStore): LibrarySlice =
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let response: SubsonicResponse<GetPlaylistResponse>
|
let response: GetPlaylistResponse
|
||||||
try {
|
try {
|
||||||
response = await client.getPlaylist({ id })
|
response = await client.fetch('getPlaylist', { id })
|
||||||
} catch {
|
} catch {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -263,9 +262,9 @@ export const createLibrarySlice = (set: SetStore, get: GetStore): LibrarySlice =
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let response: SubsonicResponse<GetSongResponse>
|
let response: GetSongResponse
|
||||||
try {
|
try {
|
||||||
response = await client.getSong({ id })
|
response = await client.fetch('getSong', { id })
|
||||||
} catch {
|
} catch {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -285,9 +284,9 @@ export const createLibrarySlice = (set: SetStore, get: GetStore): LibrarySlice =
|
|||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
let response: SubsonicResponse<GetAlbumList2Response>
|
let response: GetAlbumList2Response
|
||||||
try {
|
try {
|
||||||
response = await client.getAlbumList2(params)
|
response = await client.fetch('getAlbumList2', params)
|
||||||
} catch {
|
} catch {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
@@ -308,9 +307,9 @@ export const createLibrarySlice = (set: SetStore, get: GetStore): LibrarySlice =
|
|||||||
return empty
|
return empty
|
||||||
}
|
}
|
||||||
|
|
||||||
let response: SubsonicResponse<Search3Response>
|
let response: Search3Response
|
||||||
try {
|
try {
|
||||||
response = await client.search3(params)
|
response = await client.fetch('search3', params)
|
||||||
} catch {
|
} catch {
|
||||||
return empty
|
return empty
|
||||||
}
|
}
|
||||||
@@ -366,7 +365,7 @@ export const createLibrarySlice = (set: SetStore, get: GetStore): LibrarySlice =
|
|||||||
})
|
})
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await client.star(params)
|
await client.fetch('star', params)
|
||||||
} catch {
|
} catch {
|
||||||
set(state => {
|
set(state => {
|
||||||
if (originalValue !== null) {
|
if (originalValue !== null) {
|
||||||
@@ -405,7 +404,7 @@ export const createLibrarySlice = (set: SetStore, get: GetStore): LibrarySlice =
|
|||||||
})
|
})
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await client.unstar(params)
|
await client.fetch('unstar', params)
|
||||||
} catch {
|
} catch {
|
||||||
set(state => {
|
set(state => {
|
||||||
if (originalValue !== null) {
|
if (originalValue !== null) {
|
||||||
@@ -441,7 +440,7 @@ export const createLibrarySlice = (set: SetStore, get: GetStore): LibrarySlice =
|
|||||||
|
|
||||||
for (const id in albumsToGet) {
|
for (const id in albumsToGet) {
|
||||||
songCoverArtQueue
|
songCoverArtQueue
|
||||||
.enqueue(() => client.getAlbum({ id }))
|
.enqueue(() => client.fetch('getAlbum', { id }))
|
||||||
.then(res => {
|
.then(res => {
|
||||||
const album = mapAlbum(res.data.album)
|
const album = mapAlbum(res.data.album)
|
||||||
|
|
||||||
|
|||||||
@@ -220,7 +220,7 @@ export const createSettingsSlice = (set: SetStore, get: GetStore): SettingsSlice
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await client.ping()
|
await client.fetch('ping')
|
||||||
return true
|
return true
|
||||||
} catch {
|
} catch {
|
||||||
return false
|
return false
|
||||||
|
|||||||
@@ -298,7 +298,7 @@ export const createTrackPlayerSlice = (set: SetStore, get: GetStore): TrackPlaye
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await client.scrobble({ id })
|
await client.fetch('scrobble', { id })
|
||||||
} catch {}
|
} catch {}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import {
|
|||||||
GetPlaylistsResponse,
|
GetPlaylistsResponse,
|
||||||
GetSongResponse,
|
GetSongResponse,
|
||||||
GetTopSongsResponse,
|
GetTopSongsResponse,
|
||||||
|
NullResponse,
|
||||||
Search3Response,
|
Search3Response,
|
||||||
SubsonicResponse,
|
SubsonicResponse,
|
||||||
} from '@app/subsonic/responses'
|
} from '@app/subsonic/responses'
|
||||||
@@ -54,6 +55,48 @@ export class SubsonicApiError extends Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ResponseType<T extends SubsonicResponse> = (xml: Document) => T
|
||||||
|
|
||||||
|
type RequestParams = {
|
||||||
|
getIndexes: GetIndexesParams
|
||||||
|
getMusicDirectory: GetMusicDirectoryParams
|
||||||
|
getAlbum: GetAlbumParams
|
||||||
|
getArtistInfo: GetArtistInfoParams
|
||||||
|
getArtistInfo2: GetArtistInfo2Params
|
||||||
|
getArtist: GetArtistParams
|
||||||
|
getTopSongs: GetTopSongsParams
|
||||||
|
getSong: GetSongParams
|
||||||
|
getAlbumList: GetAlbumListParams
|
||||||
|
getAlbumList2: GetAlbumList2Params
|
||||||
|
getPlaylists: GetPlaylistsParams
|
||||||
|
getPlaylist: GetPlaylistParams
|
||||||
|
scrobble: ScrobbleParams
|
||||||
|
star: StarParams
|
||||||
|
unstar: StarParams
|
||||||
|
search3: Search3Params
|
||||||
|
}
|
||||||
|
|
||||||
|
const Methods = {
|
||||||
|
ping: (xml => new NullResponse(xml)) as ResponseType<NullResponse>,
|
||||||
|
getArtists: (xml => new GetArtistsResponse(xml)) as ResponseType<GetArtistsResponse>,
|
||||||
|
getIndexes: (xml => new GetIndexesResponse(xml)) as ResponseType<GetIndexesResponse>,
|
||||||
|
getMusicDirectory: (xml => new GetMusicDirectoryResponse(xml)) as ResponseType<GetMusicDirectoryResponse>,
|
||||||
|
getAlbum: (xml => new GetAlbumResponse(xml)) as ResponseType<GetAlbumResponse>,
|
||||||
|
getArtistInfo: (xml => new GetArtistInfoResponse(xml)) as ResponseType<GetArtistInfoResponse>,
|
||||||
|
getArtistInfo2: (xml => new GetArtistInfo2Response(xml)) as ResponseType<GetArtistInfo2Response>,
|
||||||
|
getArtist: (xml => new GetArtistResponse(xml)) as ResponseType<GetArtistResponse>,
|
||||||
|
getTopSongs: (xml => new GetTopSongsResponse(xml)) as ResponseType<GetTopSongsResponse>,
|
||||||
|
getSong: (xml => new GetSongResponse(xml)) as ResponseType<GetSongResponse>,
|
||||||
|
getAlbumList: (xml => new GetAlbumListResponse(xml)) as ResponseType<GetAlbumListResponse>,
|
||||||
|
getAlbumList2: (xml => new GetAlbumList2Response(xml)) as ResponseType<GetAlbumList2Response>,
|
||||||
|
getPlaylists: (xml => new GetPlaylistsResponse(xml)) as ResponseType<GetPlaylistsResponse>,
|
||||||
|
getPlaylist: (xml => new GetPlaylistResponse(xml)) as ResponseType<GetPlaylistResponse>,
|
||||||
|
scrobble: (xml => new NullResponse(xml)) as ResponseType<NullResponse>,
|
||||||
|
star: (xml => new NullResponse(xml)) as ResponseType<NullResponse>,
|
||||||
|
unstar: (xml => new NullResponse(xml)) as ResponseType<NullResponse>,
|
||||||
|
search3: (xml => new Search3Response(xml)) as ResponseType<Search3Response>,
|
||||||
|
}
|
||||||
|
|
||||||
export class SubsonicApiClient {
|
export class SubsonicApiClient {
|
||||||
address: string
|
address: string
|
||||||
username: string
|
username: string
|
||||||
@@ -129,96 +172,14 @@ export class SubsonicApiClient {
|
|||||||
return params
|
return params
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
async fetch<T extends keyof typeof Methods>(
|
||||||
// System
|
method: T,
|
||||||
//
|
...params: T extends Extract<keyof RequestParams, T> ? [RequestParams[Extract<keyof RequestParams, T>]] : []
|
||||||
|
): Promise<ReturnType<typeof Methods[T]>> {
|
||||||
async ping(): Promise<SubsonicResponse<null>> {
|
const xml = await this.apiGetXml(method, params.length > 0 ? params[0] : undefined)
|
||||||
const xml = await this.apiGetXml('ping')
|
return Methods[method](xml) as ReturnType<typeof Methods[T]>
|
||||||
return new SubsonicResponse<null>(xml, null)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Browsing
|
|
||||||
//
|
|
||||||
|
|
||||||
async getArtists(): Promise<SubsonicResponse<GetArtistsResponse>> {
|
|
||||||
const xml = await this.apiGetXml('getArtists')
|
|
||||||
return new SubsonicResponse<GetArtistsResponse>(xml, new GetArtistsResponse(xml))
|
|
||||||
}
|
|
||||||
|
|
||||||
async getIndexes(params?: GetIndexesParams): Promise<SubsonicResponse<GetIndexesResponse>> {
|
|
||||||
const xml = await this.apiGetXml('getIndexes', params)
|
|
||||||
return new SubsonicResponse<GetIndexesResponse>(xml, new GetIndexesResponse(xml))
|
|
||||||
}
|
|
||||||
|
|
||||||
async getMusicDirectory(params: GetMusicDirectoryParams): Promise<SubsonicResponse<GetMusicDirectoryResponse>> {
|
|
||||||
const xml = await this.apiGetXml('getMusicDirectory', params)
|
|
||||||
return new SubsonicResponse<GetMusicDirectoryResponse>(xml, new GetMusicDirectoryResponse(xml))
|
|
||||||
}
|
|
||||||
|
|
||||||
async getAlbum(params: GetAlbumParams): Promise<SubsonicResponse<GetAlbumResponse>> {
|
|
||||||
const xml = await this.apiGetXml('getAlbum', params)
|
|
||||||
return new SubsonicResponse<GetAlbumResponse>(xml, new GetAlbumResponse(xml))
|
|
||||||
}
|
|
||||||
|
|
||||||
async getArtistInfo(params: GetArtistInfoParams): Promise<SubsonicResponse<GetArtistInfoResponse>> {
|
|
||||||
const xml = await this.apiGetXml('getArtistInfo', params)
|
|
||||||
return new SubsonicResponse<GetArtistInfoResponse>(xml, new GetArtistInfoResponse(xml))
|
|
||||||
}
|
|
||||||
|
|
||||||
async getArtistInfo2(params: GetArtistInfo2Params): Promise<SubsonicResponse<GetArtistInfo2Response>> {
|
|
||||||
const xml = await this.apiGetXml('getArtistInfo2', params)
|
|
||||||
return new SubsonicResponse<GetArtistInfo2Response>(xml, new GetArtistInfo2Response(xml))
|
|
||||||
}
|
|
||||||
|
|
||||||
async getArtist(params: GetArtistParams): Promise<SubsonicResponse<GetArtistResponse>> {
|
|
||||||
const xml = await this.apiGetXml('getArtist', params)
|
|
||||||
return new SubsonicResponse<GetArtistResponse>(xml, new GetArtistResponse(xml))
|
|
||||||
}
|
|
||||||
|
|
||||||
async getTopSongs(params: GetTopSongsParams): Promise<SubsonicResponse<GetTopSongsResponse>> {
|
|
||||||
const xml = await this.apiGetXml('getTopSongs', params)
|
|
||||||
return new SubsonicResponse<GetTopSongsResponse>(xml, new GetTopSongsResponse(xml))
|
|
||||||
}
|
|
||||||
|
|
||||||
async getSong(params: GetSongParams): Promise<SubsonicResponse<GetSongResponse>> {
|
|
||||||
const xml = await this.apiGetXml('getSong', params)
|
|
||||||
return new SubsonicResponse<GetSongResponse>(xml, new GetSongResponse(xml))
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Album/song lists
|
|
||||||
//
|
|
||||||
|
|
||||||
async getAlbumList(params: GetAlbumListParams): Promise<SubsonicResponse<GetAlbumListResponse>> {
|
|
||||||
const xml = await this.apiGetXml('getAlbumList', params)
|
|
||||||
return new SubsonicResponse<GetAlbumListResponse>(xml, new GetAlbumListResponse(xml))
|
|
||||||
}
|
|
||||||
|
|
||||||
async getAlbumList2(params: GetAlbumList2Params): Promise<SubsonicResponse<GetAlbumList2Response>> {
|
|
||||||
const xml = await this.apiGetXml('getAlbumList2', params)
|
|
||||||
return new SubsonicResponse<GetAlbumList2Response>(xml, new GetAlbumList2Response(xml))
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Playlists
|
|
||||||
//
|
|
||||||
|
|
||||||
async getPlaylists(params?: GetPlaylistsParams): Promise<SubsonicResponse<GetPlaylistsResponse>> {
|
|
||||||
const xml = await this.apiGetXml('getPlaylists', params)
|
|
||||||
return new SubsonicResponse<GetPlaylistsResponse>(xml, new GetPlaylistsResponse(xml))
|
|
||||||
}
|
|
||||||
|
|
||||||
async getPlaylist(params: GetPlaylistParams): Promise<SubsonicResponse<GetPlaylistResponse>> {
|
|
||||||
const xml = await this.apiGetXml('getPlaylist', params)
|
|
||||||
return new SubsonicResponse<GetPlaylistResponse>(xml, new GetPlaylistResponse(xml))
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Media retrieval
|
|
||||||
//
|
|
||||||
|
|
||||||
getCoverArtUri(params?: GetCoverArtParams): string {
|
getCoverArtUri(params?: GetCoverArtParams): string {
|
||||||
return this.buildUrl('getCoverArt', params)
|
return this.buildUrl('getCoverArt', params)
|
||||||
}
|
}
|
||||||
@@ -226,32 +187,4 @@ export class SubsonicApiClient {
|
|||||||
streamUri(params: StreamParams): string {
|
streamUri(params: StreamParams): string {
|
||||||
return this.buildUrl('stream', params)
|
return this.buildUrl('stream', params)
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Media annotation
|
|
||||||
//
|
|
||||||
|
|
||||||
async scrobble(params: ScrobbleParams): Promise<SubsonicResponse<undefined>> {
|
|
||||||
const xml = await this.apiGetXml('scrobble', params)
|
|
||||||
return new SubsonicResponse<undefined>(xml, undefined)
|
|
||||||
}
|
|
||||||
|
|
||||||
async star(params: StarParams): Promise<SubsonicResponse<undefined>> {
|
|
||||||
const xml = await this.apiGetXml('star', params)
|
|
||||||
return new SubsonicResponse<undefined>(xml, undefined)
|
|
||||||
}
|
|
||||||
|
|
||||||
async unstar(params: StarParams): Promise<SubsonicResponse<undefined>> {
|
|
||||||
const xml = await this.apiGetXml('unstar', params)
|
|
||||||
return new SubsonicResponse<undefined>(xml, undefined)
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Searching
|
|
||||||
//
|
|
||||||
|
|
||||||
async search3(params: Search3Params): Promise<SubsonicResponse<Search3Response>> {
|
|
||||||
const xml = await this.apiGetXml('search3', params)
|
|
||||||
return new SubsonicResponse<Search3Response>(xml, new Search3Response(xml))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,128 +12,161 @@ import {
|
|||||||
|
|
||||||
export type ResponseStatus = 'ok' | 'failed'
|
export type ResponseStatus = 'ok' | 'failed'
|
||||||
|
|
||||||
export class SubsonicResponse<T> {
|
export class SubsonicResponse {
|
||||||
status: ResponseStatus
|
status: ResponseStatus
|
||||||
version: string
|
version: string
|
||||||
data: T
|
|
||||||
|
|
||||||
constructor(xml: Document, data: T) {
|
constructor(xml: Document) {
|
||||||
this.data = data
|
|
||||||
this.status = xml.documentElement.getAttribute('status') as ResponseStatus
|
this.status = xml.documentElement.getAttribute('status') as ResponseStatus
|
||||||
this.version = xml.documentElement.getAttribute('version') as string
|
this.version = xml.documentElement.getAttribute('version') as string
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class NullResponse extends SubsonicResponse {
|
||||||
|
data = null
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Browsing
|
// Browsing
|
||||||
//
|
//
|
||||||
|
|
||||||
export class GetArtistsResponse {
|
export class GetArtistsResponse extends SubsonicResponse {
|
||||||
|
data: {
|
||||||
ignoredArticles: string
|
ignoredArticles: string
|
||||||
artists: ArtistID3Element[] = []
|
artists: ArtistID3Element[]
|
||||||
|
}
|
||||||
|
|
||||||
constructor(xml: Document) {
|
constructor(xml: Document) {
|
||||||
this.ignoredArticles = xml.getElementsByTagName('artists')[0].getAttribute('ignoredArticles') as string
|
super(xml)
|
||||||
|
|
||||||
const artistElements = xml.getElementsByTagName('artist')
|
this.data = {
|
||||||
for (let i = 0; i < artistElements.length; i++) {
|
ignoredArticles: xml.getElementsByTagName('artists')[0].getAttribute('ignoredArticles') || '',
|
||||||
this.artists.push(new ArtistID3Element(artistElements[i]))
|
artists: Array.from(xml.getElementsByTagName('artist')).map(i => new ArtistID3Element(i)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class GetArtistResponse {
|
export class GetArtistResponse extends SubsonicResponse {
|
||||||
|
data: {
|
||||||
artist: ArtistID3Element
|
artist: ArtistID3Element
|
||||||
albums: AlbumID3Element[] = []
|
albums: AlbumID3Element[]
|
||||||
|
}
|
||||||
|
|
||||||
constructor(xml: Document) {
|
constructor(xml: Document) {
|
||||||
this.artist = new ArtistID3Element(xml.getElementsByTagName('artist')[0])
|
super(xml)
|
||||||
|
|
||||||
const albumElements = xml.getElementsByTagName('album')
|
this.data = {
|
||||||
for (let i = 0; i < albumElements.length; i++) {
|
artist: new ArtistID3Element(xml.getElementsByTagName('artist')[0]),
|
||||||
this.albums.push(new AlbumID3Element(albumElements[i]))
|
albums: Array.from(xml.getElementsByTagName('album')).map(i => new AlbumID3Element(i)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class GetIndexesResponse {
|
export class GetIndexesResponse extends SubsonicResponse {
|
||||||
|
data: {
|
||||||
ignoredArticles: string
|
ignoredArticles: string
|
||||||
lastModified: number
|
lastModified: number
|
||||||
artists: ArtistElement[] = []
|
artists: ArtistElement[]
|
||||||
|
}
|
||||||
|
|
||||||
constructor(xml: Document) {
|
constructor(xml: Document) {
|
||||||
|
super(xml)
|
||||||
|
|
||||||
const indexesElement = xml.getElementsByTagName('indexes')[0]
|
const indexesElement = xml.getElementsByTagName('indexes')[0]
|
||||||
|
|
||||||
this.ignoredArticles = indexesElement.getAttribute('ignoredArticles') as string
|
this.data = {
|
||||||
this.lastModified = parseInt(indexesElement.getAttribute('lastModified') as string, 10)
|
ignoredArticles: indexesElement.getAttribute('ignoredArticles') || '',
|
||||||
|
lastModified: parseInt(indexesElement.getAttribute('lastModified') || '0', 10),
|
||||||
const artistElements = xml.getElementsByTagName('artist')
|
artists: Array.from(xml.getElementsByTagName('artist')).map(i => new ArtistElement(i)),
|
||||||
for (let i = 0; i < artistElements.length; i++) {
|
|
||||||
this.artists.push(new ArtistElement(artistElements[i]))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class GetArtistInfoResponse {
|
export class GetArtistInfoResponse extends SubsonicResponse {
|
||||||
|
data: {
|
||||||
artistInfo: ArtistInfoElement
|
artistInfo: ArtistInfoElement
|
||||||
|
}
|
||||||
|
|
||||||
constructor(xml: Document) {
|
constructor(xml: Document) {
|
||||||
this.artistInfo = new ArtistInfoElement(xml.getElementsByTagName('artistInfo')[0])
|
super(xml)
|
||||||
|
|
||||||
|
this.data = {
|
||||||
|
artistInfo: new ArtistInfoElement(xml.getElementsByTagName('artistInfo')[0]),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class GetArtistInfo2Response {
|
export class GetArtistInfo2Response extends SubsonicResponse {
|
||||||
|
data: {
|
||||||
artistInfo: ArtistInfo2Element
|
artistInfo: ArtistInfo2Element
|
||||||
|
}
|
||||||
|
|
||||||
constructor(xml: Document) {
|
constructor(xml: Document) {
|
||||||
this.artistInfo = new ArtistInfo2Element(xml.getElementsByTagName('artistInfo2')[0])
|
super(xml)
|
||||||
|
|
||||||
|
this.data = {
|
||||||
|
artistInfo: new ArtistInfo2Element(xml.getElementsByTagName('artistInfo2')[0]),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class GetMusicDirectoryResponse {
|
export class GetMusicDirectoryResponse extends SubsonicResponse {
|
||||||
|
data: {
|
||||||
directory: DirectoryElement
|
directory: DirectoryElement
|
||||||
children: ChildElement[] = []
|
children: ChildElement[]
|
||||||
|
}
|
||||||
|
|
||||||
constructor(xml: Document) {
|
constructor(xml: Document) {
|
||||||
this.directory = new DirectoryElement(xml.getElementsByTagName('directory')[0])
|
super(xml)
|
||||||
|
|
||||||
const childElements = xml.getElementsByTagName('child')
|
this.data = {
|
||||||
for (let i = 0; i < childElements.length; i++) {
|
directory: new DirectoryElement(xml.getElementsByTagName('directory')[0]),
|
||||||
this.children.push(new ChildElement(childElements[i]))
|
children: Array.from(xml.getElementsByTagName('child')).map(i => new ChildElement(i)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class GetAlbumResponse {
|
export class GetAlbumResponse extends SubsonicResponse {
|
||||||
|
data: {
|
||||||
album: AlbumID3Element
|
album: AlbumID3Element
|
||||||
songs: ChildElement[] = []
|
songs: ChildElement[]
|
||||||
|
}
|
||||||
|
|
||||||
constructor(xml: Document) {
|
constructor(xml: Document) {
|
||||||
this.album = new AlbumID3Element(xml.getElementsByTagName('album')[0])
|
super(xml)
|
||||||
|
|
||||||
const childElements = xml.getElementsByTagName('song')
|
this.data = {
|
||||||
for (let i = 0; i < childElements.length; i++) {
|
album: new AlbumID3Element(xml.getElementsByTagName('album')[0]),
|
||||||
this.songs.push(new ChildElement(childElements[i]))
|
songs: Array.from(xml.getElementsByTagName('song')).map(i => new ChildElement(i)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class GetTopSongsResponse {
|
export class GetTopSongsResponse extends SubsonicResponse {
|
||||||
songs: ChildElement[] = []
|
data: {
|
||||||
|
songs: ChildElement[]
|
||||||
|
}
|
||||||
|
|
||||||
constructor(xml: Document) {
|
constructor(xml: Document) {
|
||||||
const childElements = xml.getElementsByTagName('song')
|
super(xml)
|
||||||
for (let i = 0; i < childElements.length; i++) {
|
|
||||||
this.songs.push(new ChildElement(childElements[i]))
|
this.data = {
|
||||||
|
songs: Array.from(xml.getElementsByTagName('song')).map(i => new ChildElement(i)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class GetSongResponse {
|
export class GetSongResponse extends SubsonicResponse {
|
||||||
|
data: {
|
||||||
song: ChildElement
|
song: ChildElement
|
||||||
|
}
|
||||||
|
|
||||||
constructor(xml: Document) {
|
constructor(xml: Document) {
|
||||||
this.song = new ChildElement(xml.getElementsByTagName('song')[0])
|
super(xml)
|
||||||
|
|
||||||
|
this.data = {
|
||||||
|
song: new ChildElement(xml.getElementsByTagName('song')[0]),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,13 +174,16 @@ export class GetSongResponse {
|
|||||||
// Album/song lists
|
// Album/song lists
|
||||||
//
|
//
|
||||||
|
|
||||||
class BaseGetAlbumListResponse<T> {
|
class BaseGetAlbumListResponse<T> extends SubsonicResponse {
|
||||||
albums: T[] = []
|
data: {
|
||||||
|
albums: T[]
|
||||||
|
}
|
||||||
|
|
||||||
constructor(xml: Document, albumType: new (e: Element) => T) {
|
constructor(xml: Document, AlbumType: new (e: Element) => T) {
|
||||||
const albumElements = xml.getElementsByTagName('album')
|
super(xml)
|
||||||
for (let i = 0; i < albumElements.length; i++) {
|
|
||||||
this.albums.push(new albumType(albumElements[i]))
|
this.data = {
|
||||||
|
albums: Array.from(xml.getElementsByTagName('album')).map(i => new AlbumType(i)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -168,22 +204,31 @@ export class GetAlbumList2Response extends BaseGetAlbumListResponse<AlbumID3Elem
|
|||||||
// Playlists
|
// Playlists
|
||||||
//
|
//
|
||||||
|
|
||||||
export class GetPlaylistsResponse {
|
export class GetPlaylistsResponse extends SubsonicResponse {
|
||||||
playlists: PlaylistElement[] = []
|
data: {
|
||||||
|
playlists: PlaylistElement[]
|
||||||
|
}
|
||||||
|
|
||||||
constructor(xml: Document) {
|
constructor(xml: Document) {
|
||||||
const playlistElements = xml.getElementsByTagName('playlist')
|
super(xml)
|
||||||
for (let i = 0; i < playlistElements.length; i++) {
|
|
||||||
this.playlists.push(new PlaylistElement(playlistElements[i]))
|
this.data = {
|
||||||
|
playlists: Array.from(xml.getElementsByTagName('playlist')).map(i => new PlaylistElement(i)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class GetPlaylistResponse {
|
export class GetPlaylistResponse extends SubsonicResponse {
|
||||||
|
data: {
|
||||||
playlist: PlaylistWithSongsElement
|
playlist: PlaylistWithSongsElement
|
||||||
|
}
|
||||||
|
|
||||||
constructor(xml: Document) {
|
constructor(xml: Document) {
|
||||||
this.playlist = new PlaylistWithSongsElement(xml.getElementsByTagName('playlist')[0])
|
super(xml)
|
||||||
|
|
||||||
|
this.data = {
|
||||||
|
playlist: new PlaylistWithSongsElement(xml.getElementsByTagName('playlist')[0]),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,25 +236,20 @@ export class GetPlaylistResponse {
|
|||||||
// Searching
|
// Searching
|
||||||
//
|
//
|
||||||
|
|
||||||
export class Search3Response {
|
export class Search3Response extends SubsonicResponse {
|
||||||
artists: ArtistID3Element[] = []
|
data: {
|
||||||
albums: AlbumID3Element[] = []
|
artists: ArtistID3Element[]
|
||||||
songs: ChildElement[] = []
|
albums: AlbumID3Element[]
|
||||||
|
songs: ChildElement[]
|
||||||
|
}
|
||||||
|
|
||||||
constructor(xml: Document) {
|
constructor(xml: Document) {
|
||||||
const artistElements = xml.getElementsByTagName('artist')
|
super(xml)
|
||||||
for (let i = 0; i < artistElements.length; i++) {
|
|
||||||
this.artists.push(new ArtistID3Element(artistElements[i]))
|
|
||||||
}
|
|
||||||
|
|
||||||
const albumElements = xml.getElementsByTagName('album')
|
this.data = {
|
||||||
for (let i = 0; i < albumElements.length; i++) {
|
artists: Array.from(xml.getElementsByTagName('artist')).map(i => new ArtistID3Element(i)),
|
||||||
this.albums.push(new AlbumID3Element(albumElements[i]))
|
albums: Array.from(xml.getElementsByTagName('album')).map(i => new AlbumID3Element(i)),
|
||||||
}
|
songs: Array.from(xml.getElementsByTagName('song')).map(i => new ChildElement(i)),
|
||||||
|
|
||||||
const songElements = xml.getElementsByTagName('song')
|
|
||||||
for (let i = 0; i < songElements.length; i++) {
|
|
||||||
this.songs.push(new ChildElement(songElements[i]))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user