initial v1

This commit is contained in:
Volker
2025-12-25 22:32:24 +01:00
commit f2cb420182
18 changed files with 933 additions and 0 deletions
+97
View File
@@ -0,0 +1,97 @@
import musicbrainzngs
import logging
import os
from .config import config
from datetime import datetime
from email.utils import formatdate
logger = logging.getLogger(__name__)
def init_musicbrainz():
app_name = config.MB_APP_NAME
version = config.MB_VERSION
contact = config.MB_CONTACT
logger.debug(f"Initializing MusicBrainz API with user agent: {app_name}/{version} ( {contact} )")
musicbrainzngs.set_useragent(app_name, version, contact)
def search_artists(query):
logger.debug(f"Searching for artists with query: '{query}'")
try:
result = musicbrainzngs.search_artists(query=query, limit=10)
artists = []
if 'artist-list' in result:
for artist in result['artist-list']:
artists.append({
'id': artist['id'],
'name': artist['name'],
'disambiguation': artist.get('disambiguation', '')
})
logger.debug(f"Found {len(artists)} artists for query: '{query}'")
return artists
except musicbrainzngs.MusicBrainzError as e:
logger.error(f"MusicBrainz API error while searching for '{query}': {e}")
return []
def _parse_release_date(release_date_str, release_title):
"""Parse a release date string which can be YYYY, YYYY-MM, or YYYY-MM-DD."""
if not release_date_str:
return None, None
date_formats = ['%Y-%m-%d', '%Y-%m', '%Y']
dt = None
for fmt in date_formats:
try:
dt = datetime.strptime(release_date_str, fmt)
if fmt == '%Y-%m':
dt = dt.replace(day=1)
elif fmt == '%Y':
dt = dt.replace(month=1, day=1)
break # Found a valid format
except (ValueError, TypeError):
continue
if dt:
return dt, formatdate(dt.timestamp())
logger.warning(f"Could not parse date format '{release_date_str}' for release '{release_title}'")
return None, None
def _process_release(release, artist_id):
"""Process a single release from the MusicBrainz API response."""
release_date = release.get('date', 'Unknown')
_, pub_date = _parse_release_date(release_date, release['title'])
return {
'artist': {
'name': config.get_artist_name(artist_id),
'id': artist_id,
},
'hasCoverArt': release.get('cover-art-archive', {}).get('artwork') == 'true',
'id': release['id'],
'title': release['title'],
'date': release_date,
'pub_date': pub_date,
'release-group': release.get('release-group', {})
}
def get_artist_releases(artist_id):
"""Fetch releases for a given artist ID from MusicBrainz."""
artist_name = config.get_artist_name(artist_id)
logger.debug(f"Fetching releases for artist {artist_name} ({artist_id})")
try:
result = musicbrainzngs.browse_releases(
artist=artist_id,
release_type=['album'],
includes=['release-groups']
)
releases = []
if 'release-list' in result:
releases = [_process_release(r, artist_id) for r in result['release-list']]
logger.debug(f"Found {len(releases)} releases for artist {artist_name} ({artist_id})")
return releases
except musicbrainzngs.MusicBrainzError as e:
logger.error(f"MusicBrainz API error while fetching releases for artist '{artist_id}': {e}")
return []