Added artist images

This commit is contained in:
Yoshi Askharoun
2022-02-14 23:49:24 -06:00
parent f56ead1cc2
commit ebf2fcd3af
4 changed files with 88 additions and 37 deletions
+1
View File
@@ -96,3 +96,4 @@ ENV/
# App secrets
*.key
/secrets.py
+52
View File
@@ -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
+34 -37
View File
@@ -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
View File
@@ -1,3 +1,4 @@
Flask>=1.0,<=1.1.2
musicbrainzngs==0.7.1
requests>=2.27.1
gunicorn; platform_system == "Linux"