Last active
October 27, 2024 23:49
-
-
Save Maxr1998/7753d52333f5479ff2d95fa35db01268 to your computer and use it in GitHub Desktop.
Handles qbzdl:// URLs on Linux (which are otherwise handled by the official Qobuz downloader application on Windows) and generates an aria2 input file to download your purchased tracks.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import argparse | |
import mimetypes | |
import os | |
import subprocess | |
import requests | |
# Configuration | |
SCHEME = "qbzdl" | |
API_URL = "https://qobuz.com/v4/downloader/info?token%5B%5D=" | |
DOWNLOAD_CONFIG = "~/qobuz.aria2" | |
def register_url_handler(): | |
desktop_entry = f"""\ | |
[Desktop Entry] | |
Name=Qobuz Downloader | |
Exec=qbzdl handle %u | |
Type=Application | |
NoDisplay=true | |
MimeType=x-scheme-handler/{SCHEME}; | |
""" | |
desktop_path = os.path.expanduser(f"~/.local/share/applications/{SCHEME}-handler.desktop") | |
with open(desktop_path, "w") as f: | |
f.write(desktop_entry) | |
subprocess.run(["xdg-mime", "default", f"{SCHEME}-handler.desktop", f"x-scheme-handler/{SCHEME}"]) | |
print(f"URL handler for {SCHEME} registered.") | |
def init_mime(): | |
mimetypes.init() | |
mimetypes.add_type("audio/flac", ".flac", strict=True) | |
mimetypes.add_type("audio/mpeg", ".mp3", strict=True) | |
def handle_url(url): | |
init_mime() | |
query = url.split(f"{SCHEME}://")[1] | |
response = requests.get(f"{API_URL}{query}").json() | |
try: | |
data = response[0] | |
albums = {album["id"]: album for album in data["metadata"]["albums"]} | |
tracks = {track["id"]: track for track in data["metadata"]["tracks"]} | |
audios = [] | |
for audio in data["audios"]: | |
track_id = audio["track_id"] | |
track = tracks.get(track_id) | |
if not track: | |
print(f"Skipping track [{track_id}] missing from metadata") | |
continue | |
track_position = track["track_position"] | |
title = track["title"] | |
album_id = track["album"]["id"] | |
album = albums.get(album_id) | |
if not album: | |
print(f'Skipping track "{title}" due to album [{album_id}] missing from metadata') | |
continue | |
extension = mimetypes.guess_extension(audio.get("mime_type") or "audio/flac") | |
audios.append( | |
{ | |
"title": f"{track_position:02d} {title}{extension}", | |
"album": album["title"], | |
"url": audio["url"], | |
} | |
) | |
with open(os.path.expanduser(DOWNLOAD_CONFIG), "w") as f: | |
f.write("# Generated by qbzdl\n\n") | |
for audio in audios: | |
f.write(audio["url"] + "\n") | |
out_path = os.path.join("albums", audio["album"], audio['title']) | |
f.write(f" out={out_path}\n") | |
subprocess.run(["notify-send", f"Download configuration written to {DOWNLOAD_CONFIG}"]) | |
except KeyError as e: | |
print(f"Error processing data: Missing key {e}") | |
def main(): | |
parser = argparse.ArgumentParser(description="Qobuz Downloader") | |
subparsers = parser.add_subparsers() | |
parser_register = subparsers.add_parser("register", help="Register the qbzdl URL handler") | |
parser_register.set_defaults(action="register") | |
parser_handle_url = subparsers.add_parser("handle", help="Handle a qbzdl:// URL") | |
parser_handle_url.set_defaults(action="handle-url") | |
parser_handle_url.add_argument("url", help="The qbzdl:// URL to handle") | |
args = parser.parse_args() | |
if args.action == "register": | |
register_url_handler() | |
elif args.action == "handle-url": | |
assert args.url | |
handle_url(args.url) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment