* morituri/common/program.py:

Add a retagging command.
	  Add a getMusicBrainz() method.
	* morituri/rip/cd.py:
	  Use it.
	* morituri/image/image.py:
	  Add a task to retag an image.
	* morituri/rip/image.py:
	  Add a command to retag an image.
This commit is contained in:
Thomas Vander Stichele
2010-04-13 21:57:29 +00:00
parent d9ca12d7cc
commit 297451ea0e
5 changed files with 119 additions and 30 deletions

View File

@@ -1,3 +1,15 @@
2010-04-13 Thomas Vander Stichele <thomas at apestaart dot org>
* morituri/common/program.py:
Add a retagging command.
Add a getMusicBrainz() method.
* morituri/rip/cd.py:
Use it.
* morituri/image/image.py:
Add a task to retag an image.
* morituri/rip/image.py:
Add a command to retag an image.
2010-04-13 Thomas Vander Stichele <thomas at apestaart dot org> 2010-04-13 Thomas Vander Stichele <thomas at apestaart dot org>
* morituri/common/encode.py: * morituri/common/encode.py:

View File

@@ -25,6 +25,7 @@ Common functionality and class for all programs using morituri.
""" """
import os import os
import urlparse
from morituri.common import common, log from morituri.common import common, log
from morituri.result import result from morituri.result import result
@@ -71,18 +72,23 @@ def getMetadata(release):
metadata.artist = release.artist.name metadata.artist = release.artist.name
metadata.sortName = release.artist.sortName metadata.sortName = release.artist.sortName
metadata.release = release.getEarliestReleaseDate() metadata.release = release.getEarliestReleaseDate()
metadata.mbid = urlparse.urlparse(release.id)[2].split("/")[-1]
metadata.artistMBID = urlparse.urlparse(release.artist.id)[2].split("/")[-1]
for t in release.tracks: for t in release.tracks:
track = TrackMetadata() track = TrackMetadata()
if isSingleArtist: if isSingleArtist:
track.artist = metadata.artist track.artist = metadata.artist
track.sortName = metadata.sortName track.sortName = metadata.sortName
track.title = t.title track.artistMBID = metadata.artistMBID
else: else:
# various artists discs can have tracks with no artist # various artists discs can have tracks with no artist
track.artist = t.artist and t.artist.name or release.artist.name track.artist = t.artist and t.artist.name or release.artist.name
track.sortName = t.artist.sortName track.sortName = t.artist.sortName
track.title = t.title
track.title = t.title
track.mbid = urlparse.urlparse(t.id)[2].split("/")[-1]
metadata.tracks.append(track) metadata.tracks.append(track)
return metadata return metadata
@@ -276,6 +282,34 @@ class Program(log.Loggable):
return os.path.join(outdir, template % v) return os.path.join(outdir, template % v)
def getMusicBrainz(self, ittoc, mbdiscid):
# look up disc on musicbrainz
ret = None
metadatas = None
try:
metadatas = musicbrainz(mbdiscid)
except MusicBrainzException, e:
print "Error:", e
print 'Continuing without metadata'
if metadatas:
print 'Matching releases:'
for metadata in metadatas:
print 'Artist : %s' % metadata.artist.encode('utf-8')
print 'Title : %s' % metadata.title.encode('utf-8')
# Select one of the returned releases. We just pick the first one.
ret = metadatas[0]
else:
print 'Submit this disc to MusicBrainz at:'
print ittoc.getMusicBrainzSubmitURL()
ret = None
print
return ret
def getTagList(self, number): def getTagList(self, number):
""" """
Based on the metadata, get a gst.TagList for the given track. Based on the metadata, get a gst.TagList for the given track.
@@ -292,10 +326,15 @@ class Program(log.Loggable):
if self.metadata: if self.metadata:
artist = self.metadata.artist artist = self.metadata.artist
disc = self.metadata.title disc = self.metadata.title
albumMBID = self.metadata.mbid
albumArtistMBID = self.metadata.artistMBID
if number > 0: if number > 0:
try: try:
artist = self.metadata.tracks[number - 1].artist artist = self.metadata.tracks[number - 1].artist
title = self.metadata.tracks[number - 1].title title = self.metadata.tracks[number - 1].title
trackMBID = self.metadata.tracks[number - 1].mbid
trackArtistMBID = self.metadata.tracks[number - 1].artistMBID
except IndexError, e: except IndexError, e:
print 'ERROR: no track %d found, %r' % (number, e) print 'ERROR: no track %d found, %r' % (number, e)
raise raise
@@ -342,6 +381,11 @@ class Program(log.Loggable):
str(date)) str(date))
ret[gst.TAG_DATE] = s['date'] ret[gst.TAG_DATE] = s['date']
ret["musicbrainz-trackid"] = trackMBID
ret["musicbrainz-artistid"] = trackArtistMBID
ret["musicbrainz-albumid"] = albumMBID
ret["musicbrainz-albumartistid"] = albumArtistMBID
# FIXME: gst.TAG_ISRC # FIXME: gst.TAG_ISRC
return ret return ret
@@ -404,6 +448,11 @@ class Program(log.Loggable):
trackResult.peak = t.peak trackResult.peak = t.peak
trackResult.quality = t.quality trackResult.quality = t.quality
def retagImage(self, runner, taglists):
cueImage = image.Image(self.cuePath)
t = image.ImageRetagTask(cueImage, taglists)
runner.run(t)
def verifyImage(self, runner, responses): def verifyImage(self, runner, responses):
""" """
Verify our image against the given AccurateRip responses. Verify our image against the given AccurateRip responses.

View File

@@ -200,12 +200,7 @@ class AudioLengthTask(task.Task):
error, debug = msg.parse_error() error, debug = msg.parse_error()
self.debug('Got GStreamer error: %r, debug: %r' % ( self.debug('Got GStreamer error: %r, debug: %r' % (
error.message, debug)) error.message, debug))
# give us an exception stack for debugging self.setAndRaiseException(error)
try:
raise error
except:
pass
self.setException(error)
self.stop() self.stop()
class ImageVerifyTask(task.MultiSeparateTask): class ImageVerifyTask(task.MultiSeparateTask):
@@ -300,4 +295,30 @@ class ImageEncodeTask(task.MultiSeparateTask):
index = track.indexes[1] index = track.indexes[1]
add(index) add(index)
class ImageRetagTask(task.MultiSeparateTask):
"""
I retag files in a disk image.
"""
description = "Retagging tracks"
def __init__(self, image, taglists):
task.MultiSeparateTask.__init__(self)
# here to avoid import gst eating our options
from morituri.common import encode
self._image = image
self._taglists = taglists
cue = image.cue
self._tasks = []
self.lengths = {}
for trackIndex, track in enumerate(cue.table.tracks):
self.debug('retagging track %d', trackIndex + 1)
index = track.indexes[1]
path = image.getRealPath(index.path)
assert type(path) is unicode, "%r is not unicode" % path
self.debug('schedule retag of %r', path)
root, ext = os.path.splitext(os.path.basename(path))
taskk = encode.RetagTask(path, taglists[trackIndex])

View File

@@ -113,26 +113,7 @@ See http://sourceforge.net/tracker/?func=detail&aid=604751&group_id=2171&atid=1
mbdiscid = ittoc.getMusicBrainzDiscId() mbdiscid = ittoc.getMusicBrainzDiscId()
print "MusicBrainz disc id", mbdiscid print "MusicBrainz disc id", mbdiscid
# look up disc on musicbrainz prog.metadata = prog.getMusicBrainz(ittoc, mbdiscid)
metadatas = None
try:
metadatas = program.musicbrainz(mbdiscid)
except program.MusicBrainzException, e:
print "Error:", e
print 'Continuing without metadata'
if metadatas:
print 'Matching releases:'
for metadata in metadatas:
print 'Artist : %s' % metadata.artist.encode('utf-8')
print 'Title : %s' % metadata.title.encode('utf-8')
# Select one of the returned releases. We just pick the first one.
prog.metadata = metadatas[0]
else:
print 'Submit this disc to MusicBrainz at:'
print ittoc.getMusicBrainzSubmitURL()
print
# now, read the complete index table, which is slower # now, read the complete index table, which is slower
itable = prog.getTable(runner, ittoc.getCDDBDiscId(), device) itable = prog.getTable(runner, ittoc.getCDDBDiscId(), device)

View File

@@ -22,7 +22,7 @@
import os import os
from morituri.common import logcommand, task, accurip, program from morituri.common import logcommand, task, accurip, program, encode
from morituri.image import image, cue from morituri.image import image, cue
from morituri.result import result from morituri.result import result
from morituri.program import cdrdao, cdparanoia from morituri.program import cdrdao, cdparanoia
@@ -97,6 +97,32 @@ class Encode(logcommand.LogCommand):
outm3u.write('%s' % root) outm3u.write('%s' % root)
outm3u.close() outm3u.close()
class Retag(logcommand.LogCommand):
summary = "retag image files"
def do(self, args):
prog = program.Program()
runner = task.SyncRunner()
cache = accurip.AccuCache()
for arg in args:
arg = unicode(arg)
cueImage = image.Image(arg)
cueImage.setup(runner)
mbdiscid = cueImage.table.getMusicBrainzDiscId()
prog.metadata = prog.getMusicBrainz(cueImage.table, mbdiscid)
# FIXME: this feels like we're poking at internals.
prog.cuePath = arg
prog.result = result.RipResult()
for track in cueImage.table.tracks:
path = track.indexes[1].path
taglist = prog.getTagList(track.number)
self.debug('possibly retagging %r with taglist %r',
path, taglist)
runner.run(encode.SafeRetagTask(path, taglist))
class Verify(logcommand.LogCommand): class Verify(logcommand.LogCommand):
summary = "verify image" summary = "verify image"
@@ -128,4 +154,4 @@ class Verify(logcommand.LogCommand):
class Image(logcommand.LogCommand): class Image(logcommand.LogCommand):
summary = "handle images" summary = "handle images"
subCommandClasses = [Encode, Verify, ] subCommandClasses = [Encode, Retag, Verify, ]