set disc and disctotal when autotagging (#226)

This commit is contained in:
Adrian Sampson 2012-02-07 18:03:31 -08:00
parent de8a02a0bb
commit 7522468f0e
7 changed files with 73 additions and 10 deletions

View file

@ -140,6 +140,10 @@ def apply_metadata(items, album_info):
# Title and track index.
item.title = track_info.title
item.track = index + 1
# Disc and disc count.
item.disc = track_info.medium
item.disctotal = album_info.mediums
# MusicBrainz IDs.
item.mb_trackid = track_info.track_id

View file

@ -35,13 +35,14 @@ class AlbumInfo(object):
- ``month``: release month
- ``day``: release day
- ``label``: music label responsible for the release
- ``mediums``: the number of discs in this release
The fields up through ``tracks`` are required. The others are
optional and may be None.
"""
def __init__(self, album, album_id, artist, artist_id, tracks, asin=None,
albumtype=None, va=False, year=None, month=None, day=None,
label=None):
label=None, mediums=None):
self.album = album
self.album_id = album_id
self.artist = artist
@ -54,6 +55,7 @@ class AlbumInfo(object):
self.month = month
self.day = day
self.label = label
self.mediums = mediums
class TrackInfo(object):
"""Describes a canonical track present on a release. Appears as part
@ -64,17 +66,20 @@ class TrackInfo(object):
- ``artist``: individual track artist name
- ``artist_id``
- ``length``: float: duration of the track in seconds
- ``medium``: the disc number this track appears on in the album
- ``medium_index``: the track's position on the disc
Only ``title`` and ``track_id`` are required. The rest of the fields
may be None.
"""
def __init__(self, title, track_id, artist=None, artist_id=None,
length=None, medium_index=None):
length=None, medium=None, medium_index=None):
self.title = title
self.track_id = track_id
self.artist = artist
self.artist_id = artist_id
self.length = length
self.medium = medium
self.medium_index = medium_index

View file

@ -45,13 +45,14 @@ else:
_mb_release_search = musicbrainzngs.search_releases
_mb_recording_search = musicbrainzngs.search_recordings
def track_info(recording, medium_index=None):
def track_info(recording, medium=None, medium_index=None):
"""Translates a MusicBrainz recording result dictionary into a beets
``TrackInfo`` object. ``medium_index``, if provided, is the track's
index (1-based) on its medium.
"""
info = beets.autotag.hooks.TrackInfo(recording['title'],
recording['id'],
medium=medium,
medium_index=medium_index)
# Get the name of the track artist.
@ -95,7 +96,9 @@ def album_info(release):
track_infos = []
for medium in release['medium-list']:
for track in medium['track-list']:
ti = track_info(track['recording'], int(track['position']))
ti = track_info(track['recording'],
int(medium['position']),
int(track['position']))
if track.get('title'):
# Track title may be distinct from underling recording
# title.
@ -107,6 +110,7 @@ def album_info(release):
artist_name,
release['artist-credit'][0]['artist']['id'],
track_infos,
mediums=len(release['medium-list']),
)
info.va = info.artist_id == VARIOUS_ARTISTS_ID
if 'asin' in release:

View file

@ -321,11 +321,11 @@ def sanitize_for_path(value, pathmod, key=None):
value = value.replace(sep, u'_')
elif key in ('track', 'tracktotal', 'disc', 'disctotal'):
# Pad indices with zeros.
value = u'%02i' % value
value = u'%02i' % (value or 0)
elif key == 'year':
value = u'%04i' % value
value = u'%04i' % (value or 0)
elif key in ('month', 'day'):
value = u'%02i' % value
value = u'%02i' % (value or 0)
elif key == 'bitrate':
# Bitrate gets formatted as kbps.
value = u'%ikbps' % ((value or 0) / 1000)

View file

@ -13,6 +13,8 @@ Changelog
per-disc. For example, if track 24 on a release is the first track on the
second disc, then it is not penalized for having its track number set to 1
instead of 24.
* The autotagger sets the disc number and disc total fields on autotagged
albums.
* The autotagger now also tolerates tracks whose track artists tags are set
to "Various Artists".
* Plugin-supplied template values, such as those created by ``rewrite``, are now

View file

@ -467,9 +467,11 @@ class ApplyTest(unittest.TestCase):
self.items.append(Item({}))
trackinfo = []
trackinfo.append(TrackInfo('oneNew',
'dfa939ec-118c-4d0f-84a0-60f3d1e6522c'))
'dfa939ec-118c-4d0f-84a0-60f3d1e6522c',
medium=1))
trackinfo.append(TrackInfo('twoNew',
'40130ed1-a27c-42fd-a328-1ebefb6caef4'))
'40130ed1-a27c-42fd-a328-1ebefb6caef4',
medium=2))
self.info = AlbumInfo(
tracks = trackinfo,
artist = 'artistNew',
@ -478,6 +480,7 @@ class ApplyTest(unittest.TestCase):
artist_id = 'a6623d39-2d8e-4f70-8242-0a9553b91e50',
albumtype = 'album',
va = False,
mediums = 2,
)
def test_titles_applied(self):
@ -502,6 +505,16 @@ class ApplyTest(unittest.TestCase):
self.assertEqual(self.items[0].tracktotal, 2)
self.assertEqual(self.items[1].tracktotal, 2)
def test_disc_index_applied(self):
autotag.apply_metadata(self.items, self.info)
self.assertEqual(self.items[0].disc, 1)
self.assertEqual(self.items[1].disc, 2)
def test_disc_total_applied(self):
autotag.apply_metadata(self.items, self.info)
self.assertEqual(self.items[0].disctotal, 2)
self.assertEqual(self.items[1].disctotal, 2)
def test_mb_trackid_applied(self):
autotag.apply_metadata(self.items, self.info)
self.assertEqual(self.items[0].mb_trackid,

View file

@ -39,7 +39,10 @@ class MBAlbumInfoTest(unittest.TestCase):
'recording': track,
'position': str(i+1),
})
release['medium-list'].append({ 'track-list': track_list })
release['medium-list'].append({
'position': '1',
'track-list': track_list,
})
return release
def _make_track(self, title, tr_id, duration):
@ -97,6 +100,38 @@ class MBAlbumInfoTest(unittest.TestCase):
self.assertEqual(t[0].medium_index, 1)
self.assertEqual(t[1].medium_index, 2)
def test_parse_medium_numbers_single_medium(self):
tracks = [self._make_track('TITLE ONE', 'ID ONE', 100.0 * 1000.0),
self._make_track('TITLE TWO', 'ID TWO', 200.0 * 1000.0)]
release = self._make_release(tracks=tracks)
d = mb.album_info(release)
self.assertEqual(d.mediums, 1)
t = d.tracks
self.assertEqual(t[0].medium, 1)
self.assertEqual(t[1].medium, 1)
def test_parse_medium_numbers_two_mediums(self):
tracks = [self._make_track('TITLE ONE', 'ID ONE', 100.0 * 1000.0),
self._make_track('TITLE TWO', 'ID TWO', 200.0 * 1000.0)]
release = self._make_release(tracks=[tracks[0]])
second_track_list = [{
'recording': tracks[1],
'position': '1',
}]
release['medium-list'].append({
'position': '2',
'track-list': second_track_list,
})
d = mb.album_info(release)
self.assertEqual(d.mediums, 2)
t = d.tracks
self.assertEqual(t[0].medium, 1)
self.assertEqual(t[0].medium_index, 1)
self.assertEqual(t[1].medium, 2)
self.assertEqual(t[1].medium_index, 1)
def test_parse_release_year_month_only(self):
release = self._make_release('1987-03')
d = mb.album_info(release)