82 lines
2.5 KiB
Python
82 lines
2.5 KiB
Python
import os
|
|
import requests
|
|
from typing import List, Dict, Optional
|
|
|
|
MUSICBRAINZ_USER_AGENT = os.getenv("MUSICBRAINZ_USER_AGENT", "MusicApp/1.0")
|
|
MUSICBRAINZ_URL = "https://musicbrainz.org/ws/2/"
|
|
|
|
|
|
def search_artist(artist_name: str) -> Optional[Dict]:
|
|
try:
|
|
url = f"{MUSICBRAINZ_URL}artist"
|
|
params = {
|
|
"query": artist_name,
|
|
"fmt": "json",
|
|
"limit": 1,
|
|
}
|
|
headers = {"User-Agent": MUSICBRAINZ_USER_AGENT}
|
|
|
|
response = requests.get(url, params=params, headers=headers, timeout=10)
|
|
if response.status_code != 200:
|
|
return None
|
|
|
|
data = response.json()
|
|
artists = data.get("artists", [])
|
|
if artists:
|
|
a = artists[0]
|
|
return {
|
|
"id": a.get("id"),
|
|
"name": a.get("name"),
|
|
"releases": [],
|
|
}
|
|
return None
|
|
except (requests.RequestException, KeyError):
|
|
return None
|
|
|
|
|
|
def get_artist_releases(artist_id: str, limit: int = 10) -> List[Dict]:
|
|
try:
|
|
url = f"{MUSICBRAINZ_URL}artist/{artist_id}/releases"
|
|
params = {
|
|
"inc": "recordings+labels+artists",
|
|
"fmt": "json",
|
|
"limit": limit,
|
|
"order": "date",
|
|
}
|
|
headers = {"User-Agent": MUSICBRAINZ_USER_AGENT}
|
|
|
|
response = requests.get(url, params=params, headers=headers, timeout=10)
|
|
if response.status_code != 200:
|
|
return []
|
|
|
|
data = response.json()
|
|
releases = data.get("releases", [])
|
|
|
|
result = []
|
|
for rel in releases:
|
|
recordings = rel.get("media", [{}])[0].get("tracks", []) if rel.get("media") else []
|
|
tracks = []
|
|
for rec in recordings:
|
|
tracks.append({
|
|
"title": rec.get("title", "Unknown"),
|
|
"duration": int(rec.get("length", 0)) / 1000 if rec.get("length") else 0,
|
|
"duration_formatted": _format_duration(int(rec.get("length", 0)) / 1000),
|
|
})
|
|
|
|
result.append({
|
|
"id": rel.get("id"),
|
|
"title": rel.get("title", "Unknown"),
|
|
"cover_art": None,
|
|
"release_date": rel.get("date", ""),
|
|
"tracks": tracks,
|
|
})
|
|
|
|
return result
|
|
except (requests.RequestException, KeyError, IndexError):
|
|
return []
|
|
|
|
|
|
def _format_duration(seconds: float) -> str:
|
|
m = int(seconds // 60)
|
|
s = int(seconds % 60)
|
|
return f"{m}:{s:02d}" |