@@ -3,14 +3,28 @@ import { dbOps } from "../../../config/db-helpers.js";
33import { cacheMiddleware } from "../../../middleware/cache.js" ;
44import { warmImageProxy } from "../../../services/imageProxyService.js" ;
55import { selectBestAlbumImage } from "../../../services/imageService.js" ;
6+ import { enrichTracksWithDeezerPreviews } from "../../../services/apiClients.js" ;
67import {
78 getAlbumByMbid ,
9+ getArtistByMbid ,
810 getAlbumTracksByAlbumMbid ,
911} from "../../../services/metadataProvider.js" ;
1012
1113const LEGACY_COVER_HOST_PATTERN =
1214 / h t t p s ? : \/ \/ (?: c a a \. l k l y \. n e t | c o v e r a r t a r c h i v e \. o r g | a r c h i v e \. o r g | [ \w - ] + \. c a \. a r c h i v e \. o r g ) \/ / 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" && ! / d e e z e r \. c o m \/ a r t i s t \/ / i. test ( target ) ) continue ;
22+ const match = target . match ( / d e e z e r \. c o m \/ a r t i s t \/ ( \d + ) / i) ;
23+ if ( match ?. [ 1 ] ) return match [ 1 ] ;
24+ }
25+ return null ;
26+ }
27+
1428export 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