@@ -7,6 +7,95 @@ import {
77
88const SOLR_ENDPOINT = 'https://solr.sscdn.co/letras/m1/'
99
10+ const cleanText = ( text ) => {
11+ if ( ! text ) return ''
12+ return text
13+ . replace ( / \s * \( [ ^ ) ] * \) / g, ' ' )
14+ . replace ( / \s * \[ [ ^ \] ] * \] / g, ' ' )
15+ . replace (
16+ / \b ( o f f i c i a l | v i d e o | a u d i o | m v | v i s u a l i z e r | l i v e | s e s s i o n | a o v i v o | l y r i c | l y r i c s | h d | 4 k | r e m i x | e d i t | c o v e r | a c o u s t i c | i n s t r u m e n t a l ) \b / gi,
17+ ' '
18+ )
19+ . replace ( / f e a t \. ? / gi, ' ' )
20+ . replace ( / f t \. ? / gi, ' ' )
21+ . replace ( / [ ^ \w \s ] / g, ' ' )
22+ . replace ( / \s + / g, ' ' )
23+ . trim ( )
24+ }
25+
26+ const buildSearchCandidates = ( trackInfo ) => {
27+ const candidates = new Set ( )
28+ const rawTitle = trackInfo ?. title || ''
29+ const rawAuthor = trackInfo ?. author || ''
30+
31+ const cleanedTitle = cleanText ( rawTitle )
32+ const cleanedAuthor = cleanText ( rawAuthor )
33+
34+ const pushCandidate = ( title , author ) => {
35+ const t = cleanText ( title )
36+ const a = cleanText ( author )
37+ const combined = [ t , a ] . filter ( Boolean ) . join ( ' ' ) . trim ( )
38+ if ( combined ) candidates . add ( combined )
39+ }
40+
41+ const rawTitleLower = rawTitle . toLowerCase ( )
42+ const rawAuthorLower = rawAuthor . toLowerCase ( )
43+
44+ if ( cleanedTitle || cleanedAuthor ) {
45+ pushCandidate ( cleanedTitle , cleanedAuthor )
46+ }
47+
48+ if ( cleanedTitle ) candidates . add ( cleanedTitle )
49+
50+ const splitTitle = ( title , sep ) => {
51+ if ( ! title . includes ( sep ) ) return null
52+ const parts = title . split ( sep ) . map ( ( part ) => part . trim ( ) )
53+ if ( parts . length < 2 ) return null
54+ return [ parts [ 0 ] , parts . slice ( 1 ) . join ( sep ) . trim ( ) ]
55+ }
56+
57+ const dashSplit = splitTitle ( rawTitle , ' - ' )
58+ if ( dashSplit ) {
59+ const [ left , right ] = dashSplit
60+ const leftClean = cleanText ( left )
61+ const rightClean = cleanText ( right )
62+
63+ if ( rightClean ) {
64+ pushCandidate ( rightClean , cleanedAuthor || leftClean )
65+ candidates . add ( rightClean )
66+ }
67+
68+ if ( leftClean && rightClean ) {
69+ pushCandidate ( rightClean , leftClean )
70+ }
71+ }
72+
73+ const pipeSplit = splitTitle ( rawTitle , ' | ' )
74+ if ( pipeSplit ) {
75+ const [ left , right ] = pipeSplit
76+ const leftClean = cleanText ( left )
77+ const rightClean = cleanText ( right )
78+ if ( leftClean ) candidates . add ( leftClean )
79+ if ( rightClean ) candidates . add ( rightClean )
80+ if ( leftClean && cleanedAuthor ) pushCandidate ( leftClean , cleanedAuthor )
81+ }
82+
83+ if ( rawAuthorLower && rawTitleLower . includes ( rawAuthorLower ) ) {
84+ const stripped = cleanText ( rawTitle . replace ( new RegExp ( rawAuthor , 'ig' ) , '' ) )
85+ if ( stripped ) {
86+ pushCandidate ( stripped , cleanedAuthor )
87+ candidates . add ( stripped )
88+ }
89+ }
90+
91+ if ( cleanedAuthor ) {
92+ pushCandidate ( cleanedTitle , cleanedAuthor )
93+ candidates . add ( cleanedAuthor )
94+ }
95+
96+ return Array . from ( candidates )
97+ }
98+
1099const parseJsonp = ( body ) => {
11100 if ( ! body ) return null
12101 const trimmed = body . trim ( )
@@ -139,30 +228,65 @@ export default class LetrasMusMeaning {
139228
140229 async getMeaning ( trackInfo , language ) {
141230 try {
142- let letrasTrack = trackInfo
143- if ( trackInfo . sourceName !== 'letrasmus' ) {
144- const query = `${ trackInfo . title } ${ trackInfo . author } ` . trim ( )
145- const results = await searchLetras ( query , 10 )
231+ let candidates = [ ]
232+ if ( trackInfo . sourceName === 'letrasmus' ) {
233+ candidates = [ { info : trackInfo } ]
234+ } else {
235+ const searchCandidates = buildSearchCandidates ( trackInfo )
236+ let results = [ ]
237+
238+ for ( const query of searchCandidates ) {
239+ results = await searchLetras ( query , 12 )
240+ if ( results . length ) break
241+ }
242+
146243 if ( results . length ) {
147- const best = getBestMatch ( results , trackInfo )
148- if ( best ?. info ) {
149- letrasTrack = best . info
244+ const matchTarget = {
245+ ...trackInfo ,
246+ title : cleanText ( trackInfo . title ) ,
247+ author : cleanText ( trackInfo . author )
248+ }
249+ const best = getBestMatch ( results , matchTarget )
250+ const ordered = [ ]
251+ if ( best ?. info ) ordered . push ( best )
252+ for ( const item of results ) {
253+ if ( ! best || item . info . uri !== best . info ?. uri ) ordered . push ( item )
150254 }
255+ candidates = ordered
151256 }
152257 }
153258
154- if ( ! letrasTrack ?. uri || letrasTrack . sourceName !== 'letrasmus' ) {
259+ if ( ! candidates . length ) {
155260 return { loadType : 'empty' , data : { } }
156261 }
157262
158- const baseUrl = letrasTrack . uri . endsWith ( '/' )
159- ? letrasTrack . uri
160- : `${ letrasTrack . uri } /`
161- const meaningUrl = `${ baseUrl } significado.html`
162- const { body, statusCode, error } = await http1makeRequest ( meaningUrl , {
163- method : 'GET'
164- } )
165- if ( error || statusCode !== 200 || ! body ) {
263+ let body = null
264+ let meaningUrl = null
265+ let resolvedTrack = null
266+
267+ for ( const candidate of candidates ) {
268+ const letrasTrack = candidate . info
269+ if ( ! letrasTrack ?. uri || letrasTrack . sourceName !== 'letrasmus' ) continue
270+
271+ const baseUrl = letrasTrack . uri . endsWith ( '/' )
272+ ? letrasTrack . uri
273+ : `${ letrasTrack . uri } /`
274+ const url = `${ baseUrl } significado.html`
275+ const { body : fetchedBody , statusCode, error } =
276+ await http1makeRequest ( url , { method : 'GET' } )
277+
278+ if ( error || statusCode !== 200 || ! fetchedBody ) continue
279+
280+ const meaningCheck = extractMeaning ( fetchedBody )
281+ if ( ! meaningCheck . body . length ) continue
282+
283+ body = fetchedBody
284+ meaningUrl = url
285+ resolvedTrack = letrasTrack
286+ break
287+ }
288+
289+ if ( ! body || ! meaningUrl || ! resolvedTrack ) {
166290 return { loadType : 'empty' , data : { } }
167291 }
168292
@@ -218,8 +342,8 @@ export default class LetrasMusMeaning {
218342 reviewedBy : null
219343 } ,
220344 song : {
221- title : omq ?. Name || letrasTrack . title || null ,
222- artist : omq ?. Artist || letrasTrack . author || null ,
345+ title : omq ?. Name || resolvedTrack . title || null ,
346+ artist : omq ?. Artist || resolvedTrack . author || null ,
223347 youtubeId : omq ?. YoutubeID || null ,
224348 letrasId : omq ?. ID || null ,
225349 artworkUrl : ogImage || null
0 commit comments