mirror of
https://github.com/fergalmoran/picard.git
synced 2026-01-06 08:34:01 +00:00
MusicDNS lookups.
This commit is contained in:
72
picard/musicdns/webservice.py
Normal file
72
picard/musicdns/webservice.py
Normal file
@@ -0,0 +1,72 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Picard, the next-generation MusicBrainz tagger
|
||||
# Copyright (C) 2006 Lukáš Lalinský
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
import musicbrainz2.webservice
|
||||
import urllib
|
||||
from musicbrainz2.webservice import ResponseError
|
||||
from musicbrainz2.wsxml import MbXmlParser, ParseError
|
||||
|
||||
|
||||
class TrackFilter(musicbrainz2.webservice.IFilter):
|
||||
|
||||
def __init__(self, clientId=None, clientVersion=None, fingerprint=None,
|
||||
puid=None, fileSha1=None, acousticSha1=None, metadata=None,
|
||||
bitrate=None, format=None, length=None, artist=None,
|
||||
title=None, album=None, trackNum=None, genre=None, year=None,
|
||||
composer=None, conductor=None, orchestra=None, encoding=None,
|
||||
lookupType=None):
|
||||
self._params = [
|
||||
('lkt', lookupType),
|
||||
('cid', clientId),
|
||||
('cvr', clientVersion),
|
||||
('fpt', fingerprint),
|
||||
('uid', puid),
|
||||
('s1f', fileSha1),
|
||||
('s1a', acousticSha1),
|
||||
('rmd', metadata),
|
||||
('brt', bitrate),
|
||||
('fmt', format),
|
||||
('dur', length),
|
||||
('art', artist),
|
||||
('ttl', title),
|
||||
('alb', album),
|
||||
('tnm', trackNum),
|
||||
('gnr', genre),
|
||||
('yrr', year),
|
||||
('cmp', composer),
|
||||
('cnd', conductor),
|
||||
('orc', orchestra),
|
||||
('enc', encoding),
|
||||
]
|
||||
|
||||
def createParameters(self):
|
||||
return musicbrainz2.webservice._createParameters(self._params)
|
||||
|
||||
|
||||
class Query(musicbrainz2.webservice.Query):
|
||||
|
||||
def getTrack(self, filter):
|
||||
params = filter.createParameters()
|
||||
stream = self._ws.post("track", "", urllib.urlencode(params, True))
|
||||
try:
|
||||
parser = MbXmlParser()
|
||||
return parser.parse(stream).getTrack()
|
||||
except ParseError, e:
|
||||
raise ResponseError(str(e), e)
|
||||
|
||||
@@ -117,7 +117,8 @@ class Tagger(QtGui.QApplication, ComponentManager, Component):
|
||||
console = logging.StreamHandler(sys.stdout)
|
||||
console.setFormatter(logging.Formatter(u"%(thread)s %(asctime)s %(message)s",
|
||||
u"%H:%M:%S"))
|
||||
self.log = logging.getLogger("picard")
|
||||
self.log = logging.getLogger()
|
||||
# self.log = logging.getLogger("picard")
|
||||
self.log.addHandler(console)
|
||||
self.log.setLevel(logging.DEBUG)
|
||||
|
||||
@@ -655,10 +656,23 @@ class Tagger(QtGui.QApplication, ComponentManager, Component):
|
||||
self.thread_assist.spawn(self.__analyze_thread, (files,))
|
||||
|
||||
def __analyze_thread(self, files):
|
||||
from picard.musicdns.webservice import TrackFilter, Query
|
||||
ws = self.get_web_service()
|
||||
ws._host = "ofa.musicdns.org"
|
||||
ws._pathPrefix = "/ofa"
|
||||
for file in files:
|
||||
file.lock_for_read()
|
||||
try:
|
||||
filename = file.filename
|
||||
artist = file.metadata["artist"]
|
||||
title = file.metadata["title"]
|
||||
album = file.metadata["album"]
|
||||
trackNum = file.metadata["tracknumber"]
|
||||
genre = file.metadata["genre"]
|
||||
year = file.metadata["date"][:4]
|
||||
format = file.metadata["~format"]
|
||||
bitrate = str(file.metadata.get("~#bitrate", 0))
|
||||
length = file.metadata.get("~#length", 0)
|
||||
finally:
|
||||
file.unlock()
|
||||
self.log.debug("Analyzing file %s", filename)
|
||||
@@ -667,6 +681,34 @@ class Tagger(QtGui.QApplication, ComponentManager, Component):
|
||||
fingerprint, duration = result
|
||||
self.log.debug("File %s analyzed.\nFingerprint: %s\n"
|
||||
"Duration: %s", filename, fingerprint, duration)
|
||||
if not length:
|
||||
length = duration
|
||||
q = Query(ws)
|
||||
track = q.getTrack(TrackFilter(
|
||||
clientId="80eaa76658f99dbac1c58cc06aa44779",
|
||||
clientVersion="picard-0.9", fingerprint=fingerprint,
|
||||
artist=artist, title=title, album=album, trackNum=trackNum,
|
||||
genre=genre, year=year, bitrate=bitrate, format=format,
|
||||
length=str(length), metadata="1", lookupType="1",
|
||||
encoding=""))
|
||||
if track:
|
||||
artist = ""
|
||||
if track.artist:
|
||||
artist = track.artist.name or ""
|
||||
self.log.debug("Fingerprint looked up.\nPUID: %s\nTitle: %s\n"
|
||||
"Artist: %s", track.puids, track.title or "",
|
||||
artist)
|
||||
if track.puids:
|
||||
file.lock_for_write()
|
||||
try:
|
||||
file.metadata["musicip_puid"] = track.puids[0]
|
||||
finally:
|
||||
file.unlock()
|
||||
else:
|
||||
self.log.debug("Fingerprint looked up, no PUID found.")
|
||||
|
||||
|
||||
|
||||
|
||||
def set_wait_cursor(self):
|
||||
"""Sets the waiting cursor."""
|
||||
|
||||
@@ -58,6 +58,28 @@ class CachedWebService(WebService):
|
||||
self._log.debug(u"(Cached) GET %s", url)
|
||||
return open(filename, 'rb')
|
||||
|
||||
def post(self, entity, id_, data, version='1'):
|
||||
url = self._makeUrl(entity, id_, version=version, type_=None)
|
||||
filename = self._make_cache_filename(url + data)
|
||||
if not os.path.isfile(filename):
|
||||
stream = WebService.post(self, entity, id_, data, version)
|
||||
try:
|
||||
outfile = open(filename, 'wb')
|
||||
except IOError:
|
||||
self._log.error('Couldn\'t create cache file %s', filename)
|
||||
return stream
|
||||
else:
|
||||
data = stream.read()
|
||||
if self._host == "ofa.musicdns.org":
|
||||
data = data.replace("http://musicbrainz.org/ns/mmd/1/",
|
||||
"http://musicbrainz.org/ns/mmd-1.0#")
|
||||
outfile.write(data)
|
||||
outfile.close()
|
||||
stream.close()
|
||||
else:
|
||||
self._log.debug(u"(Cached) POST %s", url)
|
||||
return open(filename, 'rb')
|
||||
|
||||
def get_from_url(self, url):
|
||||
filename = self._make_cache_filename(url)
|
||||
if not os.path.isfile(filename):
|
||||
|
||||
Reference in New Issue
Block a user