mirror of
https://codeberg.org/lucida/lucida.git
synced 2026-11-13 23:27:24 -05:00
add isrc lookup to applicable services
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "lucida",
|
"name": "lucida",
|
||||||
"version": "2.0.0-28",
|
"version": "2.0.0-29",
|
||||||
"description": "A modular music downloader tool",
|
"description": "A modular music downloader tool",
|
||||||
"main": "build/index.js",
|
"main": "build/index.js",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
@@ -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
|
export default Lucida
|
||||||
|
|||||||
@@ -520,4 +520,14 @@ export default class Deezer implements StreamerWithLogin {
|
|||||||
explicit: userData.USER.EXPLICIT_CONTENT_LEVEL != 'explicit_hide'
|
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.`)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -300,4 +300,12 @@ export default class Qobuz implements StreamerWithLogin {
|
|||||||
explicit: true
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ import {
|
|||||||
ItemType,
|
ItemType,
|
||||||
SearchResults,
|
SearchResults,
|
||||||
StreamerAccount,
|
StreamerAccount,
|
||||||
StreamerWithLogin
|
StreamerWithLogin,
|
||||||
|
Track
|
||||||
} from '../../types.js'
|
} from '../../types.js'
|
||||||
|
|
||||||
class Spotify implements StreamerWithLogin {
|
class Spotify implements StreamerWithLogin {
|
||||||
@@ -134,6 +135,11 @@ class Spotify implements StreamerWithLogin {
|
|||||||
tracks: results.tracks?.map((e) => parseTrack(e)) ?? []
|
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> {
|
async getAccountInfo(): Promise<StreamerAccount> {
|
||||||
const info = await this.client.get.me()
|
const info = await this.client.get.me()
|
||||||
|
|
||||||
|
|||||||
@@ -64,6 +64,24 @@ interface SubscriptionData {
|
|||||||
paymentOverdue: boolean
|
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 {
|
export default class Tidal implements Streamer {
|
||||||
tvToken: string
|
tvToken: string
|
||||||
tvSecret: string
|
tvSecret: string
|
||||||
@@ -116,6 +134,11 @@ export default class Tidal implements Streamer {
|
|||||||
'User-Agent': 'TIDAL_ANDROID/1039 okhttp/3.14.9'
|
'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(
|
async #get(
|
||||||
url: string,
|
url: string,
|
||||||
params: { [key: string]: string | number } = {},
|
params: { [key: string]: string | number } = {},
|
||||||
@@ -257,17 +280,6 @@ export default class Tidal implements Streamer {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
async search(query: string, limit = 20): Promise<SearchResults> {
|
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', {
|
const results = <RawSearchResults>await this.#get('search/top-hits', {
|
||||||
query: query,
|
query: query,
|
||||||
limit: limit,
|
limit: limit,
|
||||||
|
|||||||
@@ -149,6 +149,7 @@ export interface Streamer {
|
|||||||
hostnames: string[]
|
hostnames: string[]
|
||||||
testData?: StreamerTestData
|
testData?: StreamerTestData
|
||||||
search(query: string, limit: number): Promise<SearchResults>
|
search(query: string, limit: number): Promise<SearchResults>
|
||||||
|
isrcLookup?(isrc: string): Promise<Track>
|
||||||
getTypeFromUrl(url: string): Promise<ItemType>
|
getTypeFromUrl(url: string): Promise<ItemType>
|
||||||
getByUrl:
|
getByUrl:
|
||||||
| ((url: string) => Promise<GetByUrlResponse>)
|
| ((url: string) => Promise<GetByUrlResponse>)
|
||||||
|
|||||||
Reference in New Issue
Block a user