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
# 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)
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:
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",
"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()
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
--- /dev/null
+"""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"