From 2c27b73d099b5a62ccae66c1d676a87d4e36ff47 Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Sun, 18 Sep 2011 15:19:45 +0000 Subject: [PATCH] * morituri/common/common.py: Add shrinkPath to write shorter path names. * morituri/test/test_common_common.py (added): Add test. * morituri/program/cdparanoia.py: Catch ENAMETOOLONG and shrink path. * morituri/common/program.py: Update track result's filename if it was shrunk. * morituri/rip/cd.py: set the possibly shrunk path on the result. --- ChangeLog | 13 ++++++++++++ morituri/common/common.py | 32 +++++++++++++++++++++++++++++ morituri/common/program.py | 7 +++++++ morituri/program/cdparanoia.py | 5 +++++ morituri/rip/cd.py | 8 ++++---- morituri/test/test_common_common.py | 17 +++++++++++++++ 6 files changed, 78 insertions(+), 4 deletions(-) create mode 100644 morituri/test/test_common_common.py diff --git a/ChangeLog b/ChangeLog index b2dc742..b58f12c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2011-09-18 Thomas Vander Stichele + + * morituri/common/common.py: + Add shrinkPath to write shorter path names. + * morituri/test/test_common_common.py (added): + Add test. + * morituri/program/cdparanoia.py: + Catch ENAMETOOLONG and shrink path. + * morituri/common/program.py: + Update track result's filename if it was shrunk. + * morituri/rip/cd.py: + set the possibly shrunk path on the result. + 2011-09-18 Thomas Vander Stichele * morituri/program/cdparanoia.py: diff --git a/morituri/common/common.py b/morituri/common/common.py index 406df96..e28f214 100644 --- a/morituri/common/common.py +++ b/morituri/common/common.py @@ -21,6 +21,7 @@ # along with morituri. If not, see . import os +import math import tempfile import shutil @@ -254,3 +255,34 @@ class MissingDependencyException(Exception): class EmptyError(Exception): pass + +def shrinkPath(path): + """ + Shrink a full path to a shorter version. + Used to handle ENAMETOOLONG + """ + parts = list(os.path.split(path)) + length = len(parts[-1]) + target = 127 + if length <= target: + target = pow(2, int(math.log(length, 2))) - 1 + + name, ext = os.path.splitext(parts[-1]) + target -= len(ext) + 1 + + # split on space, then reassemble + words = name.split(' ') + length = 0 + pieces = [] + for word in words: + if length + 1 + len(word) <= target: + pieces.append(word) + length += 1 + len(word) + else: + break + + name = " ".join(pieces) + # ext includes period + parts[-1] = u'%s%s' % (name, ext) + path = os.path.join(*parts) + return path diff --git a/morituri/common/program.py b/morituri/common/program.py index 8ca2a2e..ed2b6f5 100644 --- a/morituri/common/program.py +++ b/morituri/common/program.py @@ -550,6 +550,9 @@ class Program(log.Loggable): def ripTrack(self, runner, trackResult, offset, device, profile, taglist, what=None): """ + Ripping the track may change the track's filename as stored in + trackResult. + @param trackResult: the object to store information in. @type trackResult: L{result.TrackResult} @param number: track number (1-based) @@ -583,6 +586,10 @@ class Program(log.Loggable): trackResult.peak = t.peak trackResult.quality = t.quality + if trackResult.filename != t.path: + trackResult.filename = t.path + self.info('Filename changed to %r', trackResult.filename) + def retagImage(self, runner, taglists): cueImage = image.Image(self.cuePath) t = image.ImageRetagTask(cueImage, taglists) diff --git a/morituri/program/cdparanoia.py b/morituri/program/cdparanoia.py index 56579b0..3a0767a 100644 --- a/morituri/program/cdparanoia.py +++ b/morituri/program/cdparanoia.py @@ -21,6 +21,7 @@ # along with morituri. If not, see . import os +import errno import re import stat import shutil @@ -478,6 +479,10 @@ class ReadVerifyTrackTask(log.Loggable, task.MultiSeparateTask): try: self.debug('Moving to final path %r', self.path) shutil.move(self._tmppath, self.path) + except IOError, e: + if e.errno == errno.ENAMETOOLONG: + self.path = common.shrinkPath(self.path) + shutil.move(self._tmppath, self.path) except Exception, e: self.debug('Exception while moving to final path %r: %r', self.path, log.getExceptionMessage(e)) diff --git a/morituri/rip/cd.py b/morituri/rip/cd.py index d4b67ab..4b9576f 100644 --- a/morituri/rip/cd.py +++ b/morituri/rip/cd.py @@ -244,11 +244,11 @@ See http://sourceforge.net/tracker/?func=detail&aid=604751&group_id=2171&atid=1 # overlay this rip onto the Table if number == 0: # HTOA goes on index 0 of track 1 - itable.setFile(1, 0, path, ittoc.getTrackStart(1), - number) + itable.setFile(1, 0, trackResult.filename, + ittoc.getTrackStart(1), number) else: - itable.setFile(number, 1, path, ittoc.getTrackLength(number), - number) + itable.setFile(number, 1, trackResult.filename, + ittoc.getTrackLength(number), number) prog.saveRipResult() diff --git a/morituri/test/test_common_common.py b/morituri/test/test_common_common.py new file mode 100644 index 0000000..a05dce4 --- /dev/null +++ b/morituri/test/test_common_common.py @@ -0,0 +1,17 @@ +# -*- Mode: Python; test-case-name: morituri.test.test_common_common -*- +# vi:si:et:sw=4:sts=4:ts=4 + +import os + +from morituri.common import common + +from morituri.test import common as tcommon + +class ShrinkTestCase(tcommon.TestCase): + def testSufjan(self): + path = u'morituri/Sufjan Stevens - Illinois/02. Sufjan Stevens - The Black Hawk War, or, How to Demolish an Entire Civilization and Still Feel Good About Yourself in the Morning, or, We Apologize for the Inconvenience but You\'re Going to Have to Leave Now, or, "I Have Fought the Big Knives and Will Continue to Fight Them Until They Are Off Our Lands!".flac' + + shorter = common.shrinkPath(path) + self.failUnless(os.path.splitext(path)[0].startswith( + os.path.splitext(shorter)[0])) + self.failIfEquals(path, shorter)