75 lines
2.5 KiB
Python
75 lines
2.5 KiB
Python
"""
|
|
Monochrome - shared utilities for Tidal/Qobuz music downloading via Monochrome API instances.
|
|
"""
|
|
|
|
import json
|
|
import ssl
|
|
import sys
|
|
import urllib.request
|
|
import urllib.error
|
|
|
|
# Hardcoded fallback API instances
|
|
FALLBACK_INSTANCES = [
|
|
"https://monochrome.tf",
|
|
"https://triton.squid.wtf",
|
|
"https://qqdl.site",
|
|
"https://monochrome.samidy.com",
|
|
"https://api.monochrome.tf",
|
|
]
|
|
|
|
QOBUZ_API = "https://qobuz.squid.wtf/api"
|
|
UPTIME_URL = "https://tidal-uptime.jiffy-puffs-1j.workers.dev/"
|
|
|
|
# SSL context that doesn't verify certs (some instances have bad certs)
|
|
SSL_CTX = ssl.create_default_context()
|
|
SSL_CTX.check_hostname = False
|
|
SSL_CTX.verify_mode = ssl.CERT_NONE
|
|
|
|
|
|
def fetch(url, timeout=15, use_ssl_ctx=True):
|
|
"""Fetch a URL, returning the response object."""
|
|
req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0"})
|
|
ctx = SSL_CTX if use_ssl_ctx else None
|
|
return urllib.request.urlopen(req, timeout=timeout, context=ctx)
|
|
|
|
|
|
def fetch_json(url, timeout=15, use_ssl_ctx=True):
|
|
"""Fetch a URL and parse JSON response."""
|
|
with fetch(url, timeout, use_ssl_ctx) as resp:
|
|
return json.loads(resp.read().decode())
|
|
|
|
|
|
def discover_instances(log=None):
|
|
"""Get live API instances from uptime monitor, fall back to hardcoded list."""
|
|
if log is None:
|
|
log = print
|
|
try:
|
|
data = fetch_json(UPTIME_URL, timeout=10)
|
|
if isinstance(data, dict):
|
|
urls = []
|
|
for key, val in data.items():
|
|
if isinstance(val, dict) and val.get("url"):
|
|
urls.append(val["url"].rstrip("/"))
|
|
elif isinstance(val, str) and val.startswith("http"):
|
|
urls.append(val.rstrip("/"))
|
|
if urls:
|
|
log(f"[*] Discovered {len(urls)} instances from uptime monitor")
|
|
return urls
|
|
elif isinstance(data, list):
|
|
urls = []
|
|
for item in data:
|
|
if isinstance(item, str) and item.startswith("http"):
|
|
urls.append(item.rstrip("/"))
|
|
elif isinstance(item, dict):
|
|
u = item.get("url") or item.get("uri") or ""
|
|
if u.startswith("http"):
|
|
urls.append(u.rstrip("/"))
|
|
if urls:
|
|
log(f"[*] Discovered {len(urls)} instances from uptime monitor")
|
|
return urls
|
|
except Exception as e:
|
|
log(f"[!] Uptime discovery failed: {e}")
|
|
|
|
log(f"[*] Using {len(FALLBACK_INSTANCES)} fallback instances")
|
|
return list(FALLBACK_INSTANCES)
|