add isrc lookup to applicable services

This commit is contained in:
aria 2024-08-15 00:54:16 -04:00
parent dfdecafc1f
commit 2d2bfb93db
7 changed files with 59 additions and 13 deletions

View file

@ -1,6 +1,6 @@
{
"name": "lucida",
"version": "2.0.0-28",
"version": "2.0.0-29",
"description": "A modular music downloader tool",
"main": "build/index.js",
"type": "module",

View file

@ -91,6 +91,15 @@ class Lucida {
})
)
}
async isrcLookup(isrc: string) {
const results = await Promise.all(
Object.values(this.modules).map(async (e) => {
if (e.isrcLookup) return await e.isrcLookup(isrc)
})
)
const moduleNames = Object.keys(this.modules)
return Object.fromEntries(results.map((e, i) => [moduleNames[i], e]))
}
}
export default Lucida

View file

@ -520,4 +520,14 @@ export default class Deezer implements StreamerWithLogin {
explicit: userData.USER.EXPLICIT_CONTENT_LEVEL != 'explicit_hide'
}
}
async isrcLookup(isrc: string): Promise<Track> {
const resp = <{ type?: 'track'; link?: string }>(
await (await fetch(`https://api.deezer.com/track/isrc:${isrc}`)).json()
)
if (resp.type == 'track' && resp.link) {
const track = <Track>(await this.getByUrl(resp.link)).metadata
return track
} else throw new Error(`Not available on Deezer.`)
}
}

View file

@ -300,4 +300,12 @@ export default class Qobuz implements StreamerWithLogin {
explicit: true
}
}
async isrcLookup(isrc: string): Promise<Track> {
const isrcUrl = (await this.search(isrc)).tracks?.[0]?.url
if (!isrcUrl) throw new Error(`Not available on Qobuz.`)
else {
const track = <Track>(await this.getByUrl(isrcUrl)).metadata
return track
}
}
}

View file

@ -5,7 +5,8 @@ import {
ItemType,
SearchResults,
StreamerAccount,
StreamerWithLogin
StreamerWithLogin,
Track
} from '../../types.js'
class Spotify implements StreamerWithLogin {
@ -134,6 +135,11 @@ class Spotify implements StreamerWithLogin {
tracks: results.tracks?.map((e) => parseTrack(e)) ?? []
}
}
async isrcLookup(isrc: string): Promise<Track> {
const results = await this.search(`isrc:${isrc}`)
if (results?.tracks[0]) return <Track>(await this.getByUrl(results.tracks?.[0]?.url)).metadata
else throw new Error(`Not available on Spotify.`)
}
async getAccountInfo(): Promise<StreamerAccount> {
const info = await this.client.get.me()

View file

@ -64,6 +64,24 @@ interface SubscriptionData {
paymentOverdue: boolean
}
interface RawSearchResults {
albums: {
items: RawAlbum[]
}
artists: {
items: RawArtist[]
}
tracks: {
items: RawTrack[]
}
}
interface RawIsrcLookup {
limit: number
offset: number
items: RawTrack[]
}
export default class Tidal implements Streamer {
tvToken: string
tvSecret: string
@ -116,6 +134,11 @@ export default class Tidal implements Streamer {
'User-Agent': 'TIDAL_ANDROID/1039 okhttp/3.14.9'
}
}
async isrcLookup(isrc: string): Promise<Track> {
const isrcQuery = <RawIsrcLookup>await this.#get('tracks', { isrc })
if (isrcQuery?.items?.[0]) return <Track>(await this.getByUrl(isrcQuery.items[0].url)).metadata
else throw new Error(`Not available on Tidal.`)
}
async #get(
url: string,
params: { [key: string]: string | number } = {},
@ -257,17 +280,6 @@ export default class Tidal implements Streamer {
return false
}
async search(query: string, limit = 20): Promise<SearchResults> {
interface RawSearchResults {
albums: {
items: RawAlbum[]
}
artists: {
items: RawArtist[]
}
tracks: {
items: RawTrack[]
}
}
const results = <RawSearchResults>await this.#get('search/top-hits', {
query: query,
limit: limit,

View file

@ -149,6 +149,7 @@ export interface Streamer {
hostnames: string[]
testData?: StreamerTestData
search(query: string, limit: number): Promise<SearchResults>
isrcLookup?(isrc: string): Promise<Track>
getTypeFromUrl(url: string): Promise<ItemType>
getByUrl:
| ((url: string) => Promise<GetByUrlResponse>)