This repository has been archived on 2025-08-08. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.
lucida-queue/backend/services/metadata.ts

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;
}