Add Metadata

This commit is contained in:
Christoph Stahl 2025-08-09 23:18:56 +02:00
parent 6b130dac00
commit 14f58de9e5

51
qobuz-dl-remote.py Normal file → Executable file
View file

@ -1,8 +1,13 @@
#!/usr/bin/env python3
from typing import Any, Literal
import requests
import tqdm
from mutagen.flac import FLAC, Picture
import sys
from dataclasses import dataclass
import datetime
from PIL import Image
from io import BytesIO
QOBUZ_API_BASE = "https://us.qobuz.squid.wtf/api"
QUALITY = 27
@ -11,7 +16,12 @@ QUALITY = 27
@dataclass
class Track:
title: str
artist: str
nr: int
id: str
album_name: str
release_date: datetime.date
cover: Image.Image | None
@dataclass
@ -44,14 +54,35 @@ class Album:
maximum_sampling_rate: int
id: str
image: ImageLink
release_date: datetime.date
@classmethod
def from_dict(cls, data: dict[Any, Any]) -> "Album":
tracks = None
release_date = datetime.date.fromtimestamp(data["released_at"])
image = ImageLink.from_dict(data["image"])
image_data = None
if image.large is not None:
# Fetch image
print(f"Fetching image from {image.large}")
image_content = BytesIO(requests.get(image.large).content)
image_data = Image.open(image_content)
if "tracks" in data and "track_ids" in data:
tracks = [
Track(id=tid, title=track["title"])
for tid, track in zip(data["track_ids"], data["tracks"]["items"])
Track(
nr=tnr + 1,
artist=data["artist"]["name"],
id=tid,
title=track["title"],
album_name=data["title"],
release_date=release_date,
cover=image_data,
)
for tnr, (tid, track) in enumerate(
zip(data["track_ids"], data["tracks"]["items"])
)
]
return cls(
artist=data["artist"]["name"],
@ -61,6 +92,7 @@ class Album:
maximum_sampling_rate=data["maximum_sampling_rate"],
id=data["id"],
image=ImageLink.from_dict(data["image"]),
release_date=release_date,
)
@ -80,8 +112,8 @@ class Qobuz:
return result_json["data"]["url"]
raise RuntimeError(f"Failed to get download URL, result: {result}")
def download_track(self, track_id: str, filename: str) -> None:
download_url = self.get_download_url(track_id)
def download_track(self, track: Track, filename: str) -> None:
download_url = self.get_download_url(track.id)
response = requests.get(download_url, stream=True)
if response.status_code == 200:
total_size = int(response.headers.get("content-length", 0))
@ -92,6 +124,15 @@ class Qobuz:
for chunk in response.iter_content(chunk_size=8192):
file.write(chunk)
pbar.update(len(chunk))
# Set metadata using mutagen
audio = FLAC(filename)
audio["title"] = track.title
audio["artist"] = track.artist
audio["tracknumber"] = str(track.nr)
audio["album"] = track.album_name
audio["date"] = track.release_date.isoformat()
audio.save()
print(f"Downloaded {filename}")
else:
raise RuntimeError("Failed to download track")
@ -112,7 +153,7 @@ class Qobuz:
for nr, track in enumerate(tracks):
print(f"Downloading track #{nr + 1:02d} {track.title}...")
filename = f"{artist} - {album_title} - {nr + 1:02d} {track.title}.flac"
self.download_track(track.id, filename)
self.download_track(track, filename)
def search_album(self, query: str) -> Album:
print(f'Searching for "{query}"')