50 lines
1.8 KiB
TypeScript
50 lines
1.8 KiB
TypeScript
import {JSDOM} from 'jsdom';
|
|
import {Song, SongSource} from '../types/queue';
|
|
|
|
const TITLE_SELECTOR: string = 'h1[class="svelte-6pt9ji"]';
|
|
const ARTIST_SELECTOR: string = 'h2[class="svelte-6pt9ji"]';
|
|
const TRACK_COUNT_SELECTOR: string = 'h3[class="svelte-6pt9ji"]';
|
|
const COVER_SELECTOR: string = 'a[title="Click for full quality cover (unproxied)."]';
|
|
|
|
export async function fetchMetadata(url: string): Promise<Song> {
|
|
const resp: Response = await fetch('https://lucida.to/?url=' + encodeURIComponent(url));
|
|
if (!resp.ok) {
|
|
return {
|
|
title: '<unknown>',
|
|
artist: '<unknown>',
|
|
trackCount: -1,
|
|
url: url,
|
|
source: getSource(url)
|
|
}
|
|
}
|
|
|
|
const doc: Document = new JSDOM(await resp.text()).window.document;
|
|
const title: string = doc.querySelector(TITLE_SELECTOR)?.textContent?.trim() ?? '<unknown>';
|
|
const artist: string = doc.querySelector(ARTIST_SELECTOR)?.textContent?.trim() ?? '<unknown>';
|
|
const trackCount: number = parseInt(doc.querySelector(TRACK_COUNT_SELECTOR)?.innerHTML.trim().split(' ')[0] ?? '-1');
|
|
const cover: string | undefined = doc.querySelector(COVER_SELECTOR)?.attributes.getNamedItem('href')?.value ?? undefined;
|
|
|
|
return {
|
|
title: title,
|
|
artist: artist.substring(artist.indexOf(' ') + 1),
|
|
trackCount: trackCount,
|
|
url: url,
|
|
source: getSource(url),
|
|
cover: cover
|
|
}
|
|
}
|
|
|
|
function getSource(url: string): SongSource {
|
|
const urlToSource: Map<string, SongSource> = new Map([
|
|
['qobuz.com', SongSource.Qobuz],
|
|
['spotify.com', SongSource.Spotify]
|
|
]);
|
|
|
|
for (const [key, value] of urlToSource) {
|
|
if (url.includes(key)) {
|
|
return value;
|
|
}
|
|
}
|
|
|
|
return SongSource.Unknown;
|
|
}
|