fix(search): trim leading aesthetic punctuation in artist lookups
Artists like ".diedlonely" (leading dot, †, ✝, _ …) weren't surfaced by iTunes, so the download's metadata lookup fell through to a titleOnly match — grabbing a same-titled track by another artist (e.g. the "In the Bleak Midwinter" Christmas carol: Holiday genre, 176s single) and steering the YouTube search to the wrong (slowed) version. - backend/metadata.js: strip leading non-alphanumeric from the search artist and the first-word comparison so the real artist matches (and the right album/genre/ duration are used). - android ExploreViewModel: strip leading symbols from the search term so the Explore tab finds these artists. Keeps the original name for display/storage — only the search/compare is trimmed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
d50e22b62d
commit
1775ec5b9b
2 files changed
+9
-3
No files matched your search
@@ -102,10 +102,13 @@ class ExploreViewModel(app: Application) : AndroidViewModel(app) {
|
||||
}
|
||||
|
||||
private fun search(q: String) {
|
||||
// Strip leading aesthetic punctuation (".diedlonely", "†…") so iTunes actually surfaces the
|
||||
// artist instead of nothing. Falls back to the raw query if it was only symbols.
|
||||
val term = q.trimStart { !it.isLetterOrDigit() }.trim().ifBlank { q }
|
||||
viewModelScope.launch {
|
||||
_state.value = _state.value.copy(isSearching = true, error = null)
|
||||
try {
|
||||
val resp = ItunesClient.search(q)
|
||||
val resp = ItunesClient.search(term)
|
||||
val results = resp.results
|
||||
_state.value = _state.value.copy(
|
||||
artists = results.filter { it.wrapperType == "artist" },
|
||||
|
||||
@@ -148,7 +148,10 @@ async function lookupItunesTrackMeta(artist, title) {
|
||||
// e.g. "don't rush - slowed" → search "don't rush" so iTunes finds the single
|
||||
const baseTitle = title.replace(/\s*[-–]\s*\S[^-]*$/, '').trim() || title;
|
||||
const searchTitle = baseTitle !== title ? baseTitle : title;
|
||||
const searchArtist = artist.split(/[;,&]/)[0].trim();
|
||||
// Strip leading aesthetic punctuation many artists use (".diedlonely", "†", "✝", "_x")
|
||||
// so the iTunes search actually surfaces them instead of a same-titled track by someone else.
|
||||
const stripLeadSym = s => (s || '').replace(/^[^\p{L}\p{N}]+/u, '').trim();
|
||||
const searchArtist = stripLeadSym(artist.split(/[;,&]/)[0].trim());
|
||||
const fetchItunes = (country) => new Promise((resolve, reject) => {
|
||||
const url = `https://itunes.apple.com/search?term=${encodeURIComponent(searchArtist + ' ' + searchTitle)}&media=music&entity=musicTrack&limit=10&country=${country}&explicit=Yes`;
|
||||
https.get(url, res => {
|
||||
@@ -159,7 +162,7 @@ async function lookupItunesTrackMeta(artist, title) {
|
||||
const normT = normalizeTitle(title);
|
||||
const normA = (searchArtist || '').toLowerCase().trim();
|
||||
// Split by space OR comma/semicolon/slash so "VXLLAIN, iGRES" → "vxllain" not "vxllain,"
|
||||
const firstWord = s => (s || '').toLowerCase().split(/[\s,;/]/)[0];
|
||||
const firstWord = s => stripLeadSym((s || '').toLowerCase()).split(/[\s,;/]/)[0];
|
||||
const strictMatch = results => results.find(t =>
|
||||
normalizeTitle(t.trackName) === normT && firstWord(t.artistName) === firstWord(normA)
|
||||
);
|
||||
|
||||
Reference in new issue
Block a user