feat: extract featured artists from track title

This commit is contained in:
geoffrey45 2023-01-24 18:53:30 +03:00
parent df6609e7f4
commit 2ba1b0386e
7 changed files with 64 additions and 19 deletions

3
.gitignore vendored
View File

@ -16,10 +16,9 @@ __pycache__
.hypothesis .hypothesis
sqllib.py sqllib.py
encoderx.py encoderx.py
tests
.pytest_cache .pytest_cache
# pyinstaller files # pyinstaller files
dist dist
build build
client client

View File

@ -19,7 +19,7 @@ class CacheEntry:
""" """
def __init__( def __init__(
self, artisthash: str, albumhashes: set[str], tracks: list[Track] self, artisthash: str, albumhashes: set[str], tracks: list[Track]
) -> None: ) -> None:
self.albums: list[Album] = [] self.albums: list[Album] = []
self.tracks: list[Track] = [] self.tracks: list[Track] = []
@ -275,7 +275,6 @@ def get_artist_tracks(artisthash: str):
# return {"albums": albums[:limit]} # return {"albums": albums[:limit]}
# @artist_bp.route("/artist/<artist>") # @artist_bp.route("/artist/<artist>")
# @cache.cached() # @cache.cached()
# def get_artist_data(artist: str): # def get_artist_data(artist: str):

View File

@ -1,7 +1,6 @@
from flask import Blueprint, request from flask import Blueprint, request
from app import settings from app import settings
from app.logger import log from app.logger import log
from app.lib import populate from app.lib import populate
from app.db.store import Store from app.db.store import Store
@ -15,7 +14,7 @@ api = Blueprint("settings", __name__, url_prefix="/")
def get_child_dirs(parent: str, children: list[str]): def get_child_dirs(parent: str, children: list[str]):
"""Returns child directories in a list, given a parent directory""" """Returns child directories in a list, given a parent directory"""
return [dir for dir in children if dir.startswith(parent) and dir != parent] return [_dir for _dir in children if _dir.startswith(parent) and _dir != parent]
@background @background
@ -56,10 +55,10 @@ def add_root_dirs():
except KeyError: except KeyError:
return msg, 400 return msg, 400
def finalize(new_dirs: list[str], removed_dirs: list[str], db_dirs: list[str]): def finalize(new_: list[str], removed_: list[str], db_dirs_: list[str]):
sdb.remove_root_dirs(removed_dirs) sdb.remove_root_dirs(removed_)
sdb.add_root_dirs(new_dirs) sdb.add_root_dirs(new_)
rebuild_store(db_dirs) rebuild_store(db_dirs_)
# --- # ---
db_dirs = sdb.get_root_dirs() db_dirs = sdb.get_root_dirs()
@ -91,7 +90,7 @@ def add_root_dirs():
pass pass
db_dirs.extend(new_dirs) db_dirs.extend(new_dirs)
db_dirs = [dir for dir in db_dirs if dir != _h] db_dirs = [dir_ for dir_ in db_dirs if dir_ != _h]
finalize(new_dirs, removed_dirs, db_dirs) finalize(new_dirs, removed_dirs, db_dirs)

View File

@ -58,10 +58,14 @@ class Track:
def __post_init__(self): def __post_init__(self):
if self.artist is not None: if self.artist is not None:
artist_str = str(self.artist).split(", ") artists = utils.split_artists(self.artist)
self.artist_hashes = [utils.create_hash(a, decode=True) for a in artist_str] featured = utils.extract_featured_artists_from_title(self.title)
artists.extend(featured)
artists = set(artists)
self.artist = [Artist(a) for a in artist_str] self.artist_hashes = [utils.create_hash(a, decode=True) for a in artists]
self.artist = [Artist(a) for a in artists]
albumartists = str(self.albumartist).split(", ") albumartists = str(self.albumartist).split(", ")
self.albumartist = [Artist(a) for a in albumartists] self.albumartist = [Artist(a) for a in albumartists]
@ -150,10 +154,10 @@ class Album:
Checks if the album is a single. Checks if the album is a single.
""" """
if ( if (
len(tracks) == 1 len(tracks) == 1
and tracks[0].title == self.title and tracks[0].title == self.title
and tracks[0].track == 1 and tracks[0].track == 1
and tracks[0].disc == 1 and tracks[0].disc == 1
): ):
self.is_single = True self.is_single = True

View File

@ -1,6 +1,7 @@
""" """
This module contains mini functions for the server. This module contains mini functions for the server.
""" """
import re
from pathlib import Path from pathlib import Path
from datetime import datetime from datetime import datetime
@ -187,7 +188,7 @@ def get_albumartists(albums: list[models.Album]) -> set[str]:
def get_all_artists( def get_all_artists(
tracks: list[models.Track], albums: list[models.Album] tracks: list[models.Track], albums: list[models.Album]
) -> list[models.Artist]: ) -> list[models.Artist]:
artists_from_tracks = get_artists_from_tracks(tracks) artists_from_tracks = get_artists_from_tracks(tracks)
artist_from_albums = get_albumartists(albums) artist_from_albums = get_albumartists(albums)
@ -250,3 +251,28 @@ def is_windows():
Returns True if the OS is Windows. Returns True if the OS is Windows.
""" """
return platform.system() == "Windows" return platform.system() == "Windows"
def split_artists(src: str):
artists = re.split(r"\s*[&,;/]\s*", src)
return [a.strip() for a in artists]
def extract_featured_artists_from_title(title: str) -> list[str]:
"""
Extracts featured artists from a song title using regex.
"""
regex = r"\((?:feat|ft|featuring|with)\.?\s+(.+?)\)"
match = re.search(regex, title, re.IGNORECASE)
if not match:
return []
artists = match.group(1)
artists = split_artists(artists)
return artists

0
tests/__init__.py Normal file
View File

18
tests/test.py Normal file
View File

@ -0,0 +1,18 @@
from app.utils import extract_featured_artists_from_title
def test_extract_featured_artists_from_title():
test_titles = [
"Own it (Featuring Ed Sheeran & Stormzy)",
"Godzilla (Deluxe)(Feat. Juice Wrld)(Deluxe)",
"Simmer (with Burna Boy)",
]
expected_test_artists = [
["Ed Sheeran", "Stormzy"],
['Juice Wrld'],
["Burna Boy"]
]
for title, expected in zip(test_titles, expected_test_artists):
assert extract_featured_artists_from_title(title) == expected