mirror of
https://github.com/beetbox/beets.git
synced 2026-03-21 21:02:09 +01:00
original_{year,month,day,date} fields (GC-441)
This commit is contained in:
parent
15a652ab73
commit
e0bb3b5cd0
10 changed files with 104 additions and 51 deletions
|
|
@ -178,12 +178,11 @@ def apply_metadata(album_info, mapping):
|
|||
item.albumartist_credit = album_info.artist_credit
|
||||
|
||||
# Release date.
|
||||
if album_info.year:
|
||||
item.year = album_info.year
|
||||
if album_info.month:
|
||||
item.month = album_info.month
|
||||
if album_info.day:
|
||||
item.day = album_info.day
|
||||
for key in ('year', 'month', 'day',
|
||||
'original_year', 'original_month', 'original_day'):
|
||||
value = getattr(album_info, key)
|
||||
if value:
|
||||
setattr(item, key, value)
|
||||
|
||||
# Title.
|
||||
item.title = track_info.title
|
||||
|
|
|
|||
|
|
@ -60,7 +60,8 @@ class AlbumInfo(object):
|
|||
label=None, mediums=None, artist_sort=None,
|
||||
releasegroup_id=None, catalognum=None, script=None,
|
||||
language=None, country=None, albumstatus=None, media=None,
|
||||
albumdisambig=None, artist_credit=None):
|
||||
albumdisambig=None, artist_credit=None, original_year=None,
|
||||
original_month=None, original_day=None):
|
||||
self.album = album
|
||||
self.album_id = album_id
|
||||
self.artist = artist
|
||||
|
|
@ -84,6 +85,9 @@ class AlbumInfo(object):
|
|||
self.media = media
|
||||
self.albumdisambig = albumdisambig
|
||||
self.artist_credit = artist_credit
|
||||
self.original_year = original_year
|
||||
self.original_month = original_month
|
||||
self.original_day = original_day
|
||||
|
||||
# Work around a bug in python-musicbrainz-ngs that causes some
|
||||
# strings to be bytes rather than Unicode.
|
||||
|
|
|
|||
|
|
@ -135,9 +135,10 @@ def track_info(recording, index=None, medium=None, medium_index=None):
|
|||
info.decode()
|
||||
return info
|
||||
|
||||
def _set_date_str(info, date_str):
|
||||
def _set_date_str(info, date_str, original=False):
|
||||
"""Given a (possibly partial) YYYY-MM-DD string and an AlbumInfo
|
||||
object, set the object's release date fields appropriately.
|
||||
object, set the object's release date fields appropriately. If
|
||||
`original`, then set the original_year, etc., fields.
|
||||
"""
|
||||
if date_str:
|
||||
date_parts = date_str.split('-')
|
||||
|
|
@ -148,6 +149,9 @@ def _set_date_str(info, date_str):
|
|||
date_num = int(date_part)
|
||||
except ValueError:
|
||||
continue
|
||||
|
||||
if original:
|
||||
key = 'original_' + key
|
||||
setattr(info, key, date_num)
|
||||
|
||||
def album_info(release):
|
||||
|
|
@ -205,13 +209,14 @@ def album_info(release):
|
|||
if reltype:
|
||||
info.albumtype = reltype.lower()
|
||||
|
||||
# Release date.
|
||||
if 'first-release-date' in release['release-group']:
|
||||
# Try earliest release date for the entire group first.
|
||||
_set_date_str(info, release['release-group']['first-release-date'])
|
||||
elif 'date' in release:
|
||||
# Fall back to release-specific date.
|
||||
_set_date_str(info, release['date'])
|
||||
# Release dates.
|
||||
release_date = release.get('date')
|
||||
release_group_date = release['release-group'].get('first-release-date')
|
||||
if not release_date:
|
||||
# Fall back if release-specific date is not available.
|
||||
release_date = release_group_date
|
||||
_set_date_str(info, release_date, False)
|
||||
_set_date_str(info, release_group_date, True)
|
||||
|
||||
# Label name.
|
||||
if release.get('label-info-list'):
|
||||
|
|
|
|||
|
|
@ -94,6 +94,9 @@ ITEM_FIELDS = [
|
|||
('rg_track_peak', 'real', True, True),
|
||||
('rg_album_gain', 'real', True, True),
|
||||
('rg_album_peak', 'real', True, True),
|
||||
('original_year', 'int', True, True),
|
||||
('original_month', 'int', True, True),
|
||||
('original_day', 'int', True, True),
|
||||
|
||||
('length', 'real', False, True),
|
||||
('bitrate', 'int', False, True),
|
||||
|
|
@ -140,6 +143,9 @@ ALBUM_FIELDS = [
|
|||
('albumdisambig', 'text', True),
|
||||
('rg_album_gain', 'real', True),
|
||||
('rg_album_peak', 'real', True),
|
||||
('original_year', 'int', True),
|
||||
('original_month', 'int', True),
|
||||
('original_day', 'int', True),
|
||||
]
|
||||
ALBUM_KEYS = [f[0] for f in ALBUM_FIELDS]
|
||||
ALBUM_KEYS_ITEM = [f[0] for f in ALBUM_FIELDS if f[2]]
|
||||
|
|
|
|||
|
|
@ -928,26 +928,6 @@ class MediaFile(object):
|
|||
etc = StorageStyle('GROUPING'),
|
||||
asf = StorageStyle('WM/ContentGroupDescription'),
|
||||
)
|
||||
year = MediaField(out_type=int,
|
||||
mp3 = StorageStyle('TDRC', packing=packing.DATE, pack_pos=0),
|
||||
mp4 = StorageStyle("\xa9day", packing=packing.DATE, pack_pos=0),
|
||||
etc = [StorageStyle('DATE', packing=packing.DATE, pack_pos=0),
|
||||
StorageStyle('YEAR')],
|
||||
asf = StorageStyle('WM/Year', packing=packing.DATE, pack_pos=0),
|
||||
)
|
||||
month = MediaField(out_type=int,
|
||||
mp3 = StorageStyle('TDRC', packing=packing.DATE, pack_pos=1),
|
||||
mp4 = StorageStyle("\xa9day", packing=packing.DATE, pack_pos=1),
|
||||
etc = StorageStyle('DATE', packing=packing.DATE, pack_pos=1),
|
||||
asf = StorageStyle('WM/Year', packing=packing.DATE, pack_pos=1),
|
||||
)
|
||||
day = MediaField(out_type=int,
|
||||
mp3 = StorageStyle('TDRC', packing=packing.DATE, pack_pos=2),
|
||||
mp4 = StorageStyle("\xa9day", packing=packing.DATE, pack_pos=2),
|
||||
etc = StorageStyle('DATE', packing=packing.DATE, pack_pos=2),
|
||||
asf = StorageStyle('WM/Year', packing=packing.DATE, pack_pos=2),
|
||||
)
|
||||
date = CompositeDateField(year, month, day)
|
||||
track = MediaField(out_type=int,
|
||||
mp3 = StorageStyle('TRCK', packing=packing.SLASHED, pack_pos=0),
|
||||
mp4 = StorageStyle('trkn', packing=packing.TUPLE, pack_pos=0),
|
||||
|
|
@ -1101,6 +1081,56 @@ class MediaFile(object):
|
|||
asf = StorageStyle('MusicBrainz/Album Comment'),
|
||||
)
|
||||
|
||||
# Release date.
|
||||
year = MediaField(out_type=int,
|
||||
mp3 = StorageStyle('TDRC', packing=packing.DATE, pack_pos=0),
|
||||
mp4 = StorageStyle("\xa9day", packing=packing.DATE, pack_pos=0),
|
||||
etc = [StorageStyle('DATE', packing=packing.DATE, pack_pos=0),
|
||||
StorageStyle('YEAR')],
|
||||
asf = StorageStyle('WM/Year', packing=packing.DATE, pack_pos=0),
|
||||
)
|
||||
month = MediaField(out_type=int,
|
||||
mp3 = StorageStyle('TDRC', packing=packing.DATE, pack_pos=1),
|
||||
mp4 = StorageStyle("\xa9day", packing=packing.DATE, pack_pos=1),
|
||||
etc = StorageStyle('DATE', packing=packing.DATE, pack_pos=1),
|
||||
asf = StorageStyle('WM/Year', packing=packing.DATE, pack_pos=1),
|
||||
)
|
||||
day = MediaField(out_type=int,
|
||||
mp3 = StorageStyle('TDRC', packing=packing.DATE, pack_pos=2),
|
||||
mp4 = StorageStyle("\xa9day", packing=packing.DATE, pack_pos=2),
|
||||
etc = StorageStyle('DATE', packing=packing.DATE, pack_pos=2),
|
||||
asf = StorageStyle('WM/Year', packing=packing.DATE, pack_pos=2),
|
||||
)
|
||||
date = CompositeDateField(year, month, day)
|
||||
|
||||
# *Original* release date.
|
||||
original_year = MediaField(out_type=int,
|
||||
mp3 = StorageStyle('TDOR', packing=packing.DATE, pack_pos=0),
|
||||
mp4 = StorageStyle('----:com.apple.iTunes:ORIGINAL YEAR',
|
||||
packing=packing.DATE, pack_pos=0),
|
||||
etc = StorageStyle('ORIGINALDATE', packing=packing.DATE, pack_pos=0),
|
||||
asf = StorageStyle('WM/OriginalReleaseYear', packing=packing.DATE,
|
||||
pack_pos=0),
|
||||
)
|
||||
original_month = MediaField(out_type=int,
|
||||
mp3 = StorageStyle('TDOR', packing=packing.DATE, pack_pos=1),
|
||||
mp4 = StorageStyle('----:com.apple.iTunes:ORIGINAL YEAR',
|
||||
packing=packing.DATE, pack_pos=1),
|
||||
etc = StorageStyle('ORIGINALDATE', packing=packing.DATE, pack_pos=1),
|
||||
asf = StorageStyle('WM/OriginalReleaseYear', packing=packing.DATE,
|
||||
pack_pos=1),
|
||||
)
|
||||
original_day = MediaField(out_type=int,
|
||||
mp3 = StorageStyle('TDOR', packing=packing.DATE, pack_pos=2),
|
||||
mp4 = StorageStyle('----:com.apple.iTunes:ORIGINAL YEAR',
|
||||
packing=packing.DATE, pack_pos=2),
|
||||
etc = StorageStyle('ORIGINALDATE', packing=packing.DATE, pack_pos=2),
|
||||
asf = StorageStyle('WM/OriginalReleaseYear', packing=packing.DATE,
|
||||
pack_pos=2),
|
||||
)
|
||||
original_date = CompositeDateField(original_year, original_month,
|
||||
original_day)
|
||||
|
||||
# Nonstandard metadata.
|
||||
artist_credit = MediaField(
|
||||
mp3 = StorageStyle('TXXX', id3_desc=u'Artist Credit'),
|
||||
|
|
|
|||
|
|
@ -30,13 +30,16 @@ Other new stuff:
|
|||
* Support for Windows Media/ASF audio files. Thanks to Dave Hayes.
|
||||
* New :doc:`/plugins/smartplaylist`: generate and maintain m3u playlist files
|
||||
based on beets queries. Thanks to Dang Mai Hai.
|
||||
* Two new plugin events were added: *database_change* and *cli_exit*. Thanks
|
||||
again to Dang Mai Hai.
|
||||
* ReplayGain tags on MPEG-4/AAC files are now supported. And, even more
|
||||
astonishingly, ReplayGain values in MP3 and AAC files are now compatible with
|
||||
`iTunes Sound Check`_. Thanks to Dave Hayes.
|
||||
* Track titles in the importer UI's difference display are now either aligned
|
||||
vertically or broken across two lines for readability. Thanks to Tai Lee.
|
||||
* Albums and items have new fields reflecting the *original* release date
|
||||
(``original_year``, ``original_month``, and ``original_day``). Previously,
|
||||
when tagging from MusicBrainz, *only* the original date was stored; now, the
|
||||
old fields refer to the *specific* release date (e.g., when the album was
|
||||
reissued).
|
||||
* Some changes to the way candidates are recommended for selection, thanks to
|
||||
Tai Lee:
|
||||
|
||||
|
|
@ -67,6 +70,8 @@ Other new stuff:
|
|||
highlighted.
|
||||
* The importer UI no longer shows a change when the track length difference is
|
||||
less than 10 seconds. (This threshold was previously 2 seconds.)
|
||||
* Two new plugin events were added: *database_change* and *cli_exit*. Thanks
|
||||
again to Dang Mai Hai.
|
||||
* Plugins are now loaded in the order they appear in the config file. Thanks to
|
||||
Dang Mai Hai.
|
||||
* :doc:`/plugins/bpd`: Browse by album artist and album artist sort name.
|
||||
|
|
|
|||
|
|
@ -170,10 +170,9 @@ Ordinary metadata:
|
|||
* genre
|
||||
* composer
|
||||
* grouping
|
||||
* year
|
||||
* month
|
||||
* day
|
||||
* track
|
||||
* year, month, day: The release date of the specific release.
|
||||
* original_year, original_month, original_day: The release date of the original
|
||||
version of the album.
|
||||
* tracktotal
|
||||
* disc
|
||||
* disctotal
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -95,7 +95,8 @@ class MBAlbumInfoTest(unittest.TestCase):
|
|||
self.assertEqual(d.album_id, 'ALBUM ID')
|
||||
self.assertEqual(d.artist, 'ARTIST NAME')
|
||||
self.assertEqual(d.artist_id, 'ARTIST ID')
|
||||
self.assertEqual(d.year, 1984)
|
||||
self.assertEqual(d.original_year, 1984)
|
||||
self.assertEqual(d.year, 3001)
|
||||
self.assertEqual(d.artist_credit, 'ARTIST CREDIT')
|
||||
|
||||
def test_parse_release_type(self):
|
||||
|
|
@ -106,9 +107,9 @@ class MBAlbumInfoTest(unittest.TestCase):
|
|||
def test_parse_release_full_date(self):
|
||||
release = self._make_release('1987-03-31')
|
||||
d = mb.album_info(release)
|
||||
self.assertEqual(d.year, 1987)
|
||||
self.assertEqual(d.month, 3)
|
||||
self.assertEqual(d.day, 31)
|
||||
self.assertEqual(d.original_year, 1987)
|
||||
self.assertEqual(d.original_month, 3)
|
||||
self.assertEqual(d.original_day, 31)
|
||||
|
||||
def test_parse_tracks(self):
|
||||
tracks = [self._make_track('TITLE ONE', 'ID ONE', 100.0 * 1000.0),
|
||||
|
|
@ -174,8 +175,8 @@ class MBAlbumInfoTest(unittest.TestCase):
|
|||
def test_parse_release_year_month_only(self):
|
||||
release = self._make_release('1987-03')
|
||||
d = mb.album_info(release)
|
||||
self.assertEqual(d.year, 1987)
|
||||
self.assertEqual(d.month, 3)
|
||||
self.assertEqual(d.original_year, 1987)
|
||||
self.assertEqual(d.original_month, 3)
|
||||
|
||||
def test_no_durations(self):
|
||||
tracks = [self._make_track('TITLE', 'ID', None)]
|
||||
|
|
@ -186,9 +187,9 @@ class MBAlbumInfoTest(unittest.TestCase):
|
|||
def test_no_release_date(self):
|
||||
release = self._make_release(None)
|
||||
d = mb.album_info(release)
|
||||
self.assertFalse(d.year)
|
||||
self.assertFalse(d.month)
|
||||
self.assertFalse(d.day)
|
||||
self.assertFalse(d.original_year)
|
||||
self.assertFalse(d.original_month)
|
||||
self.assertFalse(d.original_day)
|
||||
|
||||
def test_various_artists_defaults_false(self):
|
||||
release = self._make_release(None)
|
||||
|
|
|
|||
|
|
@ -120,6 +120,10 @@ CORRECT_DICTS = {
|
|||
'albumdisambig': u'',
|
||||
'artist_credit': u'',
|
||||
'albumartist_credit': u'',
|
||||
'original_year': 0,
|
||||
'original_month': 0,
|
||||
'original_day': 0,
|
||||
'original_date': datetime.date.min,
|
||||
},
|
||||
|
||||
# Full release date.
|
||||
|
|
|
|||
Loading…
Reference in a new issue