diff --git a/beets/autotag/__init__.py b/beets/autotag/__init__.py index e774e18eb..0ceb1dfab 100644 --- a/beets/autotag/__init__.py +++ b/beets/autotag/__init__.py @@ -122,8 +122,6 @@ def apply_metadata(album_info, mapping, per_disc_numbering=False): """ for item, track_info in mapping.iteritems(): # Album, artist, track count. - if not item: - continue if track_info.artist: item.artist = track_info.artist else: diff --git a/beets/library.py b/beets/library.py index 3d0941c92..40265231e 100644 --- a/beets/library.py +++ b/beets/library.py @@ -281,8 +281,9 @@ class Item(object): def write(self): """Writes the item's metadata to the associated file. """ + plugins.send('write', item=self) + f = MediaFile(syspath(self.path)) - plugins.send('write', item=self, mf=f) for key in ITEM_KEYS_WRITABLE: setattr(f, key, getattr(self, key)) f.save() diff --git a/beetsplug/scrub.py b/beetsplug/scrub.py index 4b82e4c3c..5fd495c20 100755 --- a/beetsplug/scrub.py +++ b/beetsplug/scrub.py @@ -1,5 +1,5 @@ # This file is part of beets. -# Copyright 2011, Adrian Sampson. +# Copyright 2012, Adrian Sampson. # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -19,12 +19,26 @@ import logging from beets.plugins import BeetsPlugin from beets import ui -from beets import mediafile from beets import util log = logging.getLogger('beets') AUTOSCRUB_KEY = 'autoscrub' +_MUTAGEN_FORMATS = { + 'asf': 'ASF', + 'apev2': 'APEv2File', + 'flac': 'FLAC', + 'id3': 'ID3FileType', + 'mp3': 'MP3', + 'oggflac': 'OggFLAC', + 'oggspeex': 'OggSpeex', + 'oggtheora': 'OggTheora', + 'oggvorbis': 'OggVorbis', + 'trueaudio': 'TrueAudio', + 'wavpack': 'WavPack', + 'monkeysaudio': 'MonkeysAudio', + 'optimfrog': 'OptimFROG', +} scrubbing = False @@ -47,9 +61,7 @@ class ScrubPlugin(BeetsPlugin): # Walk through matching files and remove tags. for item in lib.items(ui.decargs(args)): log.info(u'scrubbing: %s' % util.displayable_path(item.path)) - mf = mediafile.MediaFile(item.path) - _scrub(mf) - mf.save() + _scrub(item.path) if opts.write: log.debug(u'writing new tags after scrub') @@ -65,17 +77,36 @@ class ScrubPlugin(BeetsPlugin): return [scrub_cmd] -def _scrub(mf): - """Remove all tags from a MediaFile by manipulating the underlying - Mutagen object. +def _mutagen_classes(): + """Get a list of file type classes from the Mutagen module. """ - mf.mgfile.delete() - # Reinitialize the MediaFile: also a little hacky. - mf.__init__(mf.path) + classes = [] + for modname, clsname in _MUTAGEN_FORMATS.items(): + mod = __import__('mutagen.{}'.format(modname), + fromlist=[clsname]) + classes.append(getattr(mod, clsname)) + return classes + +def _scrub(path): + """Remove all tags from a file. + """ + for cls in _mutagen_classes(): + # Try opening the file with this type, but just skip in the + # event of any error. + try: + f = cls(util.syspath(path)) + except Exception: + continue + if f.tags is None: + continue + + # Remove the tag for this type. + f.delete() + f.save() # Automatically embed art into imported albums. @ScrubPlugin.listen('write') -def write_item(item, mf): +def write_item(item): if not scrubbing and options[AUTOSCRUB_KEY]: log.debug(u'auto-scrubbing %s' % util.displayable_path(item.path)) - _scrub(mf) + _scrub(item.path) diff --git a/docs/changelog.rst b/docs/changelog.rst index 405c5e65a..005f9733f 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -4,6 +4,9 @@ Changelog 1.0b16 (in development) ----------------------- +* :doc:`/plugins/scrub`: Scrubbing now removes *all* types of tags from a file + rather than just one. For example, if your FLAC file has both ordinary FLAC + tags and ID3 tags, the ID3 tags are now also removed. * ``list`` command: Templates given with ``-f`` can now show items' paths (using ``$path``). * Fix album queries for ``artpath`` and other non-item fields. diff --git a/docs/plugins/scrub.rst b/docs/plugins/scrub.rst index 9c3ebece5..4c4ca9ff7 100644 --- a/docs/plugins/scrub.rst +++ b/docs/plugins/scrub.rst @@ -13,7 +13,7 @@ Automatic Scrubbing To automatically remove files' tags before writing new ones, just enable the plugin (see :doc:`/plugins/index`). When importing new files (with ``import_write`` turned on) or modifying files' tags with the ``beet modify`` -command, beets will first strip the tags entirely and then write the +command, beets will first strip all types of tags entirely and then write the database-tracked metadata to the file. This behavior can be disabled with the ``autoscrub`` config option (see below). diff --git a/docs/plugins/writing.rst b/docs/plugins/writing.rst index 738a56bb4..4d2f83217 100644 --- a/docs/plugins/writing.rst +++ b/docs/plugins/writing.rst @@ -128,8 +128,8 @@ currently available are: singleton to the library (not called for full-album imports). Parameters: ``lib``, ``item``, ``config`` -* *write*: called with an ``Item`` and a ``MediaFile`` object just before a - file's metadata is written to disk. +* *write*: called with an ``Item`` object just before a file's metadata is + written to disk (i.e., just before the file on disk is opened). * *import_task_start*: called when before an import task begins processing. Parameters: ``task`` and ``config``.