traxsource: helper _split_title_mix + _format_artists + _large_cover + eccezioni
This commit is contained in:
1 parent
a95912f78c
commit
e1e629f8a2
2 files changed
+95
No files matched your search
@@ -6,6 +6,7 @@ Spec: docs/superpowers/specs/2026-08-01-traxsource-charts-design.md.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from dataclasses import dataclass
|
||||
|
||||
|
||||
@@ -59,3 +60,47 @@ def list_genres() -> list:
|
||||
]
|
||||
result.sort(key=lambda g: g["name"].casefold())
|
||||
return result
|
||||
|
||||
|
||||
class TraxsourceError(Exception):
|
||||
"""Base per errori Traxsource."""
|
||||
|
||||
|
||||
class TraxsourceUnreachableError(TraxsourceError):
|
||||
"""Rete / 5xx dopo retry."""
|
||||
|
||||
|
||||
class TraxsourceParseError(TraxsourceError):
|
||||
"""HTML ricevuto ma non conforme allo schema atteso."""
|
||||
|
||||
|
||||
_MIX_PAREN_RE = re.compile(r"^(.*)\s*\(([^()]+)\)\s*$")
|
||||
_SIZE_RE = re.compile(r"/\d+x\d+/")
|
||||
|
||||
|
||||
def _split_title_mix(full_title: str) -> tuple:
|
||||
"""Estrae mix dalle parentesi finali. 'Foo (Extended Mix)' -> ('Foo', 'Extended Mix').
|
||||
Se non ci sono parentesi finali, mix = ''."""
|
||||
if not full_title:
|
||||
return ("", "")
|
||||
m = _MIX_PAREN_RE.match(full_title.strip())
|
||||
if m:
|
||||
return (m.group(1).strip(), m.group(2).strip())
|
||||
return (full_title.strip(), "")
|
||||
|
||||
|
||||
def _format_artists(names: list) -> str:
|
||||
"""['A', 'B', 'C'] -> 'A, B & C'. Strips whitespace."""
|
||||
clean = [n.strip() for n in names if n and n.strip()]
|
||||
if not clean:
|
||||
return ""
|
||||
if len(clean) == 1:
|
||||
return clean[0]
|
||||
return ", ".join(clean[:-1]) + " & " + clean[-1]
|
||||
|
||||
|
||||
def _large_cover(url: str) -> str:
|
||||
"""Sostituisce /NxN/ nel path con /500x500/. Se pattern assente, ritorna invariato."""
|
||||
if not url:
|
||||
return ""
|
||||
return _SIZE_RE.sub("/500x500/", url)
|
||||
Reference in new issue
Block a user