From d1c6448da89a8d5e2f02de062c58d9321952d3ae Mon Sep 17 00:00:00 2001 From: Adrian Sampson Date: Fri, 6 Aug 2010 09:55:21 -0700 Subject: [PATCH] album art paths now stored in blobs in database --- NEWS | 6 ++++-- beets/library.py | 23 ++++++++++++++++++++++- test/test_db.py | 7 +++++++ 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 19788abc5..1f7c52fc8 100644 --- a/NEWS +++ b/NEWS @@ -27,6 +27,10 @@ directory until it encounters the last one it saw. (This means it might fail if that album can't be found.) Also, you can now abort the tagging process by entering "B" (for aBort) at any of the prompts. +* Overhauled methods for handling fileystem paths to allow filenames + that have badly encoded special characters. These changes are pretty + fragile, so please report any bugs involving UnicodeErrors or SQLite + ProgrammingErrors with this version. * Fixed a bug where the CLI would fail completely if the LANG environment variable was not set. * Fixed removal of albums (beet remove -a): previously, the album @@ -35,8 +39,6 @@ Windows users can now just type "beet" at the prompt to run beets. * Fixed an occasional bug where Mutagen would complain that a tag was already present. -* Fixed some errors with filenames that have badly encoded special - characters. 1.0b3 ----- diff --git a/beets/library.py b/beets/library.py index abed45622..b892f406b 100644 --- a/beets/library.py +++ b/beets/library.py @@ -71,7 +71,7 @@ ITEM_KEYS = [f[0] for f in ITEM_FIELDS] # identically-named field in the items table. ALBUM_FIELDS = [ ('id', 'integer primary key', False), - ('artpath', 'text', False), + ('artpath', 'blob', False), ('artist', 'text', True), ('album', 'text', True), @@ -1040,20 +1040,41 @@ class Album(BaseAlbum): """Set the value of an album attribute.""" if key == 'id': raise AttributeError("can't modify album id") + elif key in ALBUM_KEYS: + # Make sure paths are bytestrings. + if key == 'artpath' and isinstance(value, unicode): + value = _bytestring_path(value) + # Reflect change in this object. self._record[key] = value + + # Store art path as a buffer. + if key == 'artpath' and isinstance(value, str): + value = buffer(value) + # Change album table. sql = 'UPDATE albums SET %s=? WHERE id=?' % key self._library.conn.execute(sql, (value, self.id)) + # Possibly make modification on items as well. if key in ALBUM_KEYS_ITEM: for item in self.items(): setattr(item, key, value) self._library.store(item) + else: object.__setattr__(self, key, value) + def __getattr__(self, key): + value = super(Album, self).__getattr__(key) + + # Unwrap art path from buffer object. + if key == 'artpath' and isinstance(value, buffer): + value = str(value) + + return value + def items(self): """Returns an iterable over the items associated with this album. diff --git a/test/test_db.py b/test/test_db.py index a7790d159..134cf6dfd 100644 --- a/test/test_db.py +++ b/test/test_db.py @@ -458,6 +458,13 @@ class PathStringTest(unittest.TestCase): dest = alb.art_destination(u'image.jpg') self.assert_(isinstance(dest, str)) + def test_artpath_stores_special_chars(self): + path = 'b\xe1r' + alb = self.lib.add_album([self.i]) + alb.artpath = path + alb = self.lib.get_album(self.i) + self.assertEqual(path, alb.artpath) + def suite(): return unittest.TestLoader().loadTestsFromName(__name__)