[SCM] morituri/master: * morituri/common/Makefile.am: * morituri/common/musicbrainz.py: * morituri/common/program.py: * morituri/test/Makefile.am: * morituri/test/test_common_musicbrainz.py (added): * morituri/common/musicbrainz.py (added): Split off musicbrainz-specific code.
js at users.alioth.debian.org
js at users.alioth.debian.org
Sun Oct 19 20:09:36 UTC 2014
The following commit has been merged in the master branch:
commit 6ab37720df55f9adee2348f23d012e797deee9b3
Author: Thomas Vander Stichele <thomas (at) apestaart (dot) org>
Date: Wed Oct 19 18:00:11 2011 +0000
* morituri/common/Makefile.am:
* morituri/common/musicbrainz.py:
* morituri/common/program.py:
* morituri/test/Makefile.am:
* morituri/test/test_common_musicbrainz.py (added):
* morituri/common/musicbrainz.py (added):
Split off musicbrainz-specific code.
diff --git a/ChangeLog b/ChangeLog
index bb7cc7a..221aeb5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
2011-10-19 Thomas Vander Stichele <thomas at apestaart dot org>
+ * morituri/common/Makefile.am:
+ * morituri/common/musicbrainz.py:
+ * morituri/common/program.py:
+ * morituri/test/Makefile.am:
+ * morituri/test/test_common_musicbrainz.py (added):
+ * morituri/common/musicbrainz.py (added):
+ Split off musicbrainz-specific code.
+
+2011-10-19 Thomas Vander Stichele <thomas at apestaart dot org>
+
* TODO:
* morituri/extern/task/task.py:
Instead of chaining next in multi tasks, making the call
diff --git a/morituri/common/Makefile.am b/morituri/common/Makefile.am
index ad29478..5e9b978 100644
--- a/morituri/common/Makefile.am
+++ b/morituri/common/Makefile.am
@@ -12,5 +12,6 @@ morituri_PYTHON = \
gstreamer.py \
log.py \
logcommand.py \
+ musicbrainz.py \
program.py \
renamer.py
diff --git a/morituri/common/musicbrainz.py b/morituri/common/musicbrainz.py
new file mode 100644
index 0000000..e16ad58
--- /dev/null
+++ b/morituri/common/musicbrainz.py
@@ -0,0 +1,187 @@
+# -*- Mode: Python; test-case-name: morituri.test.test_common_musicbrainz -*-
+# vi:si:et:sw=4:sts=4:ts=4
+
+# Morituri - for those about to RIP
+
+# Copyright (C) 2009, 2010, 2011 Thomas Vander Stichele
+
+# This file is part of morituri.
+#
+# morituri 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 3 of the License, or
+# (at your option) any later version.
+#
+# morituri 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 morituri. If not, see <http://www.gnu.org/licenses/>.
+
+"""
+Handles communication with the musicbrainz server.
+"""
+
+import urlparse
+
+from morituri.common import log
+
+
+class MusicBrainzException(Exception):
+ def __init__(self, exc):
+ self.args = (exc, )
+ self.exception = exc
+
+
+class TrackMetadata(object):
+ artist = None
+ title = None
+ duration = None # in ms
+ mbid = None
+ sortName = None
+ mbidArtist = None
+
+
+class DiscMetadata(object):
+ """
+ @param release: earliest release date, in YYYY-MM-DD
+ @type release: unicode
+ """
+ artist = None
+ sortName = None
+ title = None
+ various = False
+ tracks = None
+ release = None
+
+ mbid = None
+ mbidArtist = None
+
+ def __init__(self):
+ self.tracks = []
+
+
+def _getMetadata(release):
+ """
+ @type release: L{musicbrainz2.model.Release}
+
+ @rtype: L{DiscMetadata} or None
+ """
+ log.debug('program', 'getMetadata for release id %r',
+ release.getId())
+ if not release.getId():
+ log.warning('program', 'No id for release %r', release)
+ return None
+
+ assert release.id, 'Release does not have an id'
+
+ metadata = DiscMetadata()
+
+ isSingleArtist = release.isSingleArtistRelease()
+ metadata.various = not isSingleArtist
+ metadata.title = release.title
+ # getUniqueName gets disambiguating names like Muse (UK rock band)
+ metadata.artist = release.artist.name
+ metadata.sortName = release.artist.sortName
+ metadata.release = release.getEarliestReleaseDate()
+
+ metadata.mbid = urlparse.urlparse(release.id)[2].split("/")[-1]
+ metadata.mbidArtist = urlparse.urlparse(release.artist.id)[2].split("/")[-1]
+ metadata.url = release.getId()
+
+ tainted = False
+ duration = 0
+
+ for t in release.tracks:
+ track = TrackMetadata()
+
+ if isSingleArtist or t.artist == None:
+ track.artist = metadata.artist
+ track.sortName = metadata.sortName
+ track.mbidArtist = metadata.mbidArtist
+ else:
+ # various artists discs can have tracks with no artist
+ track.artist = t.artist and t.artist.name or release.artist.name
+ track.sortName = t.artist.sortName
+ track.mbidArtist = urlparse.urlparse(t.artist.id)[2].split("/")[-1]
+
+ track.title = t.title
+ track.mbid = urlparse.urlparse(t.id)[2].split("/")[-1]
+
+ track.duration = t.duration
+ if not track.duration:
+ log.warning('getMetadata',
+ 'track %r (%r) does not have duration' % (
+ track.title, track.mbid))
+ tainted = True
+ else:
+ duration += t.duration
+
+ metadata.tracks.append(track)
+
+ if not tainted:
+ metadata.duration = duration
+ else:
+ metadata.duration = 0
+
+ return metadata
+
+
+# see http://bugs.musicbrainz.org/browser/python-musicbrainz2/trunk/examples/ripper.py
+def musicbrainz(discid):
+ """
+ @rtype: list of L{DiscMetadata}
+ """
+ log.debug('musicbrainz', 'looking up results for discid %r', discid)
+ #import musicbrainz2.disc as mbdisc
+ import musicbrainz2.webservice as mbws
+
+ results = []
+
+ # Setup a Query object.
+ service = mbws.WebService()
+ query = mbws.Query(service)
+
+
+ # Query for all discs matching the given DiscID.
+ # FIXME: let mbws.WebServiceError go through for now
+ try:
+ rfilter = mbws.ReleaseFilter(discId=discid)
+ results = query.getReleases(rfilter)
+ except mbws.WebServiceError, e:
+ raise MusicBrainzException(e)
+
+ # No disc matching this DiscID has been found.
+ if len(results) == 0:
+ return None
+
+ log.debug('musicbrainz', 'found %d results for discid %r', len(results),
+ discid)
+
+ # Display the returned results to the user.
+ ret = []
+
+ for result in results:
+ release = result.release
+ log.debug('program', 'result %r: artist %r, title %r' % (
+ release, release.artist.getName(), release.title))
+ # The returned release object only contains title and artist, but no
+ # tracks. Query the web service once again to get all data we need.
+ try:
+ inc = mbws.ReleaseIncludes(artist=True, tracks=True,
+ releaseEvents=True, discs=True)
+ # Arid - Under the Cold Street Lights has getId() None
+ if release.getId():
+ release = query.getReleaseById(release.getId(), inc)
+ except mbws.WebServiceError, e:
+ raise MusicBrainzException(e)
+
+ md = _getMetadata(release)
+ if md:
+ log.debug('program', 'duration %r', md.duration)
+ ret.append(md)
+
+
+ return ret
diff --git a/morituri/common/program.py b/morituri/common/program.py
index ed2b6f5..fb05cf7 100644
--- a/morituri/common/program.py
+++ b/morituri/common/program.py
@@ -25,177 +25,23 @@ Common functionality and class for all programs using morituri.
"""
import os
-import urlparse
import time
-from morituri.common import common, log
+from morituri.common import common, log, musicbrainz
from morituri.result import result
from morituri.program import cdrdao, cdparanoia
from morituri.image import image
-class MusicBrainzException(Exception):
- def __init__(self, exc):
- self.args = (exc, )
- self.exception = exc
-
-class TrackMetadata(object):
- artist = None
- title = None
- duration = None # in ms
- mbid = None
- sortName = None
- mbidArtist = None
-
-class DiscMetadata(object):
- """
- @param release: earliest release date, in YYYY-MM-DD
- @type release: unicode
- """
- artist = None
- sortName = None
- title = None
- various = False
- tracks = None
- release = None
-
- mbid = None
- mbidArtist = None
-
- def __init__(self):
- self.tracks = []
-
def filterForPath(text):
return "-".join(text.split("/"))
-def getMetadata(release):
- """
- @type release: L{musicbrainz2.model.Release}
-
- @rtype: L{DiscMetadata} or None
- """
- log.debug('program', 'getMetadata for release id %r',
- release.getId())
- if not release.getId():
- log.warning('program', 'No id for release %r', release)
- return None
-
- assert release.id, 'Release does not have an id'
-
- metadata = DiscMetadata()
-
- isSingleArtist = release.isSingleArtistRelease()
- metadata.various = not isSingleArtist
- metadata.title = release.title
- # getUniqueName gets disambiguating names like Muse (UK rock band)
- metadata.artist = release.artist.name
- metadata.sortName = release.artist.sortName
- metadata.release = release.getEarliestReleaseDate()
-
- metadata.mbid = urlparse.urlparse(release.id)[2].split("/")[-1]
- metadata.mbidArtist = urlparse.urlparse(release.artist.id)[2].split("/")[-1]
- metadata.url = release.getId()
-
- tainted = False
- duration = 0
-
- for t in release.tracks:
- track = TrackMetadata()
-
- if isSingleArtist or t.artist == None:
- track.artist = metadata.artist
- track.sortName = metadata.sortName
- track.mbidArtist = metadata.mbidArtist
- else:
- # various artists discs can have tracks with no artist
- track.artist = t.artist and t.artist.name or release.artist.name
- track.sortName = t.artist.sortName
- track.mbidArtist = urlparse.urlparse(t.artist.id)[2].split("/")[-1]
-
- track.title = t.title
- track.mbid = urlparse.urlparse(t.id)[2].split("/")[-1]
-
- track.duration = t.duration
- if not track.duration:
- log.warning('getMetadata',
- 'track %r (%r) does not have duration' % (
- track.title, track.mbid))
- tainted = True
- else:
- duration += t.duration
-
- metadata.tracks.append(track)
-
- if not tainted:
- metadata.duration = duration
- else:
- metadata.duration = 0
-
- return metadata
-
-
-# see http://bugs.musicbrainz.org/browser/python-musicbrainz2/trunk/examples/ripper.py
-def musicbrainz(discid):
- """
- @rtype: list of L{DiscMetadata}
- """
- log.debug('musicbrainz', 'looking up results for discid %r', discid)
- #import musicbrainz2.disc as mbdisc
- import musicbrainz2.webservice as mbws
-
- results = []
-
- # Setup a Query object.
- service = mbws.WebService()
- query = mbws.Query(service)
-
-
- # Query for all discs matching the given DiscID.
- # FIXME: let mbws.WebServiceError go through for now
- try:
- rfilter = mbws.ReleaseFilter(discId=discid)
- results = query.getReleases(rfilter)
- except mbws.WebServiceError, e:
- raise MusicBrainzException(e)
-
- # No disc matching this DiscID has been found.
- if len(results) == 0:
- return None
-
- log.debug('musicbrainz', 'found %d results for discid %r', len(results),
- discid)
-
- # Display the returned results to the user.
- ret = []
-
- for result in results:
- release = result.release
- log.debug('program', 'result %r: artist %r, title %r' % (
- release, release.artist.getName(), release.title))
- # The returned release object only contains title and artist, but no
- # tracks. Query the web service once again to get all data we need.
- try:
- inc = mbws.ReleaseIncludes(artist=True, tracks=True,
- releaseEvents=True, discs=True)
- # Arid - Under the Cold Street Lights has getId() None
- if release.getId():
- release = query.getReleaseById(release.getId(), inc)
- except mbws.WebServiceError, e:
- raise MusicBrainzException(e)
-
- md = getMetadata(release)
- if md:
- log.debug('program', 'duration %r', md.duration)
- ret.append(md)
-
-
- return ret
class Program(log.Loggable):
"""
I maintain program state and functionality.
@ivar metadata:
- @type metadata: L{DiscMetadata}
+ @type metadata: L{musicbrainz.DiscMetadata}
@ivar result: the rip's result
@type result: L{result.RipResult}
@type outdir: unicode
@@ -378,8 +224,8 @@ class Program(log.Loggable):
for _ in range(0, 4):
try:
- metadatas = musicbrainz(mbdiscid)
- except MusicBrainzException, e:
+ metadatas = musicbrainz.musicbrainz(mbdiscid)
+ except musicbrainz.MusicBrainzException, e:
print "Warning:", e
time.sleep(5)
continue
diff --git a/morituri/test/Makefile.am b/morituri/test/Makefile.am
index 2acd495..4b3e0bb 100644
--- a/morituri/test/Makefile.am
+++ b/morituri/test/Makefile.am
@@ -5,6 +5,7 @@ EXTRA_DIST = \
common.py \
test_common_accurip.py \
test_common_checksum.py \
+ test_common_musicbrainz.py \
test_common_program.py \
test_common_renamer.py \
test_image_cue.py \
diff --git a/morituri/test/test_common_musicbrainz.py b/morituri/test/test_common_musicbrainz.py
new file mode 100644
index 0000000..73a0735
--- /dev/null
+++ b/morituri/test/test_common_musicbrainz.py
@@ -0,0 +1,54 @@
+# -*- Mode: Python; test-case-name: morituri.test.test_common_musicbrainz -*-
+# vi:si:et:sw=4:sts=4:ts=4
+
+import os
+
+import unittest
+
+from morituri.common import musicbrainz
+
+
+class MetadataLengthTestCase(unittest.TestCase):
+ def testLamprey(self):
+ from musicbrainz2 import wsxml
+
+ path = os.path.join(os.path.dirname(__file__),
+ 'release.c7d919f4-3ea0-4c4b-a230-b3605f069440.xml')
+ handle = open(path, "rb")
+
+ reader = wsxml.MbXmlParser()
+ wsMetadata = reader.parse(handle)
+ release = wsMetadata.getRelease()
+ metadata = musicbrainz._getMetadata(release)
+
+ self.assertEquals(metadata.duration, 2962889)
+
+ def testLadyhawke(self):
+ from musicbrainz2 import wsxml
+
+ path = os.path.join(os.path.dirname(__file__),
+ 'release.93a6268c-ddf1-4898-bf93-fb862b1c5c5e.xml')
+ handle = open(path, "rb")
+
+ reader = wsxml.MbXmlParser()
+ wsMetadata = reader.parse(handle)
+ release = wsMetadata.getRelease()
+ metadata = musicbrainz._getMetadata(release)
+ self.failUnless(metadata)
+
+ # self.assertEquals(metadata.duration, 2609413)
+
+ def testDasCapital(self):
+ from musicbrainz2 import wsxml
+
+ path = os.path.join(os.path.dirname(__file__),
+ 'release.08397059-86c1-463b-8ed0-cd596dbd174f.xml')
+ handle = open(path, "rb")
+
+ reader = wsxml.MbXmlParser()
+ wsMetadata = reader.parse(handle)
+ release = wsMetadata.getRelease()
+ metadata = musicbrainz._getMetadata(release)
+
+ # FIXME: 2 seconds longer than the duration according to table
+ self.assertEquals(metadata.duration, 2315730)
--
morituri packaging
More information about the pkg-multimedia-commits
mailing list