class LocalCoverSource(Source): def __init__(self, args): self.root = expanduser(expandvars(args["root"])) Logger("coverfetcher").info("Created LocalCoverSource. Root={}", self.root) self.logger = Logger("coverfetcher.local") COVER_FILENAMES = ( "cover.jpg", "cover.png", "folder.jpg", "folder.png", ) def _parse_file_path(self, albuminfo): if "file" not in albuminfo: return None # Handle mopidy library file paths file = albuminfo["file"] if file.startswith("local:track:"): file = unquote(re.sub("^local:track:", "", file)) u = urlparse(file) if u.scheme == "": return u.path if isabs(u.path) else join(self.root, u.path) elif u.scheme == "file": return unquote(u.path) else: self.logger.warning("Unknown URI scheme: {}. Ignoring it.", u) # TODO: log warning return None def fetch(self, albuminfo): path = self._parse_file_path(albuminfo) if not path: return None dirpath = dirname(path) for path in [join(dirpath, n) for n in self.COVER_FILENAMES]: if isfile(path): with open(path, "rb") as f: self.logger.debug("Found cover: {}", path) return {"extension": splitext(path)[1][1:], "bytedata": f.read()} return None
def __init__(self, args): self.root = expanduser(expandvars(args["root"])) Logger("coverfetcher").info("Created LocalCoverSource. Root={}", self.root) self.logger = Logger("coverfetcher.local")
def __init__(self, args): Logger("coverfetcher").info("Created WikipediaCoverSource") self.logger = Logger("coverfetcher.wiki")
class WikipediaCoverSource(Source): def __init__(self, args): Logger("coverfetcher").info("Created WikipediaCoverSource") self.logger = Logger("coverfetcher.wiki") DBPEDIA_URL = 'http://dbpedia.org/sparql' WIKIPEDIA_URL = 'http://en.wikipedia.org/w/api.php' SPARQL_QUERY = '''PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX dbpprop: <http://dbpedia.org/property/> PREFIX owl: <http://dbpedia.org/ontology/> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> SELECT DISTINCT ?coverFilename WHERE {{ ?subject dbpprop:name ?name . ?subject rdfs:label ?label . {{ ?subject dbpprop:artist ?artist }} UNION {{ ?subject owl:artist ?artist }} {{ ?artist rdfs:label "{artist}"@en }} UNION {{ ?artist dbpprop:name "{artist}"@en }} ?subject rdf:type <http://dbpedia.org/ontology/Album> . ?subject dbpprop:cover ?coverFilename . FILTER ( regex(?name, "{album}", "i") ) }} Limit 1''' def get_url(self, albuminfo): # Find the name of the cover art filename on DBpedia cover_filename = None dbpedia_response = requests.get( self.DBPEDIA_URL, params={ 'format': 'application/sparql-results+json', 'timeout': 2500, 'query': self.SPARQL_QUERY.format(artist=albuminfo["artist"], album=albuminfo["album"]) }, headers={'content-type': 'application/json'}) try: data = dbpedia_response.json() results = data['results']['bindings'] if results: cover_filename = results[0]['coverFilename']['value'] self.logger.debug("Found album: %s" % cover_filename) else: self.logger.debug("Album not found on dbpedia") # TODO except: self.logger.error("Error scraping dbpedia album page") # Ensure we have a filename before attempting to query wikipedia if not cover_filename: return None # Find the absolute url of the cover art on Wikipedia wikipedia_response = requests.get(self.WIKIPEDIA_URL, params={ 'format': 'json', 'action': 'query', 'continue': '', 'prop': 'imageinfo', 'iiprop': 'url', 'titles': ('File:' + cover_filename).encode('utf-8')}, headers={'content-type': 'application/json'}) try: data = wikipedia_response.json() results = data['query']['pages'] for _, result in results.items(): image_url = result['imageinfo'][0]['url'] return image_url except: self.logger.error("Error scraping wikipedia imageinfo") return None def fetch(self, albuminfo): url = self.get_url(albuminfo) if url: extension = url.split(".")[-1].lower() bytedata = read(url) return {"extension": extension, "bytedata": bytedata} return None