-
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
113
Kodi/Lenovo/addons/metadata.generic.albums/lib/allmusic.py
Normal file
113
Kodi/Lenovo/addons/metadata.generic.albums/lib/allmusic.py
Normal file
@@ -0,0 +1,113 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import datetime
|
||||
import difflib
|
||||
import time
|
||||
import re
|
||||
|
||||
def allmusic_albumfind(data, artist, album):
|
||||
data = data.decode('utf-8')
|
||||
albums = []
|
||||
albumlist = re.findall('class="album">\s*(.*?)\s*</li', data, re.S)
|
||||
for item in albumlist:
|
||||
albumdata = {}
|
||||
albumartist = re.search('class="artist">.*?>(.*?)</a', item, re.S)
|
||||
if albumartist:
|
||||
albumdata['artist'] = albumartist.group(1)
|
||||
else: # classical album
|
||||
continue
|
||||
albumname = re.search('class="title">.*?>(.*?)</a', item, re.S)
|
||||
if albumname:
|
||||
albumdata['album'] = albumname.group(1)
|
||||
else: # not likely to happen, but just in case
|
||||
continue
|
||||
# filter inaccurate results
|
||||
artistmatch = difflib.SequenceMatcher(None, artist.lower(), albumdata['artist'].lower()).ratio()
|
||||
albummatch = difflib.SequenceMatcher(None, album.lower(), albumdata['album'].lower()).ratio()
|
||||
if artistmatch > 0.90 and albummatch > 0.90:
|
||||
albumurl = re.search('class="title">\s*<a href="(.*?)"', item)
|
||||
if albumurl:
|
||||
albumdata['url'] = albumurl.group(1)
|
||||
else: # not likely to happen, but just in case
|
||||
continue
|
||||
albums.append(albumdata)
|
||||
# we are only interested in the top result
|
||||
break
|
||||
return albums
|
||||
|
||||
def allmusic_albumdetails(data):
|
||||
data = data.decode('utf-8')
|
||||
albumdata = {}
|
||||
releasedata = re.search('class="release-date">.*?<span>(.*?)<', data, re.S)
|
||||
if releasedata:
|
||||
dateformat = releasedata.group(1)
|
||||
if len(dateformat) > 4:
|
||||
try:
|
||||
# month day, year
|
||||
albumdata['releasedate'] = datetime.datetime(*(time.strptime(dateformat, '%B %d, %Y')[0:3])).strftime('%Y-%m-%d')
|
||||
except:
|
||||
# month, year
|
||||
albumdata['releasedate'] = datetime.datetime(*(time.strptime(dateformat, '%B, %Y')[0:3])).strftime('%Y-%m')
|
||||
else:
|
||||
# year
|
||||
albumdata['releasedate'] = dateformat
|
||||
yeardata = re.search('class="year".*?>\s*(.*?)\s*<', data)
|
||||
if yeardata:
|
||||
albumdata['year'] = yeardata.group(1)
|
||||
genredata = re.search('class="genre">.*?">(.*?)<', data, re.S)
|
||||
if genredata:
|
||||
albumdata['genre'] = genredata.group(1)
|
||||
styledata = re.search('class="styles">.*?div>\s*(.*?)\s*</div', data, re.S)
|
||||
if styledata:
|
||||
stylelist = re.findall('">(.*?)<', styledata.group(1))
|
||||
if stylelist:
|
||||
albumdata['styles'] = ' / '.join(stylelist)
|
||||
mooddata = re.search('class="moods">.*?div>\s*(.*?)\s*</div', data, re.S)
|
||||
if mooddata:
|
||||
moodlist = re.findall('">(.*?)<', mooddata.group(1))
|
||||
if moodlist:
|
||||
albumdata['moods'] = ' / '.join(moodlist)
|
||||
themedata = re.search('class="themes">.*?div>\s*(.*?)\s*</div', data, re.S)
|
||||
if themedata:
|
||||
themelist = re.findall('">(.*?)<', themedata.group(1))
|
||||
if themelist:
|
||||
albumdata['themes'] = ' / '.join(themelist)
|
||||
ratingdata = re.search('itemprop="ratingValue">\s*(.*?)\s*</div', data)
|
||||
if ratingdata:
|
||||
albumdata['rating'] = ratingdata.group(1)
|
||||
albumdata['votes'] = ''
|
||||
titledata = re.search('class="album-title".*?>\s*(.*?)\s*<', data, re.S)
|
||||
if titledata:
|
||||
albumdata['album'] = titledata.group(1)
|
||||
labeldata = re.search('class="label-catalog".*?<.*?>(.*?)<', data, re.S)
|
||||
if labeldata:
|
||||
albumdata['label'] = labeldata.group(1)
|
||||
artistdata = re.search('class="album-artist".*?<span.*?>\s*(.*?)\s*</span', data, re.S)
|
||||
if artistdata:
|
||||
artistlist = re.findall('">(.*?)<', artistdata.group(1))
|
||||
artists = []
|
||||
for item in artistlist:
|
||||
artistinfo = {}
|
||||
artistinfo['artist'] = item
|
||||
artists.append(artistinfo)
|
||||
if artists:
|
||||
albumdata['artist'] = artists
|
||||
albumdata['artist_description'] = ' / '.join(artistlist)
|
||||
thumbsdata = re.search('class="album-contain".*?src="(.*?)"', data, re.S)
|
||||
if thumbsdata:
|
||||
thumbs = []
|
||||
thumbdata = {}
|
||||
thumb = thumbsdata.group(1).rstrip('?partner=allrovi.com')
|
||||
# ignore internal blank thumb
|
||||
if thumb.startswith('http'):
|
||||
# 0=largest / 1=75 / 2=150 / 3=250 / 4=400 / 5=500 / 6=1080
|
||||
if thumb.endswith('f=5'):
|
||||
thumbdata['image'] = thumb.replace('f=5', 'f=0')
|
||||
thumbdata['preview'] = thumb.replace('f=5', 'f=2')
|
||||
else:
|
||||
thumbdata['image'] = thumb
|
||||
thumbdata['preview'] = thumb
|
||||
thumbdata['aspect'] = 'thumb'
|
||||
thumbs.append(thumbdata)
|
||||
albumdata['thumb'] = thumbs
|
||||
return albumdata
|
||||
64
Kodi/Lenovo/addons/metadata.generic.albums/lib/discogs.py
Normal file
64
Kodi/Lenovo/addons/metadata.generic.albums/lib/discogs.py
Normal file
@@ -0,0 +1,64 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import difflib
|
||||
|
||||
def discogs_albumfind(data, artist, album):
|
||||
albums = []
|
||||
masters = []
|
||||
# sort results by lowest release id (first version of a release)
|
||||
releases = sorted(data.get('results',[]), key=lambda k: k['id'])
|
||||
for item in releases:
|
||||
masterid = item['master_id']
|
||||
# we are not interested in multiple versions that belong to the same master release
|
||||
if masterid not in masters:
|
||||
masters.append(masterid)
|
||||
albumdata = {}
|
||||
albumdata['artist'] = item['title'].split(' - ',1)[0]
|
||||
albumdata['album'] = item['title'].split(' - ',1)[1]
|
||||
albumdata['artist_description'] = item['title'].split(' - ',1)[0]
|
||||
albumdata['year'] = str(item.get('year', ''))
|
||||
albumdata['label'] = item['label'][0]
|
||||
albumdata['thumb'] = item['thumb']
|
||||
albumdata['dcalbumid'] = item['id']
|
||||
# discogs does not provide relevance, use our own
|
||||
artistmatch = difflib.SequenceMatcher(None, artist.lower(), albumdata['artist'].lower()).ratio()
|
||||
albummatch = difflib.SequenceMatcher(None, album.lower(), albumdata['album'].lower()).ratio()
|
||||
if artistmatch > 0.90 and albummatch > 0.90:
|
||||
score = round(((artistmatch + albummatch) / 2), 2)
|
||||
albumdata['relevance'] = str(score)
|
||||
albums.append(albumdata)
|
||||
return albums
|
||||
|
||||
def discogs_albummain(data):
|
||||
if data:
|
||||
if 'main_release_url' in data:
|
||||
url = data['main_release_url'].rsplit('/', 1)[1]
|
||||
return url
|
||||
|
||||
def discogs_albumdetails(data):
|
||||
albumdata = {}
|
||||
albumdata['album'] = data['title']
|
||||
if 'styles' in data:
|
||||
albumdata['styles'] = ' / '.join(data['styles'])
|
||||
albumdata['genres'] = ' / '.join(data['genres'])
|
||||
albumdata['year'] = str(data['year'])
|
||||
albumdata['label'] = data['labels'][0]['name']
|
||||
artists = []
|
||||
for artist in data['artists']:
|
||||
artistdata = {}
|
||||
artistdata['artist'] = artist['name']
|
||||
artists.append(artistdata)
|
||||
albumdata['artist'] = artists
|
||||
albumdata['artist_description'] = data['artists_sort']
|
||||
albumdata['rating'] = str(int((float(data['community']['rating']['average']) * 2) + 0.5))
|
||||
albumdata['votes'] = str(data['community']['rating']['count'])
|
||||
if 'images' in data:
|
||||
thumbs = []
|
||||
for thumb in data['images']:
|
||||
thumbdata = {}
|
||||
thumbdata['image'] = thumb['uri']
|
||||
thumbdata['preview'] = thumb['uri150']
|
||||
# not accurate: discogs can provide any art type, there is no indication if it is an album front cover (thumb)
|
||||
thumbdata['aspect'] = 'thumb'
|
||||
thumbs.append(thumbdata)
|
||||
albumdata['thumb'] = thumbs
|
||||
return albumdata
|
||||
43
Kodi/Lenovo/addons/metadata.generic.albums/lib/fanarttv.py
Normal file
43
Kodi/Lenovo/addons/metadata.generic.albums/lib/fanarttv.py
Normal file
@@ -0,0 +1,43 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
def fanarttv_albumart(data):
|
||||
if 'albums' in data:
|
||||
albumdata = {}
|
||||
thumbs = []
|
||||
extras = []
|
||||
discs = {}
|
||||
for mbid, art in data['albums'].items():
|
||||
if 'albumcover' in art:
|
||||
for thumb in art['albumcover']:
|
||||
thumbdata = {}
|
||||
thumbdata['image'] = thumb['url']
|
||||
thumbdata['preview'] = thumb['url'].replace('/fanart/', '/preview/')
|
||||
thumbdata['aspect'] = 'thumb'
|
||||
thumbs.append(thumbdata)
|
||||
if 'cdart' in art:
|
||||
for cdart in art['cdart']:
|
||||
extradata = {}
|
||||
extradata['image'] = cdart['url']
|
||||
extradata['preview'] = cdart['url'].replace('/fanart/', '/preview/')
|
||||
extradata['aspect'] = 'discart'
|
||||
extras.append(extradata)
|
||||
# support for multi-disc albums
|
||||
multidata = {}
|
||||
num = cdart['disc']
|
||||
multidata['image'] = cdart['url']
|
||||
multidata['preview'] = cdart['url'].replace('/fanart/', '/preview/')
|
||||
multidata['aspect'] = 'discart%s' % num
|
||||
if not num in discs:
|
||||
discs[num] = [multidata]
|
||||
else:
|
||||
discs[num].append(multidata)
|
||||
if thumbs:
|
||||
albumdata['thumb'] = thumbs
|
||||
# only return for multi-discs, not single discs
|
||||
if len(discs) > 1:
|
||||
for k, v in discs.items():
|
||||
for item in v:
|
||||
extras.append(item)
|
||||
if extras:
|
||||
albumdata['extras'] = extras
|
||||
return albumdata
|
||||
165
Kodi/Lenovo/addons/metadata.generic.albums/lib/musicbrainz.py
Normal file
165
Kodi/Lenovo/addons/metadata.generic.albums/lib/musicbrainz.py
Normal file
@@ -0,0 +1,165 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
def musicbrainz_albumfind(data, artist, album):
|
||||
albums = []
|
||||
# count how often each releasegroup occurs in the release results
|
||||
# keep track of the release with the highest score and earliest releasedate in each releasegroup
|
||||
releasegroups = {}
|
||||
for item in data.get('releases'):
|
||||
mbid = item['id']
|
||||
score = item.get('score', 0)
|
||||
releasegroup = item['release-group']['id']
|
||||
if 'date' in item and item['date']:
|
||||
date = item['date'].replace('-','')
|
||||
if len(date) == 4:
|
||||
date = date + '9999'
|
||||
else:
|
||||
date = '99999999'
|
||||
if releasegroup in releasegroups:
|
||||
count = releasegroups[releasegroup][0] + 1
|
||||
topmbid = releasegroups[releasegroup][1]
|
||||
topdate = releasegroups[releasegroup][2]
|
||||
topscore = releasegroups[releasegroup][3]
|
||||
if date < topdate and score >= topscore:
|
||||
topdate = date
|
||||
topmbid = mbid
|
||||
releasegroups[releasegroup] = [count, topmbid, topdate, topscore]
|
||||
else:
|
||||
releasegroups[releasegroup] = [1, mbid, date, score]
|
||||
if releasegroups:
|
||||
# get the highest releasegroup count
|
||||
maxcount = max(releasegroups.values())[0]
|
||||
# get the releasegroup(s) that match this highest value
|
||||
topgroups = [k for k, v in releasegroups.items() if v[0] == maxcount]
|
||||
for item in data.get('releases'):
|
||||
# only use the 'top' release from each releasegroup
|
||||
if item['id'] != releasegroups[item['release-group']['id']][1]:
|
||||
continue
|
||||
albumdata = {}
|
||||
if item.get('artist-credit'):
|
||||
artists = []
|
||||
artistdisp = ""
|
||||
for artist in item['artist-credit']:
|
||||
artistdata = {}
|
||||
artistdata['artist'] = artist['artist']['name']
|
||||
artistdata['mbartistid'] = artist['artist']['id']
|
||||
artistdata['artistsort'] = artist['artist']['sort-name']
|
||||
artistdisp = artistdisp + artist['artist']['name']
|
||||
artistdisp = artistdisp + artist.get('joinphrase', '')
|
||||
artists.append(artistdata)
|
||||
albumdata['artist'] = artists
|
||||
albumdata['artist_description'] = artistdisp
|
||||
if item.get('label-info','') and item['label-info'][0].get('label','') and item['label-info'][0]['label'].get('name',''):
|
||||
albumdata['label'] = item['label-info'][0]['label']['name']
|
||||
albumdata['album'] = item['title']
|
||||
if item.get('date',''):
|
||||
albumdata['year'] = item['date'][:4]
|
||||
albumdata['thumb'] = 'https://coverartarchive.org/release-group/%s/front-250' % item['release-group']['id']
|
||||
if item.get('label-info','') and item['label-info'][0].get('label','') and item['label-info'][0]['label'].get('name',''):
|
||||
albumdata['label'] = item['label-info'][0]['label']['name']
|
||||
if item.get('status',''):
|
||||
albumdata['releasestatus'] = item['status']
|
||||
albumdata['type'] = item['release-group'].get('primary-type')
|
||||
albumdata['mbalbumid'] = item['id']
|
||||
albumdata['mbreleasegroupid'] = item['release-group']['id']
|
||||
if item.get('score'):
|
||||
releasescore = item['score'] / 100.0
|
||||
# if the release is in the releasegroup with most releases, it is considered the most accurate one
|
||||
# (this also helps with preferring official releases over bootlegs, assuming there are more variations of an official release than of a bootleg)
|
||||
if item['release-group']['id'] not in topgroups:
|
||||
releasescore -= 0.001
|
||||
# if the release is an album, prefer it over singles/ep's
|
||||
# (this needs to be the double of the above, as me might have just given the album a lesser score if the single happened to be in the topgroup)
|
||||
if item['release-group'].get('primary-type') != 'Album':
|
||||
releasescore -= 0.002
|
||||
albumdata['relevance'] = str(releasescore)
|
||||
albums.append(albumdata)
|
||||
return albums
|
||||
|
||||
def musicbrainz_albumlinks(data):
|
||||
albumlinks = {}
|
||||
if 'relations' in data and data['relations']:
|
||||
for item in data['relations']:
|
||||
if item['type'] == 'allmusic':
|
||||
albumlinks['allmusic'] = item['url']['resource']
|
||||
elif item['type'] == 'discogs':
|
||||
albumlinks['discogs'] = item['url']['resource'].rsplit('/', 1)[1]
|
||||
elif item['type'] == 'wikipedia':
|
||||
albumlinks['wikipedia'] = item['url']['resource'].rsplit('/', 1)[1]
|
||||
elif item['type'] == 'wikidata':
|
||||
albumlinks['wikidata'] = item['url']['resource'].rsplit('/', 1)[1]
|
||||
return albumlinks
|
||||
|
||||
def musicbrainz_albumdetails(data):
|
||||
albumdata = {}
|
||||
albumdata['album'] = data['title']
|
||||
albumdata['mbalbumid'] = data['id']
|
||||
if data.get('release-group',''):
|
||||
albumdata['mbreleasegroupid'] = data['release-group']['id']
|
||||
if data['release-group']['rating'] and data['release-group']['rating']['value']:
|
||||
albumdata['rating'] = str(int((float(data['release-group']['rating']['value']) * 2) + 0.5))
|
||||
albumdata['votes'] = str(data['release-group']['rating']['votes-count'])
|
||||
if data['release-group'].get('primary-type'):
|
||||
albumtypes = [data['release-group']['primary-type']] + data['release-group']['secondary-types']
|
||||
albumdata['type'] = ' / '.join(albumtypes)
|
||||
if 'Compilation' in albumtypes:
|
||||
albumdata['compilation'] = 'true'
|
||||
if data['release-group'].get('first-release-date',''):
|
||||
albumdata['originaldate'] = data['release-group']['first-release-date']
|
||||
if data.get('release-events',''):
|
||||
albumdata['year'] = data['release-events'][0]['date'][:4]
|
||||
albumdata['releasedate'] = data['release-events'][0]['date']
|
||||
if data.get('label-info','') and data['label-info'][0].get('label','') and data['label-info'][0]['label'].get('name',''):
|
||||
albumdata['label'] = data['label-info'][0]['label']['name']
|
||||
if data.get('status',''):
|
||||
albumdata['releasestatus'] = data['status']
|
||||
if data.get('artist-credit'):
|
||||
artists = []
|
||||
artistdisp = ''
|
||||
for artist in data['artist-credit']:
|
||||
artistdata = {}
|
||||
artistdata['artist'] = artist['name']
|
||||
artistdata['mbartistid'] = artist['artist']['id']
|
||||
artistdata['artistsort'] = artist['artist']['sort-name']
|
||||
artistdisp = artistdisp + artist['name']
|
||||
artistdisp = artistdisp + artist.get('joinphrase', '')
|
||||
artists.append(artistdata)
|
||||
albumdata['artist'] = artists
|
||||
albumdata['artist_description'] = artistdisp
|
||||
return albumdata
|
||||
|
||||
def musicbrainz_albumart(data):
|
||||
albumdata = {}
|
||||
thumbs = []
|
||||
extras = []
|
||||
for item in data['images']:
|
||||
if 'Front' in item['types']:
|
||||
thumbdata = {}
|
||||
thumbdata['image'] = item['image']
|
||||
thumbdata['preview'] = item['thumbnails']['small']
|
||||
thumbdata['aspect'] = 'thumb'
|
||||
thumbs.append(thumbdata)
|
||||
if 'Back' in item['types']:
|
||||
backdata = {}
|
||||
backdata['image'] = item['image']
|
||||
backdata['preview'] = item['thumbnails']['small']
|
||||
backdata['aspect'] = 'back'
|
||||
extras.append(backdata)
|
||||
if 'Medium' in item['types']:
|
||||
discartdata = {}
|
||||
discartdata['image'] = item['image']
|
||||
discartdata['preview'] = item['thumbnails']['small']
|
||||
discartdata['aspect'] = 'discart'
|
||||
extras.append(discartdata)
|
||||
# exclude spine+back images
|
||||
if 'Spine' in item['types'] and len(item['types']) == 1:
|
||||
spinedata = {}
|
||||
spinedata['image'] = item['image']
|
||||
spinedata['preview'] = item['thumbnails']['small']
|
||||
spinedata['aspect'] = 'spine'
|
||||
extras.append(spinedata)
|
||||
if thumbs:
|
||||
albumdata['thumb'] = thumbs
|
||||
if extras:
|
||||
albumdata['extras'] = extras
|
||||
return albumdata
|
||||
8
Kodi/Lenovo/addons/metadata.generic.albums/lib/nfo.py
Normal file
8
Kodi/Lenovo/addons/metadata.generic.albums/lib/nfo.py
Normal file
@@ -0,0 +1,8 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import re
|
||||
|
||||
def nfo_geturl(data):
|
||||
result = re.search('https://musicbrainz.org/(ws/2/)?release/([0-9a-z\-]*)', data)
|
||||
if result:
|
||||
return result.group(2)
|
||||
497
Kodi/Lenovo/addons/metadata.generic.albums/lib/scraper.py
Normal file
497
Kodi/Lenovo/addons/metadata.generic.albums/lib/scraper.py
Normal file
@@ -0,0 +1,497 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import json
|
||||
import socket
|
||||
import sys
|
||||
import time
|
||||
import urllib.parse
|
||||
import urllib.request
|
||||
import _strptime # https://bugs.python.org/issue7980
|
||||
from socket import timeout
|
||||
from threading import Thread
|
||||
from urllib.error import HTTPError, URLError
|
||||
import xbmc
|
||||
import xbmcaddon
|
||||
import xbmcgui
|
||||
import xbmcplugin
|
||||
from .allmusic import allmusic_albumfind
|
||||
from .allmusic import allmusic_albumdetails
|
||||
from .discogs import discogs_albumfind
|
||||
from .discogs import discogs_albummain
|
||||
from .discogs import discogs_albumdetails
|
||||
from .fanarttv import fanarttv_albumart
|
||||
from .musicbrainz import musicbrainz_albumfind
|
||||
from .musicbrainz import musicbrainz_albumdetails
|
||||
from .musicbrainz import musicbrainz_albumlinks
|
||||
from .musicbrainz import musicbrainz_albumart
|
||||
from .nfo import nfo_geturl
|
||||
from .theaudiodb import theaudiodb_albumdetails
|
||||
from .wikipedia import wikipedia_albumdetails
|
||||
from .utils import *
|
||||
|
||||
ADDONID = xbmcaddon.Addon().getAddonInfo('id')
|
||||
ADDONNAME = xbmcaddon.Addon().getAddonInfo('name')
|
||||
ADDONVERSION = xbmcaddon.Addon().getAddonInfo('version')
|
||||
|
||||
|
||||
def log(txt):
|
||||
message = '%s: %s' % (ADDONID, txt)
|
||||
xbmc.log(msg=message, level=xbmc.LOGDEBUG)
|
||||
|
||||
def get_data(url, jsonformat, retry=True):
|
||||
try:
|
||||
if url.startswith('https://musicbrainz.org/'):
|
||||
api_timeout('musicbrainztime')
|
||||
elif url.startswith('https://api.discogs.com/'):
|
||||
api_timeout('discogstime')
|
||||
headers = {}
|
||||
headers['User-Agent'] = '%s/%s ( http://kodi.tv )' % (ADDONNAME, ADDONVERSION)
|
||||
req = urllib.request.Request(url, headers=headers)
|
||||
resp = urllib.request.urlopen(req, timeout=5)
|
||||
respdata = resp.read()
|
||||
except URLError as e:
|
||||
log('URLError: %s - %s' % (e.reason, url))
|
||||
return
|
||||
except HTTPError as e:
|
||||
log('HTTPError: %s - %s' % (e.reason, url))
|
||||
return
|
||||
except socket.timeout as e:
|
||||
log('socket: %s - %s' % (e, url))
|
||||
return
|
||||
if resp.getcode() == 503:
|
||||
log('exceeding musicbrainz api limit')
|
||||
if retry:
|
||||
xbmc.sleep(1000)
|
||||
get_data(url, jsonformat, retry=False)
|
||||
else:
|
||||
return
|
||||
elif resp.getcode() == 429:
|
||||
log('exceeding discogs api limit')
|
||||
if retry:
|
||||
xbmc.sleep(1000)
|
||||
get_data(url, jsonformat, retry=False)
|
||||
else:
|
||||
return
|
||||
if jsonformat:
|
||||
respdata = json.loads(respdata)
|
||||
return respdata
|
||||
|
||||
def api_timeout(scraper):
|
||||
currenttime = round(time.time() * 1000)
|
||||
previoustime = xbmcgui.Window(10000).getProperty(scraper)
|
||||
if previoustime:
|
||||
timeout = currenttime - int(previoustime)
|
||||
if timeout < 1000:
|
||||
xbmc.sleep(1000 - timeout)
|
||||
xbmcgui.Window(10000).setProperty(scraper, str(round(time.time() * 1000)))
|
||||
|
||||
|
||||
class Scraper():
|
||||
def __init__(self, action, key, artist, album, url, nfo, settings):
|
||||
# parse path settings
|
||||
self.parse_settings(settings)
|
||||
# this is just for backward compatibility with xml based scrapers https://github.com/xbmc/xbmc/pull/11632
|
||||
if action == 'resolveid':
|
||||
# return the result
|
||||
result = self.resolve_mbid(key)
|
||||
self.return_resolved(result)
|
||||
# search for artist name / album title matches
|
||||
elif action == 'find':
|
||||
# try musicbrainz first
|
||||
result = self.find_album(artist, album, 'musicbrainz')
|
||||
if result:
|
||||
self.return_search(result)
|
||||
# fallback to discogs
|
||||
else:
|
||||
result = self.find_album(artist, album, 'discogs')
|
||||
if result:
|
||||
self.return_search(result)
|
||||
# return info id's
|
||||
elif action == 'getdetails':
|
||||
details = {}
|
||||
links = {}
|
||||
url = json.loads(url)
|
||||
artist = url.get('artist')
|
||||
album = url.get('album')
|
||||
mbalbumid = url.get('mbalbumid')
|
||||
mbreleasegroupid = url.get('mbreleasegroupid')
|
||||
dcid = url.get('dcalbumid')
|
||||
threads = []
|
||||
extrascrapers = []
|
||||
# we have musicbrainz album id
|
||||
if mbalbumid:
|
||||
# get the mbreleasegroupid, artist and album if we don't have them
|
||||
if not mbreleasegroupid:
|
||||
result = self.get_details(mbalbumid, 'musicbrainz', details)
|
||||
if not result:
|
||||
scrapers = [[mbalbumid, 'musicbrainz']]
|
||||
else:
|
||||
mbreleasegroupid = details['musicbrainz']['mbreleasegroupid']
|
||||
artist = details['musicbrainz']['artist_description']
|
||||
album = details['musicbrainz']['album']
|
||||
scrapers = [[mbreleasegroupid, 'theaudiodb'], [mbreleasegroupid, 'fanarttv'], [mbreleasegroupid, 'coverarchive']]
|
||||
else:
|
||||
scrapers = [[mbalbumid, 'musicbrainz'], [mbreleasegroupid, 'theaudiodb'], [mbreleasegroupid, 'fanarttv'], [mbreleasegroupid, 'coverarchive']]
|
||||
# get musicbrainz links to other metadata sites
|
||||
lthread = Thread(target = self.get_links, args = (mbreleasegroupid, links))
|
||||
lthread.start()
|
||||
for item in scrapers:
|
||||
thread = Thread(target = self.get_details, args = (item[0], item[1], details))
|
||||
threads.append(thread)
|
||||
thread.start()
|
||||
# wait for the musicbrainz links to return
|
||||
lthread.join()
|
||||
if 'musicbrainz' in links:
|
||||
# scrape allmusic if we have an url provided by musicbrainz
|
||||
if 'allmusic' in links['musicbrainz']:
|
||||
extrascrapers.append([{'url': links['musicbrainz']['allmusic']}, 'allmusic'])
|
||||
# only scrape allmusic by artistname and albumtitle if explicitly enabled
|
||||
elif self.inaccurate and artist and album:
|
||||
extrascrapers.append([{'artist': artist, 'album': album}, 'allmusic'])
|
||||
# scrape discogs if we have an url provided by musicbrainz
|
||||
if 'discogs' in links['musicbrainz']:
|
||||
extrascrapers.append([{'masterurl': links['musicbrainz']['discogs']}, 'discogs'])
|
||||
# only scrape discogs by artistname and albumtitle if explicitly enabled
|
||||
elif self.inaccurate and artist and album:
|
||||
extrascrapers.append([{'artist': artist, 'album': album}, 'discogs'])
|
||||
# scrape wikipedia if we have an url provided by musicbrainz
|
||||
if 'wikipedia' in links['musicbrainz']:
|
||||
extrascrapers.append([links['musicbrainz']['wikipedia'], 'wikipedia'])
|
||||
elif 'wikidata' in links['musicbrainz']:
|
||||
extrascrapers.append([links['musicbrainz']['wikidata'], 'wikidata'])
|
||||
for item in extrascrapers:
|
||||
thread = Thread(target = self.get_details, args = (item[0], item[1], details))
|
||||
threads.append(thread)
|
||||
thread.start()
|
||||
# we have a discogs id
|
||||
else:
|
||||
thread = Thread(target = self.get_details, args = ({'url': dcid}, 'discogs', details))
|
||||
threads.append(thread)
|
||||
thread.start()
|
||||
for thread in threads:
|
||||
thread.join()
|
||||
result = self.compile_results(details)
|
||||
if result:
|
||||
self.return_details(result)
|
||||
# extract the mbalbumid from the provided musicbrainz url
|
||||
elif action == 'NfoUrl':
|
||||
# check if there is a musicbrainz url in the nfo file
|
||||
mbalbumid = nfo_geturl(nfo)
|
||||
if mbalbumid:
|
||||
# return the result
|
||||
result = self.resolve_mbid(mbalbumid)
|
||||
self.return_nfourl(result)
|
||||
xbmcplugin.endOfDirectory(int(sys.argv[1]))
|
||||
|
||||
def parse_settings(self, data):
|
||||
settings = json.loads(data)
|
||||
# note: path settings are taken from the db, they may not reflect the current settings.xml file
|
||||
self.review = settings['review']
|
||||
self.genre = settings['genre']
|
||||
self.lang = settings['lang']
|
||||
self.mood = settings['mood']
|
||||
self.rating = settings['rating']
|
||||
self.style = settings['style']
|
||||
self.theme = settings['theme']
|
||||
self.inaccurate = settings['inaccurate']
|
||||
|
||||
def resolve_mbid(self, mbalbumid):
|
||||
item = {}
|
||||
item['artist_description'] = ''
|
||||
item['album'] = ''
|
||||
item['mbalbumid'] = mbalbumid
|
||||
item['mbreleasegroupid'] = ''
|
||||
return item
|
||||
|
||||
def find_album(self, artist, album, site):
|
||||
json = True
|
||||
# musicbrainz
|
||||
if site == 'musicbrainz':
|
||||
url = MUSICBRAINZURL % (MUSICBRAINZSEARCH % (urllib.parse.quote_plus(album), urllib.parse.quote_plus(artist), urllib.parse.quote_plus(artist)))
|
||||
scraper = musicbrainz_albumfind
|
||||
# discogs
|
||||
elif site == 'discogs':
|
||||
url = DISCOGSURL % (DISCOGSSEARCH % (urllib.parse.quote_plus(album), urllib.parse.quote_plus(artist), DISCOGSKEY , DISCOGSSECRET))
|
||||
scraper = discogs_albumfind
|
||||
result = get_data(url, json)
|
||||
if not result:
|
||||
return
|
||||
albumresults = scraper(result, artist, album)
|
||||
return albumresults
|
||||
|
||||
def get_links(self, param, links):
|
||||
json = True
|
||||
url = MUSICBRAINZURL % (MUSICBRAINZLINKS % param)
|
||||
result = get_data(url, json)
|
||||
if result:
|
||||
linkresults = musicbrainz_albumlinks(result)
|
||||
links['musicbrainz'] = linkresults
|
||||
return links
|
||||
|
||||
def get_details(self, param, site, details):
|
||||
json = True
|
||||
# theaudiodb
|
||||
if site == 'theaudiodb':
|
||||
url = AUDIODBURL % (AUDIODBKEY, AUDIODBDETAILS % param)
|
||||
albumscraper = theaudiodb_albumdetails
|
||||
# musicbrainz
|
||||
elif site == 'musicbrainz':
|
||||
url = MUSICBRAINZURL % (MUSICBRAINZDETAILS % param)
|
||||
albumscraper = musicbrainz_albumdetails
|
||||
# fanarttv
|
||||
elif site == 'fanarttv':
|
||||
url = FANARTVURL % (param, FANARTVKEY)
|
||||
albumscraper = fanarttv_albumart
|
||||
# coverarchive
|
||||
elif site == 'coverarchive':
|
||||
url = MUSICBRAINZART % (param)
|
||||
albumscraper = musicbrainz_albumart
|
||||
# discogs
|
||||
elif site == 'discogs':
|
||||
# musicbrainz provides a link to the master release, but we need the main release
|
||||
if 'masterurl' in param:
|
||||
masterdata = get_data(DISCOGSURL % (DISCOGSMASTER % (param['masterurl'], DISCOGSKEY , DISCOGSSECRET)), True)
|
||||
if masterdata:
|
||||
url = discogs_albummain(masterdata)
|
||||
if url:
|
||||
param['url'] = url
|
||||
else:
|
||||
return
|
||||
else:
|
||||
return
|
||||
# search by artistname and albumtitle if we do not have an url
|
||||
if not 'url' in param:
|
||||
url = DISCOGSURL % (DISCOGSSEARCH % (urllib.parse.quote_plus(param['album']), urllib.parse.quote_plus(param['artist']), DISCOGSKEY , DISCOGSSECRET))
|
||||
albumresult = get_data(url, json)
|
||||
if albumresult:
|
||||
albums = discogs_albumfind(albumresult, param['artist'], param['album'])
|
||||
if albums:
|
||||
albumresult = sorted(albums, key=lambda k: k['relevance'], reverse=True)
|
||||
param['url'] = albumresult[0]['dcalbumid']
|
||||
else:
|
||||
return
|
||||
else:
|
||||
return
|
||||
url = DISCOGSURL % (DISCOGSDETAILS % (param['url'], DISCOGSKEY, DISCOGSSECRET))
|
||||
albumscraper = discogs_albumdetails
|
||||
# wikipedia
|
||||
elif site == 'wikipedia':
|
||||
url = WIKIPEDIAURL % param
|
||||
albumscraper = wikipedia_albumdetails
|
||||
elif site == 'wikidata':
|
||||
# resolve wikidata to wikipedia url
|
||||
result = get_data(WIKIDATAURL % param, json)
|
||||
try:
|
||||
album = result['entities'][param]['sitelinks']['enwiki']['url'].rsplit('/', 1)[1]
|
||||
except:
|
||||
return
|
||||
site = 'wikipedia'
|
||||
url = WIKIPEDIAURL % album
|
||||
albumscraper = wikipedia_albumdetails
|
||||
# allmusic
|
||||
elif site == 'allmusic':
|
||||
json = False
|
||||
# search by artistname and albumtitle if we do not have an url
|
||||
if not 'url' in param:
|
||||
url = ALLMUSICURL % (ALLMUSICSEARCH % (urllib.parse.quote_plus(param['artist']), urllib.parse.quote_plus(param['album'])))
|
||||
albumresult = get_data(url, json)
|
||||
if albumresult:
|
||||
albums = allmusic_albumfind(albumresult, param['artist'], param['album'])
|
||||
if albums:
|
||||
param['url'] = albums[0]['url']
|
||||
else:
|
||||
return
|
||||
else:
|
||||
return
|
||||
url = ALLMUSICDETAILS % param['url']
|
||||
albumscraper = allmusic_albumdetails
|
||||
result = get_data(url, json)
|
||||
if not result:
|
||||
return
|
||||
albumresults = albumscraper(result)
|
||||
if not albumresults:
|
||||
return
|
||||
details[site] = albumresults
|
||||
return details
|
||||
|
||||
def compile_results(self, details):
|
||||
result = {}
|
||||
thumbs = []
|
||||
extras = []
|
||||
# merge metadata results, start with the least accurate sources
|
||||
if 'discogs' in details:
|
||||
for k, v in details['discogs'].items():
|
||||
if v:
|
||||
result[k] = v
|
||||
if k == 'thumb' and v:
|
||||
thumbs.append(v)
|
||||
if 'wikipedia' in details:
|
||||
for k, v in details['wikipedia'].items():
|
||||
if v:
|
||||
result[k] = v
|
||||
if 'allmusic' in details:
|
||||
for k, v in details['allmusic'].items():
|
||||
if v:
|
||||
result[k] = v
|
||||
if k == 'thumb' and v:
|
||||
thumbs.append(v)
|
||||
if 'theaudiodb' in details:
|
||||
for k, v in details['theaudiodb'].items():
|
||||
if v:
|
||||
result[k] = v
|
||||
if k == 'thumb' and v:
|
||||
thumbs.append(v)
|
||||
if k == 'extras' and v:
|
||||
extras.append(v)
|
||||
if 'musicbrainz' in details:
|
||||
for k, v in details['musicbrainz'].items():
|
||||
if v:
|
||||
result[k] = v
|
||||
if 'coverarchive' in details:
|
||||
for k, v in details['coverarchive'].items():
|
||||
if v:
|
||||
result[k] = v
|
||||
if k == 'thumb' and v:
|
||||
thumbs.append(v)
|
||||
if k == 'extras' and v:
|
||||
extras.append(v)
|
||||
# prefer artwork from fanarttv
|
||||
if 'fanarttv' in details:
|
||||
for k, v in details['fanarttv'].items():
|
||||
if v:
|
||||
result[k] = v
|
||||
if k == 'thumb' and v:
|
||||
thumbs.append(v)
|
||||
if k == 'extras' and v:
|
||||
extras.append(v)
|
||||
# use musicbrainz artist as it provides the mbartistid (used for resolveid in the artist scraper)
|
||||
if 'musicbrainz' in details:
|
||||
result['artist'] = details['musicbrainz']['artist']
|
||||
# provide artwork from all scrapers for getthumb option
|
||||
if result:
|
||||
# thumb list from most accurate sources first
|
||||
thumbs.reverse()
|
||||
thumbnails = []
|
||||
for thumblist in thumbs:
|
||||
for item in thumblist:
|
||||
thumbnails.append(item)
|
||||
# extra art from most accurate sources first
|
||||
extras.reverse()
|
||||
extraart = []
|
||||
for extralist in extras:
|
||||
for item in extralist:
|
||||
extraart.append(item)
|
||||
# add the extra art to the end of the thumb list
|
||||
if extraart:
|
||||
thumbnails.extend(extraart)
|
||||
if thumbnails:
|
||||
result['thumb'] = thumbnails
|
||||
data = self.user_prefs(details, result)
|
||||
return data
|
||||
|
||||
def user_prefs(self, details, result):
|
||||
# user preferences
|
||||
lang = 'description' + self.lang
|
||||
if self.review == 'theaudiodb' and 'theaudiodb' in details:
|
||||
if lang in details['theaudiodb']:
|
||||
result['description'] = details['theaudiodb'][lang]
|
||||
elif 'descriptionEN' in details['theaudiodb']:
|
||||
result['description'] = details['theaudiodb']['descriptionEN']
|
||||
elif (self.review in details) and ('description' in details[self.review]):
|
||||
result['description'] = details[self.review]['description']
|
||||
if (self.genre in details) and ('genre' in details[self.genre]):
|
||||
result['genre'] = details[self.genre]['genre']
|
||||
if (self.style in details) and ('styles' in details[self.style]):
|
||||
result['styles'] = details[self.style]['styles']
|
||||
if (self.mood in details) and ('moods' in details[self.mood]):
|
||||
result['moods'] = details[self.mood]['moods']
|
||||
if (self.theme in details) and ('themes' in details[self.theme]):
|
||||
result['themes'] = details[self.theme]['themes']
|
||||
if (self.rating in details) and ('rating' in details[self.rating]):
|
||||
result['rating'] = details[self.rating]['rating']
|
||||
result['votes'] = details[self.rating]['votes']
|
||||
return result
|
||||
|
||||
def return_search(self, data):
|
||||
items = []
|
||||
for item in data:
|
||||
listitem = xbmcgui.ListItem(item['album'], offscreen=True)
|
||||
listitem.setArt({'thumb': item['thumb']})
|
||||
listitem.setProperty('album.artist', item['artist_description'])
|
||||
listitem.setProperty('album.year', item.get('year',''))
|
||||
listitem.setProperty('album.type', item.get('type',''))
|
||||
listitem.setProperty('album.releasestatus', item.get('releasestatus',''))
|
||||
listitem.setProperty('album.label', item.get('label',''))
|
||||
listitem.setProperty('relevance', item['relevance'])
|
||||
url = {'artist':item['artist_description'], 'album':item['album']}
|
||||
if 'mbalbumid' in item:
|
||||
url['mbalbumid'] = item['mbalbumid']
|
||||
url['mbreleasegroupid'] = item['mbreleasegroupid']
|
||||
if 'dcalbumid' in item:
|
||||
url['dcalbumid'] = item['dcalbumid']
|
||||
items.append((json.dumps(url), listitem, True))
|
||||
if items:
|
||||
xbmcplugin.addDirectoryItems(handle=int(sys.argv[1]), items=items)
|
||||
|
||||
def return_nfourl(self, item):
|
||||
listitem = xbmcgui.ListItem(offscreen=True)
|
||||
xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]), url=json.dumps(item), listitem=listitem, isFolder=True)
|
||||
|
||||
def return_resolved(self, item):
|
||||
listitem = xbmcgui.ListItem(path=json.dumps(item), offscreen=True)
|
||||
xbmcplugin.setResolvedUrl(handle=int(sys.argv[1]), succeeded=True, listitem=listitem)
|
||||
|
||||
def return_details(self, item):
|
||||
if not 'album' in item:
|
||||
return
|
||||
listitem = xbmcgui.ListItem(item['album'], offscreen=True)
|
||||
if 'mbalbumid' in item:
|
||||
listitem.setProperty('album.musicbrainzid', item['mbalbumid'])
|
||||
listitem.setProperty('album.releaseid', item['mbalbumid'])
|
||||
if 'mbreleasegroupid' in item:
|
||||
listitem.setProperty('album.releasegroupid', item['mbreleasegroupid'])
|
||||
if 'scrapedmbid' in item:
|
||||
listitem.setProperty('album.scrapedmbid', item['scrapedmbid'])
|
||||
if 'artist' in item:
|
||||
listitem.setProperty('album.artists', str(len(item['artist'])))
|
||||
for count, artist in enumerate(item['artist']):
|
||||
listitem.setProperty('album.artist%i.name' % (count + 1), artist['artist'])
|
||||
listitem.setProperty('album.artist%i.musicbrainzid' % (count + 1), artist.get('mbartistid', ''))
|
||||
listitem.setProperty('album.artist%i.sortname' % (count + 1), artist.get('artistsort', ''))
|
||||
if 'genre' in item:
|
||||
listitem.setProperty('album.genre', item['genre'])
|
||||
if 'styles' in item:
|
||||
listitem.setProperty('album.styles', item['styles'])
|
||||
if 'moods' in item:
|
||||
listitem.setProperty('album.moods', item['moods'])
|
||||
if 'themes' in item:
|
||||
listitem.setProperty('album.themes', item['themes'])
|
||||
if 'description' in item:
|
||||
listitem.setProperty('album.review', item['description'])
|
||||
if 'releasedate' in item:
|
||||
listitem.setProperty('album.releasedate', item['releasedate'])
|
||||
if 'originaldate' in item:
|
||||
listitem.setProperty('album.originaldate', item['originaldate'])
|
||||
if 'releasestatus' in item:
|
||||
listitem.setProperty('album.releasestatus', item['releasestatus'])
|
||||
if 'artist_description' in item:
|
||||
listitem.setProperty('album.artist_description', item['artist_description'])
|
||||
if 'label' in item:
|
||||
listitem.setProperty('album.label', item['label'])
|
||||
if 'type' in item:
|
||||
listitem.setProperty('album.type', item['type'])
|
||||
if 'compilation' in item:
|
||||
listitem.setProperty('album.compilation', item['compilation'])
|
||||
if 'year' in item:
|
||||
listitem.setProperty('album.year', item['year'])
|
||||
if 'rating' in item:
|
||||
listitem.setProperty('album.rating', item['rating'])
|
||||
if 'votes' in item:
|
||||
listitem.setProperty('album.votes', item['votes'])
|
||||
if 'thumb' in item:
|
||||
listitem.setProperty('album.thumbs', str(len(item['thumb'])))
|
||||
for count, thumb in enumerate(item['thumb']):
|
||||
listitem.setProperty('album.thumb%i.url' % (count + 1), thumb['image'])
|
||||
listitem.setProperty('album.thumb%i.aspect' % (count + 1), thumb['aspect'])
|
||||
listitem.setProperty('album.thumb%i.preview' % (count + 1), thumb['preview'])
|
||||
xbmcplugin.setResolvedUrl(handle=int(sys.argv[1]), succeeded=True, listitem=listitem)
|
||||
124
Kodi/Lenovo/addons/metadata.generic.albums/lib/theaudiodb.py
Normal file
124
Kodi/Lenovo/addons/metadata.generic.albums/lib/theaudiodb.py
Normal file
@@ -0,0 +1,124 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
def theaudiodb_albumdetails(data):
|
||||
if data.get('album'):
|
||||
item = data['album'][0]
|
||||
albumdata = {}
|
||||
albumdata['album'] = item['strAlbum']
|
||||
if item.get('intYearReleased',''):
|
||||
albumdata['year'] = item['intYearReleased']
|
||||
if item.get('strStyle',''):
|
||||
albumdata['styles'] = item['strStyle']
|
||||
if item.get('strGenre',''):
|
||||
albumdata['genre'] = item['strGenre']
|
||||
if item.get('strLabel',''):
|
||||
albumdata['label'] = item['strLabel']
|
||||
if item.get('strReleaseFormat',''):
|
||||
albumdata['type'] = item['strReleaseFormat']
|
||||
if item.get('intScore',''):
|
||||
albumdata['rating'] = str(int(float(item['intScore']) + 0.5))
|
||||
if item.get('intScoreVotes',''):
|
||||
albumdata['votes'] = item['intScoreVotes']
|
||||
if item.get('strMood',''):
|
||||
albumdata['moods'] = item['strMood']
|
||||
if item.get('strTheme',''):
|
||||
albumdata['themes'] = item['strTheme']
|
||||
if item.get('strMusicBrainzID',''):
|
||||
albumdata['mbreleasegroupid'] = item['strMusicBrainzID']
|
||||
# api inconsistent
|
||||
if item.get('strDescription',''):
|
||||
albumdata['descriptionEN'] = item['strDescription']
|
||||
elif item.get('strDescriptionEN',''):
|
||||
albumdata['descriptionEN'] = item['strDescriptionEN']
|
||||
if item.get('strDescriptionDE',''):
|
||||
albumdata['descriptionDE'] = item['strDescriptionDE']
|
||||
if item.get('strDescriptionFR',''):
|
||||
albumdata['descriptionFR'] = item['strDescriptionFR']
|
||||
if item.get('strDescriptionCN',''):
|
||||
albumdata['descriptionCN'] = item['strDescriptionCN']
|
||||
if item.get('strDescriptionIT',''):
|
||||
albumdata['descriptionIT'] = item['strDescriptionIT']
|
||||
if item.get('strDescriptionJP',''):
|
||||
albumdata['descriptionJP'] = item['strDescriptionJP']
|
||||
if item.get('strDescriptionRU',''):
|
||||
albumdata['descriptionRU'] = item['strDescriptionRU']
|
||||
if item.get('strDescriptionES',''):
|
||||
albumdata['descriptionES'] = item['strDescriptionES']
|
||||
if item.get('strDescriptionPT',''):
|
||||
albumdata['descriptionPT'] = item['strDescriptionPT']
|
||||
if item.get('strDescriptionSE',''):
|
||||
albumdata['descriptionSE'] = item['strDescriptionSE']
|
||||
if item.get('strDescriptionNL',''):
|
||||
albumdata['descriptionNL'] = item['strDescriptionNL']
|
||||
if item.get('strDescriptionHU',''):
|
||||
albumdata['descriptionHU'] = item['strDescriptionHU']
|
||||
if item.get('strDescriptionNO',''):
|
||||
albumdata['descriptionNO'] = item['strDescriptionNO']
|
||||
if item.get('strDescriptionIL',''):
|
||||
albumdata['descriptionIL'] = item['strDescriptionIL']
|
||||
if item.get('strDescriptionPL',''):
|
||||
albumdata['descriptionPL'] = item['strDescriptionPL']
|
||||
if item.get('strArtist',''):
|
||||
albumdata['artist_description'] = item['strArtist']
|
||||
artists = []
|
||||
artistdata = {}
|
||||
artistdata['artist'] = item['strArtist']
|
||||
if item.get('strMusicBrainzArtistID',''):
|
||||
artistdata['mbartistid'] = item['strMusicBrainzArtistID']
|
||||
artists.append(artistdata)
|
||||
albumdata['artist'] = artists
|
||||
thumbs = []
|
||||
extras = []
|
||||
if item.get('strAlbumThumb',''):
|
||||
thumbdata = {}
|
||||
thumbdata['image'] = item['strAlbumThumb']
|
||||
thumbdata['preview'] = item['strAlbumThumb'] + '/preview'
|
||||
thumbdata['aspect'] = 'thumb'
|
||||
thumbs.append(thumbdata)
|
||||
if item.get('strAlbumThumbBack',''):
|
||||
extradata = {}
|
||||
extradata['image'] = item['strAlbumThumbBack']
|
||||
extradata['preview'] = item['strAlbumThumbBack'] + '/preview'
|
||||
extradata['aspect'] = 'back'
|
||||
extras.append(extradata)
|
||||
if item.get('strAlbumSpine',''):
|
||||
extradata = {}
|
||||
extradata['image'] = item['strAlbumSpine']
|
||||
extradata['preview'] = item['strAlbumSpine'] + '/preview'
|
||||
extradata['aspect'] = 'spine'
|
||||
extras.append(extradata)
|
||||
if item.get('strAlbumCDart',''):
|
||||
extradata = {}
|
||||
extradata['image'] = item['strAlbumCDart']
|
||||
extradata['preview'] = item['strAlbumCDart'] + '/preview'
|
||||
extradata['aspect'] = 'discart'
|
||||
extras.append(extradata)
|
||||
if item.get('strAlbum3DCase',''):
|
||||
extradata = {}
|
||||
extradata['image'] = item['strAlbum3DCase']
|
||||
extradata['preview'] = item['strAlbum3DCase'] + '/preview'
|
||||
extradata['aspect'] = '3dcase'
|
||||
extras.append(extradata)
|
||||
if item.get('strAlbum3DFlat',''):
|
||||
extradata = {}
|
||||
extradata['image'] = item['strAlbum3DFlat']
|
||||
extradata['preview'] = item['strAlbum3DFlat'] + '/preview'
|
||||
extradata['aspect'] = '3dflat'
|
||||
extras.append(extradata)
|
||||
if item.get('strAlbum3DFace',''):
|
||||
extradata = {}
|
||||
extradata['image'] = item['strAlbum3DFace']
|
||||
extradata['preview'] = item['strAlbum3DFace'] + '/preview'
|
||||
extradata['aspect'] = '3dface'
|
||||
extras.append(extradata)
|
||||
if item.get('strAlbum3DThumb',''):
|
||||
extradata = {}
|
||||
extradata['image'] = item['strAlbum3DThumb']
|
||||
extradata['preview'] = item['strAlbum3DThumb'] + '/preview'
|
||||
extradata['aspect'] = '3dthumb'
|
||||
extras.append(extradata)
|
||||
if thumbs:
|
||||
albumdata['thumb'] = thumbs
|
||||
if extras:
|
||||
albumdata['extras'] = extras
|
||||
return albumdata
|
||||
29
Kodi/Lenovo/addons/metadata.generic.albums/lib/utils.py
Normal file
29
Kodi/Lenovo/addons/metadata.generic.albums/lib/utils.py
Normal file
@@ -0,0 +1,29 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
AUDIODBKEY = '95424d43204d6564696538'
|
||||
AUDIODBURL = 'https://www.theaudiodb.com/api/v1/json/%s/%s'
|
||||
AUDIODBSEARCH = 'searchalbum.php?s=%s&a=%s'
|
||||
AUDIODBDETAILS = 'album-mb.php?i=%s'
|
||||
|
||||
MUSICBRAINZURL = 'https://musicbrainz.org/ws/2/%s'
|
||||
MUSICBRAINZSEARCH = 'release/?query=release:"%s"%%20AND%%20(artistname:"%s"%%20OR%%20artist:"%s")&fmt=json'
|
||||
MUSICBRAINZLINKS = 'release-group/%s?inc=url-rels&fmt=json'
|
||||
MUSICBRAINZDETAILS = 'release/%s?inc=release-groups+artists+labels+ratings&fmt=json'
|
||||
MUSICBRAINZART = 'https://coverartarchive.org/release-group/%s'
|
||||
|
||||
DISCOGSKEY = 'zACPgktOmNegwbwKWMaC'
|
||||
DISCOGSSECRET = 'wGuSOeMtfdkQxtERKQKPquyBwExSHdQq'
|
||||
DISCOGSURL = 'https://api.discogs.com/%s'
|
||||
DISCOGSSEARCH = 'database/search?release_title=%s&type=release&artist=%s&page=1&per_page=100&key=%s&secret=%s'
|
||||
DISCOGSMASTER = 'masters/%s?key=%s&secret=%s'
|
||||
DISCOGSDETAILS = 'releases/%s?key=%s&secret=%s'
|
||||
|
||||
ALLMUSICURL = 'https://www.allmusic.com/%s'
|
||||
ALLMUSICSEARCH = 'search/albums/%s+%s'
|
||||
ALLMUSICDETAILS = '%s/releases'
|
||||
|
||||
FANARTVKEY = '88ca41db0d6878929f1f9771eade41fd'
|
||||
FANARTVURL = 'https://webservice.fanart.tv/v3/music/albums/%s?api_key=%s'
|
||||
|
||||
WIKIDATAURL = 'https://www.wikidata.org/wiki/Special:EntityData/%s.json'
|
||||
WIKIPEDIAURL = 'https://en.wikipedia.org/w/api.php?action=query&format=json&prop=extracts&titles=%s&formatversion=2&exsentences=10&exlimit=1&explaintext=1'
|
||||
@@ -0,0 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
|
||||
def wikipedia_albumdetails(data):
|
||||
albumdata = {}
|
||||
# check in case musicbrainz did not provide a direct link
|
||||
if 'extract' in data['query']['pages'][0] and not data['query']['pages'][0]['extract'].endswith('may refer to:'):
|
||||
albumdata['description'] = re.sub('\n\n\n== .*? ==\n', ' ', data['query']['pages'][0]['extract'])
|
||||
return albumdata
|
||||
Reference in New Issue
Block a user