apply jonathan.buchanan's compilation patch from issue #48

This commit is contained in:
Adrian Sampson 2011-01-23 18:41:35 -08:00
parent 3bfae3b78c
commit 342c360285
10 changed files with 303 additions and 107 deletions

View file

@ -20,6 +20,7 @@ from collections import defaultdict
from beets.autotag import mb
import re
from munkres import Munkres
from musicbrainz2.model import VARIOUS_ARTISTS_ID
from beets import library, mediafile, plugins
import logging
@ -72,6 +73,8 @@ SD_PATTERNS = [
(r'(, )?(pt\.|part) .+', 0.2),
]
VARIOUS_ARTISTS_ID = VARIOUS_ARTISTS_ID.rsplit('/', 1)[1]
# Autotagging exceptions.
class AutotagError(Exception):
pass
@ -350,9 +353,13 @@ def apply_metadata(items, info):
"""Set the items' metadata to match the data given in info. The
list of items must be ordered.
"""
for index, (item, track_data) in enumerate(zip(items, info['tracks'])):
for index, (item, track_data) in enumerate(zip(items, info['tracks'])):
# Album, artist, track count.
item.artist = info['artist']
if 'artist' in track_data:
item.artist = track_data['artist']
else:
item.artist = info['artist']
item.album_artist = info['artist']
item.album = info['album']
item.tracktotal = len(items)
@ -371,7 +378,15 @@ def apply_metadata(items, info):
# MusicBrainz IDs.
item.mb_trackid = track_data['id']
item.mb_albumid = info['album_id']
item.mb_artistid = info['artist_id']
if 'artist_id' in track_data:
item.mb_artistid = track_data['artist_id']
else:
item.mb_artistid = info['artist_id']
item.mb_albumartistid = info['artist_id']
item.mb_albumtype = info['albumtype']
# Compilation flag.
item.comp = (info['artist_id'] == VARIOUS_ARTISTS_ID)
def match_by_id(items):
"""If the items are tagged with a MusicBrainz album ID, returns an

View file

@ -25,6 +25,7 @@ import re
import time
import datetime
import musicbrainz2.webservice as mbws
from musicbrainz2.model import Release
from threading import Lock
SEARCH_LIMIT = 10
@ -36,6 +37,20 @@ SPECIAL_CASE_ARTISTS = {
'!!!': 'f26c72d3-e52c-467b-b651-679c73d8e1a7',
}
RELEASE_TYPES = [
Release.TYPE_ALBUM,
Release.TYPE_SINGLE,
Release.TYPE_EP,
Release.TYPE_COMPILATION,
Release.TYPE_SOUNDTRACK,
Release.TYPE_SPOKENWORD,
Release.TYPE_INTERVIEW,
Release.TYPE_AUDIOBOOK,
Release.TYPE_LIVE,
Release.TYPE_REMIX,
Release.TYPE_OTHER
]
# MusicBrainz requires that a client does not query the server more
# than once a second. This function enforces that limit using a
# module-global variable to keep track of the last time a query was
@ -153,8 +168,15 @@ def release_dict(release, tracks=None):
'artist': release.artist.name,
'artist_id': release.artist.id.rsplit('/', 1)[1],
'asin': release.asin,
'albumtype': '',
}
# Release type not always populated.
for type in release.types:
if type in RELEASE_TYPES:
out['albumtype'] = type.split('#')[1].lower()
break
# Release date.
try:
date_str = release.getEarliestReleaseDate()
@ -176,6 +198,11 @@ def release_dict(release, tracks=None):
for track in tracks:
t = {'title': track.title,
'id': track.id.rsplit('/', 1)[1]}
if track.artist is not None:
# Track artists will only be present for releases with
# multiple artists.
t['artist'] = track.artist.name
t['artist_id'] = track.artist.id.rsplit('/', 1)[1]
if track.duration is not None:
# Duration not always present.
t['length'] = track.duration/(1000.0)

View file

@ -38,26 +38,29 @@ ITEM_FIELDS = [
('path', 'blob', False, False),
('album_id', 'int', False, False),
('title', 'text', True, True),
('artist', 'text', True, True),
('album', 'text', True, True),
('genre', 'text', True, True),
('composer', 'text', True, True),
('grouping', 'text', True, True),
('year', 'int', True, True),
('month', 'int', True, True),
('day', 'int', True, True),
('track', 'int', True, True),
('tracktotal', 'int', True, True),
('disc', 'int', True, True),
('disctotal', 'int', True, True),
('lyrics', 'text', True, True),
('comments', 'text', True, True),
('bpm', 'int', True, True),
('comp', 'bool', True, True),
('mb_trackid', 'text', True, True),
('mb_albumid', 'text', True, True),
('mb_artistid', 'text', True, True),
('title', 'text', True, True),
('artist', 'text', True, True),
('album', 'text', True, True),
('album_artist', 'text', True, True),
('genre', 'text', True, True),
('composer', 'text', True, True),
('grouping', 'text', True, True),
('year', 'int', True, True),
('month', 'int', True, True),
('day', 'int', True, True),
('track', 'int', True, True),
('tracktotal', 'int', True, True),
('disc', 'int', True, True),
('disctotal', 'int', True, True),
('lyrics', 'text', True, True),
('comments', 'text', True, True),
('bpm', 'int', True, True),
('comp', 'bool', True, True),
('mb_trackid', 'text', True, True),
('mb_albumid', 'text', True, True),
('mb_artistid', 'text', True, True),
('mb_albumartistid', 'text', True, True),
('mb_albumtype', 'text', True, True),
('length', 'real', False, True),
('bitrate', 'int', False, True),
@ -68,31 +71,38 @@ ITEM_KEYS_META = [f[0] for f in ITEM_FIELDS if f[3]]
ITEM_KEYS = [f[0] for f in ITEM_FIELDS]
# Database fields for the "albums" table.
# The third entry in each tuple indicates whether the field reflects an
# identically-named field in the items table.
# The third entry in each tuple indicates whether the field reflects a
# field in the items table.
ALBUM_FIELDS = [
('id', 'integer primary key', False),
('artpath', 'blob', False),
('id', 'integer primary key', False),
('artpath', 'blob', False),
('artist', 'text', True),
('album', 'text', True),
('genre', 'text', True),
('year', 'int', True),
('month', 'int', True),
('day', 'int', True),
('tracktotal', 'int', True),
('disctotal', 'int', True),
('comp', 'bool', True),
('mb_albumid', 'text', True),
('mb_artistid', 'text', True),
('artist', 'text', True),
('album', 'text', True),
('genre', 'text', True),
('year', 'int', True),
('month', 'int', True),
('day', 'int', True),
('tracktotal', 'int', True),
('disctotal', 'int', True),
('comp', 'bool', True),
('mb_albumid', 'text', True),
('mb_artistid', 'text', True),
('mb_albumtype', 'text', True),
]
ALBUM_KEYS = [f[0] for f in ALBUM_FIELDS]
ALBUM_KEYS_ITEM = [f[0] for f in ALBUM_FIELDS if f[2]]
# Mapping between album field names and item field names, where they
# differ.
ALBUM_KEYS_ITEM_MAP = {
'artist': 'album_artist',
'mb_artistid': 'mb_albumartistid',
}
# Default search fields for various granularities.
ARTIST_DEFAULT_FIELDS = ('artist',)
ALBUM_DEFAULT_FIELDS = ARTIST_DEFAULT_FIELDS + ('album', 'genre')
ITEM_DEFAULT_FIELDS = ALBUM_DEFAULT_FIELDS + ('title', 'comments')
ITEM_DEFAULT_FIELDS = ALBUM_DEFAULT_FIELDS + ('album_artist', 'title', 'comments')
# Logger.
log = logging.getLogger('beets')
@ -708,7 +718,7 @@ class BaseLibrary(object):
item = specimens[k]
record = {}
for key in ALBUM_KEYS_ITEM:
record[key] = getattr(item, key)
record[key] = getattr(item, ALBUM_KEYS_ITEM_MAP.get(key, key))
yield BaseAlbum(self, record)
def items(self, artist=None, album=None, title=None, query=None):
@ -762,10 +772,10 @@ class BaseAlbum(object):
self._record[key] = value
# Modify items.
if key in ALBUM_KEYS_ITEM:
items = self._library.items(artist=self.artist,
items = self._library.items(album_artist=self.artist,
album=self.album)
for item in items:
setattr(item, key, value)
setattr(item, ALBUM_KEYS_ITEM_MAP.get(key, key), value)
self._library.store(item)
else:
object.__setattr__(self, key, value)
@ -776,7 +786,7 @@ class BaseAlbum(object):
items = self._library.items(artist=self.artist, album=self.album)
item = iter(items).next()
for key in ALBUM_KEYS_ITEM:
self._record[key] = getattr(item, key)
self._record[key] = getattr(item, ALBUM_KEYS_ITEM_MAP.get(key, key))
# Concrete DB-backed library.
@ -785,13 +795,17 @@ class Library(BaseLibrary):
"""A music library using an SQLite database as a metadata store."""
def __init__(self, path='library.blb',
directory='~/Music',
path_format='$artist/$album/$track $title',
path_formats=None,
art_filename='cover',
item_fields=ITEM_FIELDS,
album_fields=ALBUM_FIELDS):
self.path = _bytestring_path(path)
self.directory = _bytestring_path(directory)
self.path_format = path_format
if path_formats is None:
path_formats = {'default': '$artist/$album/$track $title'}
elif isinstance(path_formats, basestring):
path_formats = {'default': path_formats}
self.path_formats = path_formats
self.art_filename = _bytestring_path(art_filename)
self.conn = sqlite3.connect(self.path)
@ -836,13 +850,34 @@ class Library(BaseLibrary):
self.conn.executescript(setup_sql)
self.conn.commit()
def _sanitize_for_path(self, value, pathmod, key=None):
"""Sanitize the value for inclusion in a path: replace separators
with _, etc.
"""
if isinstance(value, basestring):
for sep in (pathmod.sep, pathmod.altsep):
if sep:
value = value.replace(sep, '_')
elif key in ('track', 'tracktotal', 'disc', 'disctotal'):
# pad with zeros
value = '%02i' % value
else:
value = str(value)
return value
def destination(self, item, pathmod=None):
"""Returns the path in the library directory designated for item
item (i.e., where the file ought to be).
"""
pathmod = pathmod or os.path
subpath_tmpl = Template(self.path_format)
# Use a path format based on the album type, if available.
if item.comp and 'comp' in self.path_formats:
path_format = self.path_formats['comp']
else:
path_format = self.path_formats['default']
subpath_tmpl = Template(path_format)
# Get the item's Album if it has one.
album = self.get_album(item)
@ -858,19 +893,11 @@ class Library(BaseLibrary):
else:
# From Item.
value = getattr(item, key)
# Sanitize the value for inclusion in a path: replace
# separators with _, etc.
if isinstance(value, basestring):
for sep in (pathmod.sep, pathmod.altsep):
if sep:
value = value.replace(sep, '_')
elif key in ('track', 'tracktotal', 'disc', 'disctotal'):
# pad with zeros
value = '%02i' % value
else:
value = str(value)
mapping[key] = value
mapping[key] = self._sanitize_for_path(value, pathmod, key)
# Use the track's artist if it differs
if album is not None and item.artist != album.artist:
mapping['artist'] = self._sanitize_for_path(item.artist, pathmod)
# Perform substitution.
subpath = subpath_tmpl.substitute(mapping)
@ -1058,7 +1085,8 @@ class Library(BaseLibrary):
sql = 'INSERT INTO albums (%s) VALUES (%s)' % \
(', '.join(ALBUM_KEYS_ITEM),
', '.join(['?'] * len(ALBUM_KEYS_ITEM)))
subvals = [getattr(items[0], key) for key in ALBUM_KEYS_ITEM]
subvals = [getattr(items[0], ALBUM_KEYS_ITEM_MAP.get(key, key))
for key in ALBUM_KEYS_ITEM]
c = self.conn.execute(sql, subvals)
album_id = c.lastrowid
@ -1066,7 +1094,8 @@ class Library(BaseLibrary):
record = {}
for key in ALBUM_KEYS:
if key in ALBUM_KEYS_ITEM:
record[key] = getattr(items[0], key)
record[key] = getattr(items[0],
ALBUM_KEYS_ITEM_MAP.get(key, key))
else:
# Non-item fields default to None.
record[key] = None
@ -1118,7 +1147,7 @@ class Album(BaseAlbum):
# Possibly make modification on items as well.
if key in ALBUM_KEYS_ITEM:
for item in self.items():
setattr(item, key, value)
setattr(item, ALBUM_KEYS_ITEM_MAP.get(key, key), value)
self._library.store(item)
else:

View file

@ -657,8 +657,17 @@ class MediaFile(object):
as_type = bool),
etc = StorageStyle('compilation')
)
# MusicBrainz IDs.
# Album Artist
album_artist = MediaField(
mp3 = StorageStyle('TXXX', id3_desc='Album Artist'),
mp4 = StorageStyle(
'----:com.apple.iTunes:Album Artist',
as_type=str),
etc = StorageStyle('album_artist')
)
# MusicBrainz fields
mb_trackid = MediaField(
mp3 = StorageStyle('UFID:http://musicbrainz.org',
list_elem = False),
@ -673,14 +682,28 @@ class MediaFile(object):
'----:com.apple.iTunes:MusicBrainz Album Id',
as_type=str),
etc = StorageStyle('musicbrainz_albumid')
)
)
mb_artistid = MediaField(
mp3 = StorageStyle('TXXX', id3_desc='MusicBrainz Artist Id'),
mp4 = StorageStyle(
'----:com.apple.iTunes:MusicBrainz Artist Id',
as_type=str),
etc = StorageStyle('musicbrainz_artistid')
)
)
mb_albumartistid = MediaField(
mp3 = StorageStyle('TXXX', id3_desc='MusicBrainz Album Artist Id'),
mp4 = StorageStyle(
'----:com.apple.iTunes:MusicBrainz Album Artist Id',
as_type=str),
etc = StorageStyle('musicbrainz_albumartistid')
)
mb_albumtype = MediaField(
mp3 = StorageStyle('TXXX', id3_desc='MusicBrainz Album Type'),
mp4 = StorageStyle(
'----:com.apple.iTunes:MusicBrainz Album Type',
as_type=str),
etc = StorageStyle('musicbrainz_albumtype')
)
@property
def length(self):

View file

@ -436,13 +436,20 @@ def main():
config_val(config, 'beets', 'library', DEFAULT_LIBRARY)
directory = options.directory or \
config_val(config, 'beets', 'directory', DEFAULT_DIRECTORY)
path_format = options.path_format or \
config_val(config, 'beets', 'path_format', DEFAULT_PATH_FORMAT)
if options.path_format:
# If given, -p overrides all path format settings
path_formats = {'default': options.path_format}
else:
path_formats = {
'default': config_val(config, 'beets', 'path_format', DEFAULT_PATH_FORMAT)
}
if config.has_section('paths'):
path_formats.update(config.items('paths'))
art_filename = \
config_val(config, 'beets', 'art_filename', DEFAULT_ART_FILENAME)
lib = library.Library(os.path.expanduser(libpath),
directory,
path_format,
path_formats,
art_filename)
# Configure the logger.

View file

@ -265,7 +265,7 @@ def _reopen_lib(lib):
return library.Library(
lib.path,
lib.directory,
lib.path_format,
lib.path_formats,
lib.art_filename,
)
else:
@ -482,7 +482,7 @@ def apply_choices(lib, copy, write, art, delete):
artpath = beets.autotag.art.art_for_album(info)
if artpath:
albuminfo.set_art(artpath)
# Write the database after each album.
lib.save()

View file

@ -203,6 +203,7 @@ class ApplyTest(unittest.TestCase):
'album': 'albumNew',
'album_id': '7edb51cb-77d6-4416-a23c-3a8c2994a2c7',
'artist_id': 'a6623d39-2d8e-4f70-8242-0a9553b91e50',
'albumtype': 'album',
}
def test_titles_applied(self):
@ -242,6 +243,87 @@ class ApplyTest(unittest.TestCase):
self.assertEqual(item.mb_artistid,
'a6623d39-2d8e-4f70-8242-0a9553b91e50')
def test_comp_flag(self):
autotag.apply_metadata(self.items, self.info)
self.assertEqual(self.items[0].mb_albumtype, 'album')
self.assertEqual(self.items[1].mb_albumtype, 'album')
self.assertFalse(self.items[0].comp)
self.assertFalse(self.items[1].comp)
class ApplyCompilationTest(unittest.TestCase):
def setUp(self):
self.items = []
self.items.append(Item({}))
self.items.append(Item({}))
trackinfo = []
trackinfo.append({
'title': 'oneNew',
'id': 'dfa939ec-118c-4d0f-84a0-60f3d1e6522c',
'artist': 'artistOneNew',
'artist_id': 'a05686fc-9db2-4c23-b99e-77f5db3e5282',
})
trackinfo.append({
'title': 'twoNew',
'id': '40130ed1-a27c-42fd-a328-1ebefb6caef4',
'artist': 'artistTwoNew',
'artist_id': '80b3cf5e-18fe-4c59-98c7-e5bb87210710',
})
self.info = {
'tracks': trackinfo,
'artist': 'variousNew',
'album': 'albumNew',
'album_id': '3b69ea40-39b8-487f-8818-04b6eff8c21a',
'artist_id': '89ad4ac3-39f7-470e-963a-56509c546377',
'albumtype': 'compilation',
}
def test_titles_applied(self):
autotag.apply_metadata(self.items, self.info)
self.assertEqual(self.items[0].title, 'oneNew')
self.assertEqual(self.items[1].title, 'twoNew')
def test_album_and_artist_applied_to_all(self):
autotag.apply_metadata(self.items, self.info)
self.assertEqual(self.items[0].album, 'albumNew')
self.assertEqual(self.items[1].album, 'albumNew')
self.assertEqual(self.items[0].album_artist, 'variousNew')
self.assertEqual(self.items[1].album_artist, 'variousNew')
self.assertEqual(self.items[0].artist, 'artistOneNew')
self.assertEqual(self.items[1].artist, 'artistTwoNew')
def test_track_index_applied(self):
autotag.apply_metadata(self.items, self.info)
self.assertEqual(self.items[0].track, 1)
self.assertEqual(self.items[1].track, 2)
def test_track_total_applied(self):
autotag.apply_metadata(self.items, self.info)
self.assertEqual(self.items[0].tracktotal, 2)
self.assertEqual(self.items[1].tracktotal, 2)
def test_mb_trackid_applied(self):
autotag.apply_metadata(self.items, self.info)
self.assertEqual(self.items[0].mb_trackid,
'dfa939ec-118c-4d0f-84a0-60f3d1e6522c')
self.assertEqual(self.items[1].mb_trackid,
'40130ed1-a27c-42fd-a328-1ebefb6caef4')
def test_mb_albumid_and_artistid_applied(self):
autotag.apply_metadata(self.items, self.info)
self.assertEqual(self.items[0].mb_albumid, '3b69ea40-39b8-487f-8818-04b6eff8c21a')
self.assertEqual(self.items[1].mb_albumid, '3b69ea40-39b8-487f-8818-04b6eff8c21a')
self.assertEqual(self.items[0].mb_albumartistid, '89ad4ac3-39f7-470e-963a-56509c546377')
self.assertEqual(self.items[1].mb_albumartistid, '89ad4ac3-39f7-470e-963a-56509c546377')
self.assertEqual(self.items[0].mb_artistid, 'a05686fc-9db2-4c23-b99e-77f5db3e5282')
self.assertEqual(self.items[1].mb_artistid, '80b3cf5e-18fe-4c59-98c7-e5bb87210710')
def test_comp_flag(self):
autotag.apply_metadata(self.items, self.info)
self.assertEqual(self.items[0].mb_albumtype, 'compilation')
self.assertEqual(self.items[1].mb_albumtype, 'compilation')
self.assertTrue(self.items[0].comp)
self.assertTrue(self.items[1].comp)
class StringDistanceTest(unittest.TestCase):
def test_equal_strings(self):
dist = autotag.string_dist('Some String', 'Some String')

View file

@ -28,31 +28,33 @@ def lib(): return beets.library.Library('rsrc' + os.sep + 'test.blb')
def boracay(l): return beets.library.Item(l.conn.execute('select * from items '
'where id=3').fetchone())
def item(): return beets.library.Item({
'title': u'the title',
'artist': u'the artist',
'album': u'the album',
'genre': u'the genre',
'composer': u'the composer',
'grouping': u'the grouping',
'year': 1,
'month': 2,
'day': 3,
'track': 4,
'tracktotal': 5,
'disc': 6,
'disctotal': 7,
'lyrics': u'the lyrics',
'comments': u'the comments',
'bpm': 8,
'comp': True,
'path': 'somepath',
'length': 60.0,
'bitrate': 128000,
'format': 'FLAC',
'mb_trackid': 'someID-1',
'mb_albumid': 'someID-2',
'mb_artistid': 'someID-3',
'album_id': None,
'title': u'the title',
'artist': u'the artist',
'album_artist': u'the album artist',
'album': u'the album',
'genre': u'the genre',
'composer': u'the composer',
'grouping': u'the grouping',
'year': 1,
'month': 2,
'day': 3,
'track': 4,
'tracktotal': 5,
'disc': 6,
'disctotal': 7,
'lyrics': u'the lyrics',
'comments': u'the comments',
'bpm': 8,
'comp': True,
'path': 'somepath',
'length': 60.0,
'bitrate': 128000,
'format': 'FLAC',
'mb_trackid': 'someID-1',
'mb_albumid': 'someID-2',
'mb_artistid': 'someID-3',
'mb_albumartistid': 'someID-4',
'album_id': None,
})
np = beets.library._normpath
@ -161,17 +163,17 @@ class DestinationTest(unittest.TestCase):
def test_directory_works_with_trailing_slash(self):
self.lib.directory = 'one/'
self.lib.path_format = 'two'
self.lib.path_formats = {'default': 'two'}
self.assertEqual(self.lib.destination(self.i), np('one/two'))
def test_directory_works_without_trailing_slash(self):
self.lib.directory = 'one'
self.lib.path_format = 'two'
self.lib.path_formats = {'default': 'two'}
self.assertEqual(self.lib.destination(self.i), np('one/two'))
def test_destination_substitues_metadata_values(self):
self.lib.directory = 'base'
self.lib.path_format = '$album/$artist $title'
self.lib.path_formats = {'default': '$album/$artist $title'}
self.i.title = 'three'
self.i.artist = 'two'
self.i.album = 'one'
@ -180,15 +182,15 @@ class DestinationTest(unittest.TestCase):
def test_destination_preserves_extension(self):
self.lib.directory = 'base'
self.lib.path_format = '$title'
self.lib.path_formats = {'default': '$title'}
self.i.path = 'hey.audioFormat'
self.assertEqual(self.lib.destination(self.i),
np('base/the title.audioFormat'))
def test_destination_pads_some_indices(self):
self.lib.directory = 'base'
self.lib.path_format = '$track $tracktotal ' \
'$disc $disctotal $bpm $year'
self.lib.path_formats = {'default': '$track $tracktotal ' \
'$disc $disctotal $bpm $year'}
self.i.track = 1
self.i.tracktotal = 2
self.i.disc = 3
@ -260,7 +262,7 @@ class DestinationTest(unittest.TestCase):
self.assertEqual(p, u'-')
def test_path_with_format(self):
self.lib.path_format = '$artist/$album ($format)'
self.lib.path_formats = {'default': '$artist/$album ($format)'}
p = self.lib.destination(self.i)
self.assert_('(FLAC)' in p)
@ -268,9 +270,16 @@ class DestinationTest(unittest.TestCase):
i1, i2 = item(), item()
self.lib.add_album([i1, i2])
i1.year, i2.year = 2009, 2010
self.lib.path_format = '$album ($year)/$track $title'
self.lib.path_formats = {'default': '$album ($year)/$track $title'}
dest1, dest2 = self.lib.destination(i1), self.lib.destination(i2)
self.assertEqual(os.path.dirname(dest1), os.path.dirname(dest2))
def test_comp_path(self):
self.i.comp = True
self.lib.directory = 'one'
self.lib.path_formats = {'default': 'two',
'comp': 'three'}
self.assertEqual(self.lib.destination(self.i), np('one/three'))
def test_syspath_windows_format(self):
path = ntpath.join('a', 'b', 'c')
@ -370,7 +379,8 @@ class AlbumInfoTest(unittest.TestCase):
def test_albuminfo_reflects_metadata(self):
ai = self.lib.get_album(self.i)
self.assertEqual(ai.artist, self.i.artist)
self.assertEqual(ai.mb_artistid, self.i.mb_albumartistid)
self.assertEqual(ai.artist, self.i.album_artist)
self.assertEqual(ai.album, self.i.album)
self.assertEqual(ai.year, self.i.year)
@ -523,7 +533,6 @@ class PathStringTest(unittest.TestCase):
alb = self.lib.get_album(alb.id)
self.assert_(isinstance(alb.artpath, str))
def suite():
return unittest.TestLoader().loadTestsFromName(__name__)

View file

@ -42,7 +42,7 @@ class MoveTest(unittest.TestCase):
# set up the destination
self.libdir = join('rsrc', 'testlibdir')
self.lib.directory = self.libdir
self.lib.path_format = join('$artist', '$album', '$title')
self.lib.path_formats = {'default': join('$artist', '$album', '$title')}
self.i.artist = 'one'
self.i.album = 'two'
self.i.title = 'three'
@ -129,6 +129,7 @@ class AlbumFileTest(unittest.TestCase):
def setUp(self):
# Make library and item.
self.lib = beets.library.Library(':memory:')
self.lib.path_formats = {'default': join('$album_artist', '$album', '$title')}
self.libdir = os.path.join('rsrc', 'testlibdir')
self.lib.directory = self.libdir
self.i = item()

View file

@ -60,6 +60,8 @@ class MBReleaseDictTest(unittest.TestCase):
release = musicbrainz2.model.Release()
release.title = 'ALBUM TITLE'
release.id = 'domain/ALBUM ID'
release.addType(musicbrainz2.model.Release.TYPE_ALBUM)
release.addType(musicbrainz2.model.Release.TYPE_OFFICIAL)
release.artist = musicbrainz2.model.Artist()
release.artist.name = 'ARTIST NAME'
release.artist.id = 'domain/ARTIST ID'
@ -84,6 +86,7 @@ class MBReleaseDictTest(unittest.TestCase):
d = mb.release_dict(release)
self.assertEqual(d['album'], 'ALBUM TITLE')
self.assertEqual(d['album_id'], 'ALBUM ID')
self.assertEqual(d['albumtype'], 'album')
self.assertEqual(d['artist'], 'ARTIST NAME')
self.assertEqual(d['artist_id'], 'ARTIST ID')
self.assertEqual(d['year'], 1984)