diff --git a/beets/importer.py b/beets/importer.py index 38d2a4e628..3e288c271b 100644 --- a/beets/importer.py +++ b/beets/importer.py @@ -572,10 +572,11 @@ def remove_duplicates(self, lib): util.prune_dirs(os.path.dirname(item.path), lib.directory) - def set_fields(self): + def set_fields(self, lib): """Sets the fields given at CLI or configuration to the specified - values. + values, for both the album and all its items. """ + items = self.imported_items() for field, view in config['import']['set_fields'].items(): value = view.get() log.debug(u'Set field {1}={2} for {0}', @@ -583,7 +584,12 @@ def set_fields(self): field, value) self.album[field] = value - self.album.store() + for item in items: + item[field] = value + with lib.transaction(): + for item in items: + item.store() + self.album.store() def finalize(self, session): """Save progress, clean up files, and emit plugin event. @@ -946,9 +952,9 @@ def choose_match(self, session): def reload(self): self.item.load() - def set_fields(self): + def set_fields(self, lib): """Sets the fields given at CLI or configuration to the specified - values. + values, for the singleton item. """ for field, view in config['import']['set_fields'].items(): value = view.get() @@ -1516,7 +1522,7 @@ def apply_choice(session, task): # because then the ``ImportTask`` won't have an `album` for which # it can set the fields. if config['import']['set_fields']: - task.set_fields() + task.set_fields(session.lib) @pipeline.mutator_stage diff --git a/docs/changelog.rst b/docs/changelog.rst index 892900ba99..0a468313cf 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -218,6 +218,8 @@ Other new things: ``check_on_import`` config option. * :doc:`/plugins/export`: big speedups when `--include-keys` option is used Thanks to :user:`ssssam`. +* The `importer` persists all fields set using :ref:`set_fields` to the + mediafiles of all imported tracks. * Added 7z support via the `py7zr`_ library Thanks to :user:`arogl`. :bug:`3906` * Get ISRC identifiers from musicbrainz diff --git a/docs/reference/config.rst b/docs/reference/config.rst index 455639be0d..aabe732c20 100644 --- a/docs/reference/config.rst +++ b/docs/reference/config.rst @@ -683,6 +683,9 @@ Here's an example:: Other field/value pairs supplied via the ``--set`` option on the command-line override any settings here for fields with the same name. +Fields are set on both the album and each individual track of the album. +Fields are persisted to the media files of each track. + Default: ``{}`` (empty). .. _musicbrainz-config: diff --git a/test/test_importer.py b/test/test_importer.py index 48cb23378b..16881a152c 100644 --- a/test/test_importer.py +++ b/test/test_importer.py @@ -740,10 +740,12 @@ def test_asis_no_data_source(self): def test_set_fields(self): genre = u"\U0001F3B7 Jazz" collection = u"To Listen" + comments = u"managed by beets" config['import']['set_fields'] = { + u'genre': genre, u'collection': collection, - u'genre': genre + u'comments': comments } # As-is album import. @@ -754,7 +756,17 @@ def test_set_fields(self): for album in self.lib.albums(): album.load() # TODO: Not sure this is necessary. self.assertEqual(album.genre, genre) - self.assertEqual(album.collection, collection) + self.assertEqual(album.comments, comments) + for item in album.items(): + self.assertEqual( + item.get("genre", with_album=False), + genre) + self.assertEqual( + item.get("collection", with_album=False), + collection) + self.assertEqual( + item.get("comments", with_album=False), + comments) # Remove album from library to test again with APPLY choice. album.remove() @@ -767,7 +779,17 @@ def test_set_fields(self): for album in self.lib.albums(): album.load() self.assertEqual(album.genre, genre) - self.assertEqual(album.collection, collection) + self.assertEqual(album.comments, comments) + for item in album.items(): + self.assertEqual( + item.get("genre", with_album=False), + genre) + self.assertEqual( + item.get("collection", with_album=False), + collection) + self.assertEqual( + item.get("comments", with_album=False), + comments) class ImportTracksTest(_common.TestCase, ImportHelper):