From 912546b41dfb1e274e6da2999b58baa10c68c320 Mon Sep 17 00:00:00 2001 From: Marcel van der Veldt Date: Thu, 21 Apr 2022 19:15:45 +0200 Subject: [PATCH] Fix version parsing in track matching logic (#261) --- music_assistant/helpers/compare.py | 12 ++++++++++ music_assistant/helpers/util.py | 35 +++++++++++++++++------------- tests/utils.py | 12 ++++++++++ 3 files changed, 44 insertions(+), 15 deletions(-) create mode 100644 tests/utils.py diff --git a/music_assistant/helpers/compare.py b/music_assistant/helpers/compare.py index 553b5ccb..91287fd0 100644 --- a/music_assistant/helpers/compare.py +++ b/music_assistant/helpers/compare.py @@ -40,6 +40,15 @@ def compare_version(left_version: str, right_version: str): return left_versions == right_versions +def compare_explicit(left_metadata: dict, right_metadata: dict): + """Compare if explicit is same in metadata.""" + left = left_metadata.get("explicit") + right = right_metadata.get("explicit") + if left is None and right is None: + return True + return left == right + + def compare_artists(left_artists: List["Artist"], right_artists: List["Artist"]): """Compare two lists of artist and return True if both lists match.""" matches = 0 @@ -101,6 +110,9 @@ def compare_track(left_track: "Track", right_track: "Track"): # track artist(s) must match if not compare_artists(left_track.artists, right_track.artists): return False + # track if both tracks are (not) explicit + if not compare_explicit(left_track.metadata, right_track.metadata): + return False # album match OR near exact duration match if ( compare_album(left_track.album, right_track.album) diff --git a/music_assistant/helpers/util.py b/music_assistant/helpers/util.py index b45cdab0..926ff3d4 100755 --- a/music_assistant/helpers/util.py +++ b/music_assistant/helpers/util.py @@ -83,9 +83,8 @@ def create_sort_name(name): return sort_name.lower() -def parse_title_and_version(track_title, track_version=None): +def parse_title_and_version(title: str, track_version: str = None): """Try to parse clean track title and version from the title.""" - title = track_title.lower() version = "" for splitter in [" (", " [", " - ", " (", " [", "-"]: if splitter in title: @@ -95,16 +94,6 @@ def parse_title_and_version(track_title, track_version=None): for end_splitter in [")", "]"]: if end_splitter in title_part: title_part = title_part.split(end_splitter)[0] - for ignore_str in [ - "feat.", - "featuring", - "ft.", - "with ", - " & ", - "explicit", - ]: - if ignore_str in title_part: - title = title.split(splitter + title_part)[0] for version_str in [ "version", "live", @@ -122,10 +111,10 @@ def parse_title_and_version(track_title, track_version=None): "akoestisch", "deluxe", ]: - if version_str in title_part: + if version_str in title_part.lower(): version = title_part title = title.split(splitter + version)[0] - title = title.strip().title() + title = clean_title(title) if not version and track_version: version = track_version version = get_version_substitute(version).title() @@ -134,7 +123,23 @@ def parse_title_and_version(track_title, track_version=None): return title, version -def get_version_substitute(version_str): +def clean_title(title: str) -> str: + """Strip unwanted additional text from title.""" + for splitter in [" (", " [", " - ", " (", " [", "-"]: + if splitter in title: + title_parts = title.split(splitter) + for title_part in title_parts: + # look for the end splitter + for end_splitter in [")", "]"]: + if end_splitter in title_part: + title_part = title_part.split(end_splitter)[0] + for ignore_str in ["feat.", "featuring", "ft.", "with ", "explicit"]: + if ignore_str in title_part.lower(): + return title.split(splitter + title_part)[0].strip() + return title.strip() + + +def get_version_substitute(version_str: str): """Transform provider version str to universal version type.""" version_str = version_str.lower() # substitute edit and edition with version diff --git a/tests/utils.py b/tests/utils.py new file mode 100644 index 00000000..6f21487d --- /dev/null +++ b/tests/utils.py @@ -0,0 +1,12 @@ +"""Tests for utility functions.""" + +from music_assistant.helpers import util + + +def test_version_extract(): + """Test the extraction of version from title.""" + + test_str = "Bam Bam (feat. Ed Sheeran) - Karaoke Version" + title, version = util.parse_title_and_version(test_str) + assert title == "Bam Bam" + assert version == "Karaoke Version" -- 2.34.1