diff --git a/beetsplug/zero.py b/beetsplug/zero.py index abccde36f..b538d6167 100644 --- a/beetsplug/zero.py +++ b/beetsplug/zero.py @@ -41,26 +41,54 @@ class ZeroPlugin(BeetsPlugin): self.config.add({ 'fields': [], + 'keep_fields': [], 'update_database': False, }) self.patterns = {} self.warned = False - for field in self.config['fields'].as_str_seq(): - if field in ('id', 'path', 'album_id'): - self._log.warn(u'field \'{0}\' ignored, zeroing ' - u'it would be dangerous', field) - continue + if self.config['fields']: + self.validate_config('fields') + for field in self.config['fields'].as_str_seq(): + self.set_pattern(field) + + elif self.config['keep_fields']: + self.validate_config('keep_fields') + + for field in MediaFile.fields(): + if field in self.config['keep_fields'].as_str_seq(): + continue + self.set_pattern(field) + + # These fields should be preserved + for key in ('id', 'path', 'album_id'): + if key in self.patterns: + del self.patterns[key] + + def validate_config(self, mode): + """Check if fields written in config are correct.""" + if self.config['fields'] and self.config['keep_fields']: + self._log.warn(u'cannot blacklist and whitelist at the same time') + for field in self.config[mode].as_str_seq(): if field not in MediaFile.fields(): self._log.error(u'invalid field: {0}', field) continue + if mode == 'fields' and field in ('id', 'path', 'album_id'): + self._log.warn(u'field \'{0}\' ignored, zeroing ' + u'it would be dangerous', field) + continue - try: - self.patterns[field] = self.config[field].as_str_seq() - except confit.NotFoundError: - # Matches everything - self.patterns[field] = True + def set_pattern(self, field): + """Set a field in `self.patterns` to a string list corresponding to + the configuration, or `True` if the field has no specific + configuration. + """ + try: + self.patterns[field] = self.config[field].as_str_seq() + except confit.NotFoundError: + # Matches everything + self.patterns[field] = True def import_task_choice_event(self, session, task): """Listen for import_task_choice event.""" diff --git a/docs/plugins/zero.rst b/docs/plugins/zero.rst index 2682ee6ca..cc70e6675 100644 --- a/docs/plugins/zero.rst +++ b/docs/plugins/zero.rst @@ -18,6 +18,9 @@ fields to nullify and the conditions for nullifying them: get the list of all available fields by running ``beet fields``. In addition, the ``images`` field allows you to remove any images embedded in the media file. +* Set ``keep_fields`` to *invert* the logic of the plugin. Only these fields + will be kept; other fields will be removed. Remember to set only + ``fields`` or ``keep_fields``, not both! * To conditionally filter a field, use ``field: [regexp, regexp]`` to specify regular expressions. * By default this plugin only affects files' tags ; the beets database is left @@ -31,6 +34,10 @@ For example:: genre: [rnb, 'power metal'] update_database: true +The plugin can work in one of two modes. The first mode, the default, +is a blacklist, where you choose the tags you want to remove. The second mode +is a whitelist where you instead specify the tags you want to keep. + If a custom pattern is not defined for a given field, the field will be nulled unconditionally.