* 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:
Thomas Vander Stichele
2009-09-11 15:37:02 +00:00
parent ac9d8f194d
commit 9a15e890e0
6 changed files with 79 additions and 25 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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