decode pathnames before formatting them (#232)

This commit is contained in:
Adrian Sampson 2011-11-13 10:10:19 -08:00
parent bfb8b443ff
commit 7e627c5e57
4 changed files with 89 additions and 3 deletions

4
beets/ui/commands.py Executable file → Normal file
View file

@ -29,7 +29,7 @@ from beets import autotag
import beets.autotag.art
from beets import plugins
from beets import importer
from beets.util import syspath, normpath, ancestry
from beets.util import syspath, normpath, ancestry, displayable_path
from beets import library
# Global logger.
@ -168,7 +168,7 @@ def show_change(cur_artist, cur_album, items, info, dist, color=True):
# Show filename (non-colorized) when title is not set.
if not item.title.strip():
cur_title = os.path.basename(item.path)
cur_title = displayable_path(os.path.basename(item.path))
if cur_title != new_title and cur_track != new_track:
print_(u" * %s (%s) -> %s (%s)" % (

View file

@ -150,9 +150,22 @@ def bytestring_path(path):
encoding = sys.getfilesystemencoding() or sys.getdefaultencoding()
try:
return path.encode(encoding)
except UnicodeError:
except (UnicodeError, LookupError):
return path.encode('utf8')
def displayable_path(path):
"""Attempts to decode a bytestring path to a unicode object for the
purpose of displaying it to the user.
"""
if isinstance(path, unicode):
return path
encoding = sys.getfilesystemencoding() or sys.getdefaultencoding()
try:
return path.decode(encoding, 'ignore')
except (UnicodeError, LookupError):
return path.decode('utf8', 'ignore')
def syspath(path, pathmod=None):
"""Convert a path for use by the operating system. In particular,
paths on Windows must receive a magic prefix and must be converted

View file

@ -19,6 +19,7 @@ Changelog
that looks like an MBID in the entered string. This means that full
MusicBrainz URLs now work as IDs at the prompt. (Thanks to derwin.)
* Fix a crash after using the "as Tracks" option during import.
* Fix a Unicode error when tagging items with missing titles.
.. _KraYmer: https://github.com/KraYmer
.. _Next Generation Schema: http://musicbrainz.org/doc/XML_Web_Service/Version_2

View file

@ -580,6 +580,78 @@ class ManualIDTest(unittest.TestCase):
out = commands.manual_id(False)
self.assertEqual(out, AN_ID)
class ShowChangeTest(unittest.TestCase):
def setUp(self):
self.io = _common.DummyIO()
self.io.install()
def tearDown(self):
self.io.restore()
def _items_and_info(self):
items = [_common.item()]
items[0].track = 1
items[0].path = '/path/to/file.mp3'
info = autotag.AlbumInfo(
'the album', 'album id', 'the artist', 'artist id', [
autotag.TrackInfo('the title', 'track id')
])
return items, info
def test_null_change(self):
items, info = self._items_and_info()
commands.show_change('the artist', 'the album',
items, info, 0.1, color=False)
msg = self.io.getoutput().lower()
self.assertTrue('similarity: 90' in msg)
self.assertTrue('tagging:' in msg)
def test_album_data_change(self):
items, info = self._items_and_info()
commands.show_change('another artist', 'another album',
items, info, 0.1, color=False)
msg = self.io.getoutput().lower()
self.assertTrue('correcting tags from:' in msg)
def test_item_data_change(self):
items, info = self._items_and_info()
items[0].title = 'different'
commands.show_change('the artist', 'the album',
items, info, 0.1, color=False)
msg = self.io.getoutput().lower()
self.assertTrue('different -> the title' in msg)
def test_item_data_change_with_unicode(self):
items, info = self._items_and_info()
items[0].title = u'caf\xe9'
commands.show_change('the artist', 'the album',
items, info, 0.1, color=False)
msg = self.io.getoutput().lower()
self.assertTrue(u'caf\xe9 -> the title' in msg.decode('utf8'))
def test_album_data_change_with_unicode(self):
items, info = self._items_and_info()
commands.show_change(u'caf\xe9', u'another album',
items, info, 0.1, color=False)
msg = self.io.getoutput().lower()
self.assertTrue('correcting tags from:' in msg)
def test_item_data_change_title_missing(self):
items, info = self._items_and_info()
items[0].title = ''
commands.show_change('the artist', 'the album',
items, info, 0.1, color=False)
msg = self.io.getoutput().lower()
self.assertTrue('file.mp3 -> the title' in msg)
def test_item_data_change_title_missing_with_unicode_filename(self):
items, info = self._items_and_info()
items[0].title = ''
items[0].path = u'/path/to/caf\xe9.mp3'.encode('utf8')
commands.show_change('the artist', 'the album',
items, info, 0.1, color=False)
msg = self.io.getoutput().lower()
self.assertTrue(u'caf\xe9.mp3 -> the title' in msg.decode('utf8'))
def suite():
return unittest.TestLoader().loadTestsFromName(__name__)