mirror of
https://github.com/ZuneDev/PyZuneImageCatalogServer.git
synced 2026-07-27 13:12:06 -07:00
Added artist images
This commit is contained in:
@@ -96,3 +96,4 @@ ENV/
|
||||
|
||||
# App secrets
|
||||
*.key
|
||||
/secrets.py
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
import requests
|
||||
from requests import RequestException, Response
|
||||
import urllib.error
|
||||
import musicbrainzngs
|
||||
from musicbrainzngs.musicbrainz import ResponseError
|
||||
from secrets import *
|
||||
import json
|
||||
|
||||
from typing import Union, Tuple, Dict
|
||||
|
||||
|
||||
DISCOGS_API: str = "https://api.discogs.com"
|
||||
DC_HEADERS: Dict[str, str] = {
|
||||
"User-Agent": USER_AGENT,
|
||||
"Authorization": f"Discogs key={DC_API_KEY}, secret={DC_API_SECRET}"
|
||||
}
|
||||
|
||||
|
||||
def get_artist_from_dcid(dcid: Union[int, str]) -> Union[int, dict]:
|
||||
try:
|
||||
response: Response = requests.get("https://api.discogs.com/artists/" + str(dcid), headers=DC_HEADERS)
|
||||
except RequestException as error:
|
||||
return error.response.status_code
|
||||
|
||||
discogs: dict = response.json()
|
||||
return discogs
|
||||
|
||||
|
||||
def get_artist_from_mbid(mbid: str) -> Tuple[Union[int, dict], dict]:
|
||||
try:
|
||||
mb_artist: dict = musicbrainzngs.get_artist_by_id(mbid, includes=["url-rels", "tags"])["artist"]
|
||||
except ResponseError as error:
|
||||
return error.cause.code
|
||||
|
||||
dc_artist: dict = get_artist_from_mbobj(mb_artist)
|
||||
return dc_artist, mb_artist
|
||||
|
||||
|
||||
def get_artist_from_mbobj(mbobj: dict) -> Union[int, dict]:
|
||||
if "url-relation-list" not in mbobj:
|
||||
return 404
|
||||
discogs_rel = [x for x in mbobj["url-relation-list"] if x["type"] == "discogs"]
|
||||
if len(discogs_rel) < 1:
|
||||
return 404
|
||||
discogs_link: str = discogs_rel[0]["target"].replace("www", "api").replace("artist", "artists")
|
||||
try:
|
||||
response = urllib.request.urlopen(discogs_link)
|
||||
except urllib.error.HTTPError as error:
|
||||
return error.code
|
||||
|
||||
discogs: dict = json.load(response)
|
||||
return discogs
|
||||
@@ -1,19 +1,29 @@
|
||||
import json
|
||||
|
||||
from typing import Dict, List
|
||||
from flask import Flask, request, Response, abort, send_file
|
||||
import urllib.request
|
||||
from urllib.error import HTTPError
|
||||
from io import BytesIO
|
||||
import requests
|
||||
from requests import RequestException
|
||||
|
||||
import musicbrainzngs
|
||||
import api.discogs as discogs
|
||||
from secrets import USER_AGENT
|
||||
|
||||
from locale import *
|
||||
|
||||
|
||||
locale = getdefaultlocale()[0]
|
||||
|
||||
|
||||
app = Flask(__name__)
|
||||
caa_supported_sizes = [250, 500, 1200]
|
||||
dc_artist_cache: Dict[str, dict] = {}
|
||||
|
||||
musicbrainzngs.set_useragent("Zune", "4.8", "https://github.com/yoshiask/PyZuneImageCatalogServer")
|
||||
DEFAULT_HEADERS: Dict[str, str] = {
|
||||
"User-Agent": USER_AGENT
|
||||
}
|
||||
|
||||
|
||||
import re
|
||||
@@ -40,46 +50,33 @@ def default():
|
||||
|
||||
@app.route(f"/v3.2/<string:locale>/image/<string:mbid>")
|
||||
def get_image(mbid: str, locale: str):
|
||||
# The Cover Art Archive API supports sizes of 250, 500, and 1200
|
||||
requested_width = request.args.get("width", default=500, type=int)
|
||||
width = min(caa_supported_sizes, key=lambda x: abs(x - requested_width))
|
||||
image_url: str = ""
|
||||
if mbid.endswith('0' * 12):
|
||||
dcid: int = int(mbid[:8], 16)
|
||||
img_idx: int = int(mbid[9:13], 16)
|
||||
|
||||
# Get or update cached artist
|
||||
dc_artist: dict = dc_artist_cache.get(dcid)
|
||||
if dc_artist is None:
|
||||
# Artist not in cache
|
||||
dc_artist = discogs.get_artist_from_dcid(dcid)
|
||||
dc_artist_cache[dcid] = dc_artist
|
||||
|
||||
# Get URL for requested image
|
||||
image_url = dc_artist["images"][img_idx]["uri"]
|
||||
else:
|
||||
# The Cover Art Archive API supports sizes of 250, 500, and 1200
|
||||
requested_width = request.args.get("width", default=500, type=int)
|
||||
width = min(caa_supported_sizes, key=lambda x: abs(x - requested_width))
|
||||
image_url = f"http://coverartarchive.org/release/{mbid}/front-{width}"
|
||||
|
||||
# Request the image from the API and forward it to the Zune software
|
||||
try:
|
||||
image = urllib.request.urlopen(f"http://coverartarchive.org/release/{mbid}/front-{width}")
|
||||
return Response(image.read(), mimetype="image/jpeg")
|
||||
except urllib.error.HTTPError as error:
|
||||
image = requests.get(image_url, headers=DEFAULT_HEADERS, stream=True)
|
||||
return Response(BytesIO(image.content), content_type="image/jpeg")
|
||||
except RequestException as error:
|
||||
return send_file('noart.png', attachment_filename='noart.png')
|
||||
|
||||
|
||||
@app.route("/v3.2/<string:locale>/music/artist/<string:mbid>/primaryImage")
|
||||
def get_artist_primary_image(mbid: str, locale: str):
|
||||
try:
|
||||
artist = musicbrainzngs.get_artist_by_id(mbid, ["url-rels"])["artist"]
|
||||
except musicbrainzngs.ResponseError as error:
|
||||
abort(error.cause.code)
|
||||
return
|
||||
|
||||
# Get the Deezer artist ID
|
||||
deezerUrls = [
|
||||
rel["target"]
|
||||
for rel in artist["url-relation-list"]
|
||||
if rel["type"] == "free streaming" and "deezer" in rel["target"]
|
||||
]
|
||||
if len(deezerUrls) == 0:
|
||||
abort(404)
|
||||
deezerUrl: str = deezerUrls[0]
|
||||
|
||||
# Get Deezer's artist info
|
||||
dzResponse = urllib.request.urlopen(deezerUrl.replace("www", "api", 1))
|
||||
raw_data = dzResponse.read()
|
||||
encoding = dzResponse.info().get_content_charset('utf8') # JSON default
|
||||
dzArtist = json.loads(raw_data.decode(encoding))
|
||||
|
||||
# Request the image from the API and forward it to the Zune software
|
||||
image = urllib.request.urlopen(dzArtist["picture_xl"])
|
||||
return Response(image.read(), mimetype="image/jpeg")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(host="127.0.0.1", port=80)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
Flask>=1.0,<=1.1.2
|
||||
musicbrainzngs==0.7.1
|
||||
requests>=2.27.1
|
||||
gunicorn; platform_system == "Linux"
|
||||
|
||||
Reference in New Issue
Block a user