* morituri/image/cue.py:
* morituri/image/toc.py: * morituri/test/test_image_cue.py: * morituri/test/test_image_toc.py: Read input file as utf-8. Fix logging of paths. * morituri/image/image.py: Document and add asserts for unicodeness of paths. Encode path in launch lines as utf-8
This commit is contained in:
11
ChangeLog
11
ChangeLog
@@ -1,3 +1,14 @@
|
||||
2009-09-11 Thomas Vander Stichele <thomas at apestaart dot org>
|
||||
|
||||
* morituri/image/cue.py:
|
||||
* morituri/image/toc.py:
|
||||
* morituri/test/test_image_cue.py:
|
||||
* morituri/test/test_image_toc.py:
|
||||
Read input file as utf-8. Fix logging of paths.
|
||||
* morituri/image/image.py:
|
||||
Document and add asserts for unicodeness of paths.
|
||||
Encode path in launch lines as utf-8
|
||||
|
||||
2009-09-11 Thomas Vander Stichele <thomas at apestaart dot org>
|
||||
|
||||
* morituri/common/task.py:
|
||||
|
||||
@@ -28,6 +28,7 @@ See http://digitalx.org/cuesheetsyntax.php
|
||||
|
||||
import os
|
||||
import re
|
||||
import codecs
|
||||
|
||||
from morituri.common import common, log
|
||||
from morituri.image import table
|
||||
@@ -65,6 +66,11 @@ class CueFile(object, log.Loggable):
|
||||
@ivar table: the index table.
|
||||
"""
|
||||
def __init__(self, path):
|
||||
"""
|
||||
@type path: unicode
|
||||
"""
|
||||
assert type(path) is unicode, "%r is not unicode" % path
|
||||
|
||||
self._path = path
|
||||
self._rems = {}
|
||||
self._messages = []
|
||||
@@ -77,8 +83,8 @@ class CueFile(object, log.Loggable):
|
||||
currentTrack = None
|
||||
counter = 0
|
||||
|
||||
self.info('Parsing .cue file %s', self._path)
|
||||
handle = open(self._path, 'r')
|
||||
self.info('Parsing .cue file %r', self._path)
|
||||
handle = codecs.open(self._path, 'r', 'utf-8')
|
||||
|
||||
for number, line in enumerate(handle.readlines()):
|
||||
line = line.rstrip()
|
||||
@@ -134,7 +140,7 @@ class CueFile(object, log.Loggable):
|
||||
+ seconds * common.FRAMES_PER_SECOND \
|
||||
+ minutes * common.FRAMES_PER_SECOND * 60
|
||||
|
||||
self.debug('found index %d of track %r in %s:%d',
|
||||
self.debug('found index %d of track %r in %r:%d',
|
||||
indexNumber, currentTrack, currentFile.path, frameOffset)
|
||||
# FIXME: what do we do about File's FORMAT ?
|
||||
currentTrack.index(indexNumber,
|
||||
@@ -173,7 +179,11 @@ class CueFile(object, log.Loggable):
|
||||
def getRealPath(self, path):
|
||||
"""
|
||||
Translate the .cue's FILE to an existing path.
|
||||
|
||||
@type path: unicode
|
||||
"""
|
||||
assert type(path) is unicode, "%r is not unicode" % path
|
||||
|
||||
if os.path.exists(path):
|
||||
return path
|
||||
|
||||
@@ -199,7 +209,7 @@ class CueFile(object, log.Loggable):
|
||||
if os.path.exists(cpath):
|
||||
return cpath
|
||||
|
||||
raise KeyError, "Cannot find file for %s" % path
|
||||
raise KeyError, "Cannot find file for %r" % path
|
||||
|
||||
|
||||
class File:
|
||||
@@ -207,8 +217,13 @@ class File:
|
||||
I represent a FILE line in a cue file.
|
||||
"""
|
||||
def __init__(self, path, format):
|
||||
"""
|
||||
@type path: unicode
|
||||
"""
|
||||
assert type(path) is unicode, "%r is not unicode" % path
|
||||
|
||||
self.path = path
|
||||
self.format = format
|
||||
|
||||
def __repr__(self):
|
||||
return '<File "%s" of format %s>' % (self.path, self.format)
|
||||
return '<File %r of format %s>' % (self.path, self.format)
|
||||
|
||||
@@ -37,8 +37,11 @@ class Image(object, log.Loggable):
|
||||
|
||||
def __init__(self, path):
|
||||
"""
|
||||
@type path: unicode
|
||||
@param path: .cue path
|
||||
"""
|
||||
assert type(path) is unicode, "%r is not unicode" % path
|
||||
|
||||
self._path = path
|
||||
self.cue = cue.CueFile(path)
|
||||
self.cue.parse()
|
||||
@@ -50,7 +53,11 @@ class Image(object, log.Loggable):
|
||||
def getRealPath(self, path):
|
||||
"""
|
||||
Translate the .cue's FILE to an existing path.
|
||||
|
||||
@param path: .cue path
|
||||
"""
|
||||
assert type(path) is unicode, "%r is not unicode" % path
|
||||
|
||||
return self.cue.getRealPath(path)
|
||||
|
||||
def setup(self, runner):
|
||||
@@ -132,6 +139,11 @@ class AudioLengthTask(task.Task):
|
||||
length = None
|
||||
|
||||
def __init__(self, path):
|
||||
"""
|
||||
@type path: unicode
|
||||
"""
|
||||
assert type(path) is unicode, "%r is not unicode" % path
|
||||
|
||||
self._path = path
|
||||
|
||||
def start(self, runner):
|
||||
@@ -139,7 +151,7 @@ class AudioLengthTask(task.Task):
|
||||
self._pipeline = gst.parse_launch('''
|
||||
filesrc location="%s" !
|
||||
decodebin ! audio/x-raw-int !
|
||||
fakesink name=sink''' % self._path)
|
||||
fakesink name=sink''' % self._path.encode('utf-8'))
|
||||
self.debug('pausing')
|
||||
self._pipeline.set_state(gst.STATE_PAUSED)
|
||||
self._pipeline.get_state()
|
||||
@@ -152,12 +164,12 @@ class AudioLengthTask(task.Task):
|
||||
try:
|
||||
length, qformat = sink.query_duration(gst.FORMAT_DEFAULT)
|
||||
except gst.QueryError:
|
||||
print 'failed to query %s' % self._path
|
||||
print 'failed to query %r' % self._path
|
||||
# wavparse 0.10.14 returns in bytes
|
||||
if qformat == gst.FORMAT_BYTES:
|
||||
self.debug('query returned in BYTES format')
|
||||
length /= 4
|
||||
self.debug('total length of %s in samples: %d', self._path, length)
|
||||
self.debug('total length of %r in samples: %d', self._path, length)
|
||||
self.length = length
|
||||
self._pipeline.set_state(gst.STATE_NULL)
|
||||
|
||||
@@ -186,7 +198,8 @@ class ImageVerifyTask(task.MultiSeparateTask):
|
||||
|
||||
if length == -1:
|
||||
path = image.getRealPath(index.path)
|
||||
self.debug('schedule scan of audio length of %s', path)
|
||||
assert type(path) is unicode, "%r is not unicode" % path
|
||||
self.debug('schedule scan of audio length of %r', path)
|
||||
taskk = AudioLengthTask(path)
|
||||
self.addTask(taskk)
|
||||
self._tasks.append((trackIndex + 1, track, taskk))
|
||||
|
||||
@@ -26,6 +26,7 @@ Reading .toc files
|
||||
|
||||
import os
|
||||
import re
|
||||
import codecs
|
||||
|
||||
from morituri.common import common, log
|
||||
from morituri.image import table
|
||||
@@ -87,6 +88,10 @@ _INDEX_RE = re.compile(r"""
|
||||
|
||||
class TocFile(object, log.Loggable):
|
||||
def __init__(self, path):
|
||||
"""
|
||||
@type path: unicode
|
||||
"""
|
||||
assert type(path) is unicode, "%r is not unicode" % path
|
||||
self._path = path
|
||||
self._messages = []
|
||||
self.table = table.Table()
|
||||
@@ -113,7 +118,7 @@ class TocFile(object, log.Loggable):
|
||||
# the first track's INDEX 1 can only be gotten from the .toc
|
||||
# file once the first pregap is calculated; so we add INDEX 1
|
||||
# at the end of each parsed TRACK record
|
||||
handle = open(self._path, 'r')
|
||||
handle = codecs.open(self._path, "r", "utf-8")
|
||||
|
||||
for number, line in enumerate(handle.readlines()):
|
||||
line = line.rstrip()
|
||||
@@ -313,7 +318,11 @@ class TocFile(object, log.Loggable):
|
||||
def getRealPath(self, path):
|
||||
"""
|
||||
Translate the .cue's FILE to an existing path.
|
||||
|
||||
@type path: unicode
|
||||
"""
|
||||
assert type(path) is unicode, "%r is not unicode" % path
|
||||
|
||||
if os.path.exists(path):
|
||||
return path
|
||||
|
||||
@@ -339,16 +348,21 @@ class TocFile(object, log.Loggable):
|
||||
if os.path.exists(cpath):
|
||||
return cpath
|
||||
|
||||
raise KeyError, "Cannot find file for %s" % path
|
||||
raise KeyError, "Cannot find file for %r" % path
|
||||
|
||||
class File:
|
||||
"""
|
||||
I represent a FILE line in a .toc file.
|
||||
"""
|
||||
def __init__(self, path, start, length):
|
||||
"""
|
||||
@type path: unicode
|
||||
"""
|
||||
assert type(path) is unicode, "%r is not unicode" % path
|
||||
|
||||
self.path = path
|
||||
#self.start = start
|
||||
#self.length = length
|
||||
|
||||
def __repr__(self):
|
||||
return '<File "%s">' % (self.path, )
|
||||
return '<File %r>' % (self.path, )
|
||||
|
||||
@@ -12,7 +12,7 @@ from morituri.image import table, cue
|
||||
class KingsSingleTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.cue = cue.CueFile(os.path.join(os.path.dirname(__file__),
|
||||
'kings-single.cue'))
|
||||
u'kings-single.cue'))
|
||||
self.cue.parse()
|
||||
self.assertEquals(len(self.cue.table.tracks), 11)
|
||||
|
||||
@@ -26,7 +26,7 @@ class KingsSingleTestCase(unittest.TestCase):
|
||||
class KingsSeparateTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.cue = cue.CueFile(os.path.join(os.path.dirname(__file__),
|
||||
'kings-separate.cue'))
|
||||
u'kings-separate.cue'))
|
||||
self.cue.parse()
|
||||
self.assertEquals(len(self.cue.table.tracks), 11)
|
||||
|
||||
@@ -40,7 +40,7 @@ class KingsSeparateTestCase(unittest.TestCase):
|
||||
class KanyeMixedTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.cue = cue.CueFile(os.path.join(os.path.dirname(__file__),
|
||||
'kanye.cue'))
|
||||
u'kanye.cue'))
|
||||
self.cue.parse()
|
||||
self.assertEquals(len(self.cue.table.tracks), 13)
|
||||
|
||||
@@ -51,18 +51,19 @@ class KanyeMixedTestCase(unittest.TestCase):
|
||||
|
||||
class WriteCueFileTestCase(unittest.TestCase):
|
||||
def testWrite(self):
|
||||
fd, path = tempfile.mkstemp(suffix='morituri.test.cue')
|
||||
fd, path = tempfile.mkstemp(suffix=u'morituri.test.cue')
|
||||
os.close(fd)
|
||||
|
||||
it = table.Table()
|
||||
|
||||
t = table.Track(1)
|
||||
t.index(1, absolute=0, path='track01.wav', relative=0, counter=1)
|
||||
t.index(1, absolute=0, path=u'track01.wav', relative=0, counter=1)
|
||||
it.tracks.append(t)
|
||||
|
||||
t = table.Track(2)
|
||||
t.index(0, absolute=1000, path='track01.wav', relative=1000, counter=1)
|
||||
t.index(1, absolute=2000, path='track02.wav', relative=0, counter=2)
|
||||
t.index(0, absolute=1000, path=u'track01.wav',
|
||||
relative=1000, counter=1)
|
||||
t.index(1, absolute=2000, path=u'track02.wav', relative=0, counter=2)
|
||||
it.tracks.append(t)
|
||||
it.absolutize()
|
||||
it.leadout = 3000
|
||||
|
||||
@@ -12,7 +12,7 @@ from morituri.test import common
|
||||
class CureTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.toc = toc.TocFile(os.path.join(os.path.dirname(__file__),
|
||||
'cure.toc'))
|
||||
u'cure.toc'))
|
||||
self.toc.parse()
|
||||
self.assertEquals(len(self.toc.table.tracks), 13)
|
||||
|
||||
@@ -93,7 +93,7 @@ class CureTestCase(unittest.TestCase):
|
||||
class BlocTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.toc = toc.TocFile(os.path.join(os.path.dirname(__file__),
|
||||
'bloc.toc'))
|
||||
u'bloc.toc'))
|
||||
self.toc.parse()
|
||||
self.assertEquals(len(self.toc.table.tracks), 13)
|
||||
|
||||
@@ -140,7 +140,7 @@ class BlocTestCase(unittest.TestCase):
|
||||
class BreedersTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.toc = toc.TocFile(os.path.join(os.path.dirname(__file__),
|
||||
'breeders.toc'))
|
||||
u'breeders.toc'))
|
||||
self.toc.parse()
|
||||
self.assertEquals(len(self.toc.table.tracks), 13)
|
||||
|
||||
@@ -166,7 +166,7 @@ class BreedersTestCase(unittest.TestCase):
|
||||
class LadyhawkeTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.toc = toc.TocFile(os.path.join(os.path.dirname(__file__),
|
||||
'ladyhawke.toc'))
|
||||
u'ladyhawke.toc'))
|
||||
self.toc.parse()
|
||||
self.assertEquals(len(self.toc.table.tracks), 13)
|
||||
#import code; code.interact(local=locals())
|
||||
@@ -182,13 +182,13 @@ class LadyhawkeTestCase(unittest.TestCase):
|
||||
class CapitalMergeTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.toc1 = toc.TocFile(os.path.join(os.path.dirname(__file__),
|
||||
'capital.1.toc'))
|
||||
u'capital.1.toc'))
|
||||
self.toc1.parse()
|
||||
self.assertEquals(len(self.toc1.table.tracks), 11)
|
||||
self.failUnless(self.toc1.table.tracks[-1].audio)
|
||||
|
||||
self.toc2 = toc.TocFile(os.path.join(os.path.dirname(__file__),
|
||||
'capital.2.toc'))
|
||||
u'capital.2.toc'))
|
||||
self.toc2.parse()
|
||||
self.assertEquals(len(self.toc2.table.tracks), 1)
|
||||
self.failIf(self.toc2.table.tracks[-1].audio)
|
||||
|
||||
Reference in New Issue
Block a user