Have find_best_match and sort_by_similarity accept any iterable

This commit is contained in:
Philipp Wolfer
2022-02-16 11:41:07 +01:00
parent 159deb299a
commit e1c6234dd7
6 changed files with 26 additions and 15 deletions

View File

@@ -688,7 +688,7 @@ class Album(DataObject, Item):
similarity = track.metadata.length_score(track.metadata.length, file.metadata.length)
yield SimMatchAlbum(similarity=similarity, track=track)
best_match = find_best_match(mbid_candidates, no_match)
best_match = find_best_match(mbid_candidates(), no_match)
if best_match != no_match:
yield (file, best_match.result.track)
continue
@@ -700,7 +700,7 @@ class Album(DataObject, Item):
if similarity >= threshold:
yield SimMatchAlbum(similarity=similarity, track=track)
best_match = find_best_match(similarity_candidates, no_match)
best_match = find_best_match(similarity_candidates(), no_match)
yield (file, best_match.result.track)
def match_files(self, files):

View File

@@ -6,7 +6,7 @@
# Copyright (C) 2006-2008, 2011 Lukáš Lalinský
# Copyright (C) 2008 Hendrik van Antwerpen
# Copyright (C) 2008 Will
# Copyright (C) 2010-2011, 2014, 2018-2021 Philipp Wolfer
# Copyright (C) 2010-2011, 2014, 2018-2022 Philipp Wolfer
# Copyright (C) 2011-2013 Michael Wiencek
# Copyright (C) 2012 Chad Wilson
# Copyright (C) 2012 Wieland Hoffmann
@@ -271,7 +271,7 @@ class Cluster(FileList):
yield match
no_match = SimMatchRelease(similarity=-1, release=None)
best_match = find_best_match(candidates, no_match)
best_match = find_best_match(candidates(), no_match)
return best_match.result.release
def lookup_metadata(self):

View File

@@ -830,7 +830,7 @@ class File(QtCore.QObject, Item):
yield self.metadata.compare_to_track(track, self.comparison_weights)
no_match = SimMatchTrack(similarity=-1, releasegroup=None, release=None, track=None)
best_match = find_best_match(candidates, no_match)
best_match = find_best_match(candidates(), no_match)
if best_match.similarity < threshold:
return None

View File

@@ -5,7 +5,7 @@
# Copyright (C) 2016 Rahul Raturi
# Copyright (C) 2018 Antonio Larrosa
# Copyright (C) 2018-2021 Laurent Monin
# Copyright (C) 2018-2021 Philipp Wolfer
# Copyright (C) 2018-2022 Philipp Wolfer
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
@@ -134,7 +134,7 @@ class TrackSearchDialog(SearchDialog):
for track in tracks:
yield metadata.compare_to_track(track, File.comparison_weights)
tracks = [result.track for result in sort_by_similarity(candidates)]
tracks = [result.track for result in sort_by_similarity(candidates())]
del self.search_results[:] # Clear existing data
self.parse_tracks(tracks)

View File

@@ -724,15 +724,29 @@ BestMatch = namedtuple('BestMatch', ('similarity', 'result'))
def sort_by_similarity(candidates):
"""Sorts the objects in candidates by similarity.
Args:
candidates: Iterable with objects having a `similarity` attribute
Returns: List of candidates sorted by similarity (highest similarity first)
"""
return sorted(
candidates(),
candidates,
reverse=True,
key=attrgetter('similarity')
)
def find_best_match(candidates, no_match):
best_match = max(candidates(), key=attrgetter('similarity'), default=no_match)
"""Returns a BestMatch based on the similarity of candidates.
Args:
candidates: Iterable with objects having a `similarity` attribute
no_match: Match to return if there was no candidate
Returns: `BestMatch` with the similarity and the matched object as result.
"""
best_match = max(candidates, key=attrgetter('similarity'), default=no_match)
return BestMatch(similarity=best_match.similarity, result=best_match)

View File

@@ -407,16 +407,13 @@ class SortBySimilarity(PicardTestCase):
SimMatchTest(similarity=0.75, name='c'),
]
def candidates(self):
yield from self.test_values
def test_sort_by_similarity(self):
results = [result.name for result in sort_by_similarity(self.candidates)]
results = [result.name for result in sort_by_similarity(self.test_values)]
self.assertEqual(results, ['b', 'c', 'd', 'a'])
def test_findbestmatch(self):
no_match = SimMatchTest(similarity=-1, name='no_match')
best_match = find_best_match(self.candidates, no_match)
best_match = find_best_match(self.test_values, no_match)
self.assertEqual(best_match.result.name, 'b')
self.assertEqual(best_match.similarity, 0.75)
@@ -425,7 +422,7 @@ class SortBySimilarity(PicardTestCase):
self.test_values = []
no_match = SimMatchTest(similarity=-1, name='no_match')
best_match = find_best_match(self.candidates, no_match)
best_match = find_best_match(self.test_values, no_match)
self.assertEqual(best_match.result.name, 'no_match')
self.assertEqual(best_match.similarity, -1)