MusicDNS lookups.

This commit is contained in:
Lukáš Lalinský
2006-10-08 14:03:35 +02:00
parent d55212c203
commit b9610d3517
3 changed files with 137 additions and 1 deletions

View 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)

View File

@@ -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."""

View File

@@ -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):