Skip to content

Commit

Permalink
Review duplicate_keys feature
Browse files Browse the repository at this point in the history
  • Loading branch information
jcassette committed Jan 22, 2022
1 parent 6ce29a6 commit f50d250
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 34 deletions.
44 changes: 13 additions & 31 deletions beets/importer.py
Expand Up @@ -521,28 +521,18 @@ def skip(self):

# Convenient data.

def chosen_ident(self):
"""Returns identifying metadata about the current choice. For
albums, this is an (artist, album) pair. For items, this is
(artist, title). May only be called when the choice flag is ASIS
or RETAG (in which case the data comes from the files' current
metadata) or APPLY (data comes from the choice).
"""
if self.choice_flag in (action.ASIS, action.RETAG):
return (self.cur_artist, self.cur_album)
elif self.choice_flag is action.APPLY:
return (self.match.info.artist, self.match.info.album)

def chosen_info(self):
"""Returns a dictionnary of metadata about the current choice.
"""Return a dictionary of metadata about the current choice.
May only be called when the choice flag is ASIS or RETAG
(in which case the data comes from the files' current metadata)
or APPLY (in which case the data comes from the choice).
"""
assert(self.choice_flag in (action.ASIS, action.RETAG, action.APPLY))
if self.choice_flag in (action.ASIS, action.RETAG):
return self.cur_info
likelies, consensus = autotag.current_metadata(self.items)
return likelies
elif self.choice_flag is action.APPLY:
return self.match.info
return self.match.info.copy()

def imported_items(self):
"""Return a list of Items that should be added to the library.
Expand Down Expand Up @@ -667,8 +657,6 @@ def lookup_candidates(self):
candidate IDs are stored in self.search_ids: if present, the
initial lookup is restricted to only those IDs.
"""
likelies, consensus = autotag.current_metadata(self.items)
self.cur_info = likelies
artist, album, prop = \
autotag.tag_album(self.items, search_ids=self.search_ids)
self.cur_artist = artist
Expand All @@ -680,26 +668,20 @@ def find_duplicates(self, lib):
"""Return a list of albums from `lib` with the same artist and
album name as the task.
"""
artist, album = self.chosen_ident()
info = self.chosen_info()

if artist is None:
if info['artist'] is None:
# As-is import with no artist. Skip check.
return []

duplicates = []
task_paths = {i.path for i in self.items if i}
keys = config['import']['duplicate_keys'].as_str().split()
info = self.chosen_info().copy()
info['albumartist'] = artist
album = library.Album(None, **info)
subqueries = []
for key in keys:
value = album.get(key)
fast = key in library.Album.item_keys
subqueries.append(dbcore.MatchQuery(key, value, fast))
duplicate_query = dbcore.AndQuery(subqueries)

for album in lib.albums(duplicate_query):
keys = config['import']['duplicate_keys'].as_str_seq()
info['albumartist'] = info['artist']
# Create an Album object so that flexible attributes can be used.
tmp_album = library.Album(lib, **info)

for album in tmp_album.duplicates(*keys):
# Check whether the album paths are all present in the task
# i.e. album is being completely re-imported by the task,
# in which case it is not a duplicate (will be replaced).
Expand Down
14 changes: 14 additions & 0 deletions beets/library.py
Expand Up @@ -1142,6 +1142,20 @@ def _getters(cls):
getters['albumtotal'] = Album._albumtotal
return getters

@classmethod
def construct_match_queries(cls, **info):
subqueries = []
for (key, value) in info.items():
# Use slow queries for flexible attributes.
fast = key in cls._fields
subqueries.append(dbcore.MatchQuery(key, value, fast))
return subqueries

def duplicates(self, *keys):
info = {key: self.get(key) for key in keys}
subqueries = self.construct_match_queries(**info)
return self._db.albums(dbcore.AndQuery(subqueries))

def items(self):
"""Return an iterable over the items associated with this
album.
Expand Down
2 changes: 1 addition & 1 deletion docs/changelog.rst
Expand Up @@ -11,7 +11,7 @@ New features:
* :doc:`/plugins/kodiupdate`: Now supports multiple kodi instances
:bug:`4101`
* Add the item fields ``bitrate_mode``, ``encoder_info`` and ``encoder_settings``.
* Allow to configure which fields are used to find duplicates
* :doc:`/reference/config`: Allow to configure which fields are used to find duplicates

Bug fixes:

Expand Down
2 changes: 1 addition & 1 deletion docs/reference/config.rst
Expand Up @@ -676,7 +676,7 @@ duplicate_keys
~~~~~~~~~~~~~~

The fields used to find duplicates in import task.
If several items have the same value for each key, they will be considered duplicates.
If several albums have the same value for each key, they will be considered duplicates.

Default: ``albumartist album``

Expand Down
2 changes: 1 addition & 1 deletion test/test_importer.py
Expand Up @@ -1311,7 +1311,7 @@ def test_merge_duplicate_album(self):

def test_twice_in_import_dir(self):
self.skipTest('write me')

def test_keep_when_extra_key_is_different(self):
config['import']['duplicate_keys'] = 'albumartist album flex'

Expand Down

0 comments on commit f50d250

Please sign in to comment.