From 22795c712498397301c3b82945ea8e344ae317aa Mon Sep 17 00:00:00 2001 From: "adrian.sampson" Date: Mon, 25 Aug 2008 07:52:18 +0000 Subject: [PATCH] added Mon Aug 25 00:52:14 PDT 2008 convenience field for MediaFile --HG-- extra : convert_revision : svn%3A41726ec3-264d-0410-9c23-a9f1637257cc/trunk%4089 --- beets/mediafile.py | 24 +++++++++++++++++++++--- test/test_mediafile.py | 34 ++++++++++++++++++++++++++++++---- 2 files changed, 51 insertions(+), 7 deletions(-) diff --git a/beets/mediafile.py b/beets/mediafile.py index 9c432477f..ba21f1915 100644 --- a/beets/mediafile.py +++ b/beets/mediafile.py @@ -15,6 +15,7 @@ or the empty string).""" import mutagen import os.path +import datetime __all__ = ['FileTypeError', 'MediaFile'] @@ -308,9 +309,25 @@ class MediaField(object): # store the data self._storedata(obj, out) - - - +class CompositeDateField(object): + def __init__(self, year_field, month_field, day_field): + self.year_field = year_field + self.month_field = month_field + self.day_field = day_field + + def __get__(self, obj, owner): + try: + return datetime.date(max(self.year_field.__get__(obj, owner), + datetime.MINYEAR), + max(self.month_field.__get__(obj, owner), 1), + max(self.day_field.__get__(obj, owner), 1) + ) + except ValueError: # Out of range values. + return datetime.date.min + def __set__(self, obj, val): + self.year_field.__set__(obj, val.year) + self.month_field.__set__(obj, val.month) + self.day_field.__set__(obj, val.day) @@ -406,6 +423,7 @@ class MediaFile(object): packing = packing.DATE, pack_pos = 2) ) + date = CompositeDateField(year, month, day) track = MediaField(out_type = int, mp3 = StorageStyle('TRCK', packing = packing.SLASHED, diff --git a/test/test_mediafile.py b/test/test_mediafile.py index 0997e8041..ee302fd06 100755 --- a/test/test_mediafile.py +++ b/test/test_mediafile.py @@ -4,7 +4,7 @@ Test the MediaFile metadata layer. """ -import unittest, sys, os, shutil +import unittest, sys, os, shutil, datetime sys.path.append('..') import beets.mediafile @@ -37,6 +37,8 @@ def MakeWritingTest(path, correct_dict, field, testsuffix='_test'): self.value = correct_dict[field] + 42 elif type(correct_dict[field]) is bool: self.value = not correct_dict[field] + elif type(correct_dict[field]) is datetime.date: + self.value = correct_dict[field] + datetime.timedelta(42) else: raise ValueError('unknown field type ' + \ str(type(correct_dict[field]))) @@ -51,13 +53,34 @@ def MakeWritingTest(path, correct_dict, field, testsuffix='_test'): b = beets.mediafile.MediaFile(self.tpath) for readfield in correct_dict.keys(): got = getattr(b, readfield) - if readfield is field: + + # Make sure the modified field was changed correctly... + if readfield == field: self.assertEqual(got, self.value, field + ' modified incorrectly (changed to ' + \ repr(self.value) + ' but read ' + repr(got) + \ ') when testing ' + os.path.basename(path)) + + # ... and that no other field was changed. else: - correct = getattr(a, readfield) + # The value should be what it was originally most of the time. + correct = correct_dict[readfield] + + # The date field, however, is modified when its components + # change. + if readfield == 'date' and field in ('year', 'month', 'day'): + try: + correct = datetime.date( + self.value if field == 'year' else correct.year, + self.value if field == 'month' else correct.month, + self.value if field == 'day' else correct.day + ) + except ValueError: + correct = datetime.date.min + # And vice-versa. + if field == 'date' and readfield in ('year', 'month', 'day'): + correct = getattr(self.value, readfield) + self.assertEqual(got, correct, readfield + ' changed when it should not have (expected' ' ' + repr(correct) + ', got ' + repr(got) + ') when ' @@ -81,6 +104,7 @@ correct_dicts = { 'year': 2001, 'month': 0, 'day': 0, + 'date': datetime.date(2001, 1, 1), 'track': 2, 'tracktotal': 3, 'disc': 4, @@ -117,6 +141,7 @@ correct_dicts = { 'year': 0, 'month': 0, 'day': 0, + 'date': datetime.date.min, 'track': 0, 'tracktotal': 0, 'disc': 0, @@ -131,7 +156,8 @@ correct_dicts = { 'date': { 'year': 1987, 'month': 3, - 'day': 31 + 'day': 31, + 'date': datetime.date(1987, 3, 31) }, }