basic album information access through proxy object

This commit is contained in:
Adrian Sampson 2010-07-13 18:01:14 -07:00
parent 84f5577121
commit bdbabe91da
2 changed files with 66 additions and 2 deletions

View file

@ -69,6 +69,7 @@ ALBUM_FIELDS = [
('album', 'text'),
('artpath', 'text'),
]
ALBUM_KEYS = [f[0] for f in ALBUM_FIELDS]
# Default search fields for various granularities.
ARTIST_DEFAULT_FIELDS = ('artist',)
@ -206,8 +207,7 @@ class Item(object):
def __getattr__(self, key):
"""If key is an item attribute (i.e., a column in the database),
returns the record entry for that key. Otherwise, performs an
ordinary getattr.
returns the record entry for that key.
"""
if key in ITEM_KEYS:
return self.record[key]
@ -528,6 +528,31 @@ class ResultIterator(object):
return Item(row)
# Album information proxy objects.
class AlbumInfo(object):
"""Provides access to information about albums stored in a library.
"""
def __init__(self, library, album, artist):
self._library = library
self._album = album
self._artist = artist
def __getattr__(self, key):
"""Get an album field's value."""
if key in ALBUM_KEYS:
return self._library._album_get(self._album, self._artist, key)
else:
return getattr(self, key)
def __setattr__(self, key, value):
"""Set an album field."""
if key in ALBUM_KEYS:
self._library._album_set(self._album, self._artist, key, value)
else:
super(AlbumInfo, self).__setattr__(key, value)
# An abstract library.
class BaseLibrary(object):
@ -651,6 +676,28 @@ class BaseLibrary(object):
return sorted(out, compare)
# Album information.
# Provides access to information about items at an album
# granularity. AlbumInfo proxy objects are used to access fields;
# they invoke _album_get and _album_set.
def albuminfo(self, artist, album):
"""Given an artist and album name, return an AlbumInfo proxy
object whose attributes correspond to information about the
album.
"""
return AlbumInfo(self, artist, album)
def _album_get(self, artist, album, key):
"""For the album specified, returns the value associated with
the key."""
raise NotImplementedError()
def _album_set(self, artist, album, key, value):
"""Sets the indicated album's value for key."""
raise NotImplementedError()
# Concrete DB-backed library.
class Library(BaseLibrary):

View file

@ -321,6 +321,23 @@ class MigrationTest(unittest.TestCase):
except sqlite3.OperationalError:
self.fail("select failed")
class AlbumInfoTest(unittest.TestCase):
def setUp(self):
self.lib = beets.library.Library(':memory:')
self.i = item()
self.lib.add(self.i)
def test_albuminfo_reflects_metadata(self):
ai = self.lib.albuminfo(self.i.artist, self.i.album)
self.assertEqual(ai.artist, self.i.artist)
self.assertEqual(ai.album, self.i.album)
def test_albuminfo_stores_art(self):
ai = self.lib.albuminfo(self.i.artist, self.i.album)
ai.artpath = '/my/great/art'
new_ai = self.lib.albuminfo(self.i.artist, self.i.album)
self.assertEqual(new_ai.artpath, '/my/great/art')
def suite():
return unittest.TestLoader().loadTestsFromName(__name__)