diff --git a/beets/mediafile.py b/beets/mediafile.py index 738843923..af68aed89 100644 --- a/beets/mediafile.py +++ b/beets/mediafile.py @@ -1,5 +1,5 @@ # This file is part of beets. -# Copyright 2013, Adrian Sampson. +# Copyright 2014, Adrian Sampson. # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -50,10 +50,12 @@ from beets.util.enumeration import enum __all__ = ['UnreadableFileError', 'FileTypeError', 'MediaFile'] + # Logger. log = logging.getLogger('beets') + # Exceptions. # Raised for any file MediaFile can't read. @@ -65,6 +67,7 @@ class FileTypeError(UnreadableFileError): pass + # Constants. # Human-readable type names. @@ -82,13 +85,14 @@ TYPES = { } + # Utility. def _safe_cast(out_type, val): - """Tries to covert val to out_type but will never raise an - exception. If the value can't be converted, then a sensible - default value is returned. out_type should be bool, int, or - unicode; otherwise, the value is just passed through. + """Try to covert val to out_type but never raise an exception. If + the value can't be converted, then a sensible default value is + returned. out_type should be bool, int, or unicode; otherwise, the + value is just passed through. """ if out_type == int: if val is None: @@ -149,6 +153,7 @@ def _safe_cast(out_type, val): return val + # Image coding for ASF/WMA. def _unpack_asf_image(data): @@ -186,6 +191,7 @@ def _pack_asf_image(mime, data, type=3, description=""): return tag_data + # iTunes Sound Check encoding. def _sc_decode(soundcheck): @@ -247,6 +253,7 @@ def _sc_encode(gain, peak): return (u' %08X' * 10) % values + # Flags for encoding field behavior. # Determine style of packing, if any. @@ -255,9 +262,12 @@ packing = enum('SLASHED', # pair delimited by / 'DATE', # YYYY-MM-DD 'SC', # Sound Check gain/peak encoding name='packing') -packing_type = packing + +# StorageStyle classes describe strategies for accessing values in +# Mutagen file objects. + class StorageStyle(object): """Parameterizes the storage behavior of a single field for a certain tag format. @@ -289,11 +299,6 @@ class StorageStyle(object): if formats: self.formats = formats - if self.packing == packing_type.DATE: - self.packing_length = 3 - else: - self.packing_length = 2 - # Convert suffix to correct string type. if self.suffix and self.as_type == unicode: self.suffix = self.as_type(self.suffix) @@ -319,8 +324,13 @@ class StorageStyle(object): def unpack(self, data): """Splits raw data from a tag into a list of values.""" + if self.packing == packing.DATE: + packing_length = 3 + else: + packing_length = 2 + if data is None: - return [None]*self.packing_length + return [None] * packing_length if self.packing == packing.DATE: # Remove time information from dates. Usually delimited by @@ -334,7 +344,7 @@ class StorageStyle(object): elif self.packing == packing.SC: items = _sc_decode(data) - return list(items) + [None]*(self.packing_length - len(items)) + return list(items) + [None] * (packing_length - len(items)) def store(self, mediafile, value): """Stores a serialized value in the mediafile.""" @@ -610,6 +620,7 @@ class MP3UFIDStorageStyle(MP3StorageStyle): frame = mutagen.id3.UFID(owner=self.owner, data=value) mediafile.mgfile.tags.setall(self.key, [frame]) + class MP3DescStorageStyle(MP3StorageStyle): def __init__(self, desc=u'', key='TXXX', **kwargs): @@ -721,7 +732,7 @@ class VorbisImageStorageStyle(ListStorageStyle): for data in mediafile.mgfile["metadata_block_picture"]: try: pics.append(mutagen.flac.Picture(base64.b64decode(data)).data) - except TypeError, AttributeError: + except (TypeError, AttributeError): pass return pics @@ -772,7 +783,11 @@ class FlacImageStorageStyle(ListStorageStyle): mediafile.mgfile.add_picture(pic) -# The field itself. + +# MediaField is a descriptor that represents a single logical field. It +# aggregates several StorageStyles describing how to access the data for +# each file type. + class MediaField(object): """A descriptor providing access to a particular (abstract) metadata field. @@ -916,7 +931,8 @@ class ImageField(MediaField): style.set(obj, val) -# The file (a collection of fields). + +# MediaFile is a collection of fields. class MediaFile(object): """Represents a multimedia file on disk and provides access to its diff --git a/docs/changelog.rst b/docs/changelog.rst index 5336b8d93..aecd83056 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -1,7 +1,14 @@ Changelog ========= -1.3.4 (February 26, 2014) +1.3.4 (in development) +---------------------- + +* Internally, beets has laid the groundwork for supporting multi-valued + fields. Thanks to geigerzaehler. + + +1.3.3 (February 26, 2014) ------------------------- Version 1.3.3 brings a bunch changes to how item and album fields work