Files
swingmusic-extended/app/store/tracks.py
T
2024-05-25 15:12:44 +03:00

200 lines
5.8 KiB
Python

# from tqdm import tqdm
from flask_jwt_extended import current_user
from app.db.sqlite.favorite import SQLiteFavoriteMethods as favdb
from app.db.sqlite.tracks import SQLiteTrackMethods as trackdb
from app.models import Track
from app.utils.bisection import use_bisection
from app.utils.customlist import CustomList
from app.utils.remove_duplicates import remove_duplicates
TRACKS_LOAD_KEY = ""
class TrackStore:
tracks: list[Track] = CustomList()
@classmethod
def load_all_tracks(cls, instance_key: str):
"""
Loads all tracks from the database into the store.
"""
print("Loading tracks... ", end="")
global TRACKS_LOAD_KEY
TRACKS_LOAD_KEY = instance_key
cls.tracks = CustomList(trackdb.get_all_tracks())
favs = favdb.get_fav_tracks()
records = dict()
for fav in favs:
if fav[1] not in records:
# if trackhash not in dict, add it
# and set the value to a set containing the userid
records[fav[1]] = {fav[4]}
# if trackhash is in dict, add the userid to the set
records[fav[1]].add(fav[4])
for track in cls.tracks:
if instance_key != TRACKS_LOAD_KEY:
return
try:
track.fav_userids = list(records[track.trackhash])
except KeyError:
track.fav_userids = []
# if track.trackhash in fav_hashes:
# fav = [t for t in favs if t["hash"] == track.trackhash][0]
# print(fav)
# track.favorite_data = [i["userid"] for i in fav]
print("Done!")
@classmethod
def add_track(cls, track: Track):
"""
Adds a single track to the store.
"""
cls.tracks.append(track)
@classmethod
def add_tracks(cls, tracks: list[Track]):
"""
Adds multiple tracks to the store.
"""
cls.tracks.extend(tracks)
@classmethod
def remove_track_obj(cls, track: Track):
"""
Removes a single track from the store.
"""
try:
cls.tracks.remove(track)
except ValueError:
pass
@classmethod
def remove_track_by_filepath(cls, filepath: str):
"""
Removes a track from the store by its filepath.
"""
for track in cls.tracks:
if track.filepath == filepath:
cls.remove_track_obj(track)
break
@classmethod
def remove_tracks_by_filepaths(cls, filepaths: set[str]):
"""
Removes multiple tracks from the store by their filepaths.
"""
for track in cls.tracks:
if track.filepath in filepaths:
cls.remove_track_obj(track)
@classmethod
def count_tracks_by_trackhash(cls, trackhash: str) -> int:
"""
Counts the number of tracks with a specific trackhash.
"""
return sum(1 for track in cls.tracks if track.trackhash == trackhash)
@classmethod
def make_track_fav(cls, trackhash: str):
"""
Adds a track to the favorites.
"""
for track in cls.tracks:
if track.trackhash == trackhash:
if current_user["id"] not in track.fav_userids:
track.fav_userids.append(current_user["id"])
@classmethod
def remove_track_from_fav(cls, trackhash: str):
"""
Removes a track from the favorites.
"""
for track in cls.tracks:
if track.trackhash == trackhash:
if current_user["id"] in track.fav_userids:
track.fav_userids.remove(current_user["id"])
@classmethod
def append_track_artists(
cls, albumhash: str, artists: list[str], new_album_title: str
):
tracks = cls.get_tracks_by_albumhash(albumhash)
for track in tracks:
track.add_artists(artists, new_album_title)
# ================================================
# ================== GETTERS =====================
# ================================================
@classmethod
def get_tracks_by_trackhashes(cls, trackhashes: list[str]) -> list[Track]:
"""
Returns a list of tracks by their hashes.
"""
hash_set = set(trackhashes)
set_len = len(hash_set)
tracks = []
for track in cls.tracks:
if track.trackhash in hash_set:
tracks.append(track)
if len(tracks) == set_len:
break
# sort the tracks in the order of the given trackhashes
tracks.sort(key=lambda t: trackhashes.index(t.trackhash))
return tracks
@classmethod
def get_tracks_by_filepaths(cls, paths: list[str]) -> list[Track]:
"""
Returns all tracks matching the given paths.
"""
tracks = sorted(cls.tracks, key=lambda x: x.filepath)
tracks = use_bisection(tracks, "filepath", paths)
return [track for track in tracks if track is not None]
@classmethod
def get_tracks_by_albumhash(cls, album_hash: str) -> list[Track]:
"""
Returns all tracks matching the given album hash.
"""
tracks = [t for t in cls.tracks if t.albumhash == album_hash]
return remove_duplicates(tracks, is_album_tracks=True)
@classmethod
def get_tracks_by_artisthash(cls, artisthash: str):
"""
Returns all tracks matching the given artist. Duplicate tracks are removed.
"""
tracks = [t for t in cls.tracks if artisthash in t.artist_hashes]
tracks = remove_duplicates(tracks)
tracks.sort(key=lambda x: x.last_mod)
return tracks
@classmethod
def get_tracks_in_path(cls, path: str):
"""
Returns all tracks in the given path.
"""
return (t for t in cls.tracks if t.folder.startswith(path))