Skip to content

Commit e0fac8c

Browse files
committed
Add Deezer track previews and inline playlist menus
- enrich release-group and library tracks with Deezer preview URLs - replace the track add modal with per-track playlist menus - cache Deezer album and preview matching results
1 parent a1ee97d commit e0fac8c

8 files changed

Lines changed: 855 additions & 275 deletions

File tree

backend/routes/artists/handlers/releaseGroup.js

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,28 @@ import { dbOps } from "../../../config/db-helpers.js";
33
import { cacheMiddleware } from "../../../middleware/cache.js";
44
import { warmImageProxy } from "../../../services/imageProxyService.js";
55
import { selectBestAlbumImage } from "../../../services/imageService.js";
6+
import { enrichTracksWithDeezerPreviews } from "../../../services/apiClients.js";
67
import {
78
getAlbumByMbid,
9+
getArtistByMbid,
810
getAlbumTracksByAlbumMbid,
911
} from "../../../services/metadataProvider.js";
1012

1113
const LEGACY_COVER_HOST_PATTERN =
1214
/https?:\/\/(?:caa\.lkly\.net|coverartarchive\.org|archive\.org|[\w-]+\.ca\.archive\.org)\//i;
1315

16+
function extractDeezerArtistIdFromLinks(links = []) {
17+
if (!Array.isArray(links)) return null;
18+
for (const link of links) {
19+
const type = String(link?.type || "").toLowerCase();
20+
const target = String(link?.target || link?.url?.resource || "").trim();
21+
if (type !== "deezer" && !/deezer\.com\/artist\//i.test(target)) continue;
22+
const match = target.match(/deezer\.com\/artist\/(\d+)/i);
23+
if (match?.[1]) return match[1];
24+
}
25+
return null;
26+
}
27+
1428
export default function registerReleaseGroup(router) {
1529
router.get("/release-group/:mbid/cover", cacheMiddleware(86400), async (req, res) => {
1630
try {
@@ -107,16 +121,70 @@ export default function registerReleaseGroup(router) {
107121
return res.status(400).json({ error: "Invalid MBID format" });
108122
}
109123

124+
const artistMbid =
125+
typeof req.query.artistMbid === "string" &&
126+
UUID_REGEX.test(req.query.artistMbid)
127+
? req.query.artistMbid
128+
: "";
129+
const artistName =
130+
typeof req.query.artistName === "string"
131+
? req.query.artistName.trim()
132+
: "";
133+
const albumTitle =
134+
typeof req.query.albumTitle === "string"
135+
? req.query.albumTitle.trim()
136+
: "";
137+
const releaseType =
138+
typeof req.query.releaseType === "string"
139+
? req.query.releaseType.trim()
140+
: "";
141+
const releaseDate =
142+
typeof req.query.releaseDate === "string"
143+
? req.query.releaseDate.trim()
144+
: "";
145+
const deezerAlbumId =
146+
typeof req.query.deezerAlbumId === "string"
147+
? req.query.deezerAlbumId.trim()
148+
: "";
149+
110150
const tracks = await getAlbumTracksByAlbumMbid(mbid);
151+
let deezerArtistId = "";
152+
if (artistMbid) {
153+
const override = dbOps.getArtistOverride(artistMbid);
154+
deezerArtistId = override?.deezerArtistId || "";
155+
if (!deezerArtistId) {
156+
const resolvedArtistMbid = override?.musicbrainzId || artistMbid;
157+
const metadataArtist = await getArtistByMbid(resolvedArtistMbid).catch(
158+
() => null,
159+
);
160+
deezerArtistId =
161+
extractDeezerArtistIdFromLinks(metadataArtist?.links) || "";
162+
}
163+
}
164+
const enrichedTracks = await enrichTracksWithDeezerPreviews(tracks, {
165+
artistName,
166+
deezerArtistId,
167+
deezerAlbumId,
168+
albumTitle,
169+
releaseType,
170+
releaseDate,
171+
cacheKey: `release-group:${mbid}:${
172+
deezerAlbumId || deezerArtistId || artistName
173+
}`,
174+
});
175+
111176
res.json(
112-
tracks.map((track) => ({
177+
enrichedTracks.map((track) => ({
113178
id: track.recordingId || track.id,
114179
mbid: track.recordingId || track.id,
115180
title: track.title,
116181
trackName: track.title,
117182
trackNumber: track.trackPosition || track.trackNumber || 0,
118183
position: track.trackPosition || track.trackNumber || 0,
119184
length: track.durationMs || null,
185+
preview_url: track.preview_url || null,
186+
previewProvider: track.previewProvider || null,
187+
previewTrackId: track.previewTrackId || null,
120188
})),
121189
);
122190
} catch (error) {

0 commit comments

Comments
 (0)