From 6439b512e9492fc839fcb8ca8bcda07e652113f3 Mon Sep 17 00:00:00 2001 From: mungai-njoroge Date: Fri, 21 Jul 2023 01:15:57 +0300 Subject: [PATCH] preset mimetypes + add db and api methods to remove tracks from playlists --- app/api/playlist.py | 55 ++++++++++++++++++++++++++++++-------- app/db/sqlite/playlists.py | 31 +++++++++++++++++++++ app/models/album.py | 5 ++++ app/utils/parsers.py | 35 +++++++++++++----------- manage.py | 13 +++++++++ 5 files changed, 112 insertions(+), 27 deletions(-) diff --git a/app/api/playlist.py b/app/api/playlist.py index c1c7abf..baf35c9 100644 --- a/app/api/playlist.py +++ b/app/api/playlist.py @@ -10,6 +10,7 @@ from PIL import UnidentifiedImageError from app import models from app.db.sqlite.playlists import SQLitePlaylistMethods from app.lib import playlistlib +from app.models.track import Track from app.utils.dates import date_string_to_time_passed, create_new_date from app.utils.remove_duplicates import remove_duplicates @@ -31,36 +32,44 @@ update_playlist = PL.update_playlist delete_playlist = PL.delete_playlist -# get_tracks_by_trackhashes = SQLiteTrackMethods.get_tracks_by_trackhashes def duplicate_images(images: list): if len(images) == 1: images *= 4 elif len(images) == 2: images += list(reversed(images)) elif len(images) == 3: - images = images + images[:1] + images = images + images[:] return images -def get_first_4_images(trackhashes: list[str]) -> list[dict['str', str]]: - tracks = TrackStore.get_tracks_by_trackhashes(trackhashes) +def get_first_4_images( + tracks: list[Track] = [], trackhashes: list[str] = [] +) -> list[dict["str", str]]: + if len(trackhashes) > 0: + tracks = TrackStore.get_tracks_by_trackhashes(trackhashes) + albums = [] for track in tracks: if track.albumhash not in albums: albums.append(track.albumhash) + if len(albums) == 4: break albums = AlbumStore.get_albums_by_hashes(albums) images = [ { - 'image': album.image, - 'color': ''.join(album.colors), + "image": album.image, + "color": "".join(album.colors), } for album in albums ] + + if len(images) == 4: + return images + return duplicate_images(images) @@ -77,8 +86,8 @@ def send_all_playlists(): for playlist in playlists: if not no_images: - playlist.images = get_first_4_images(playlist.trackhashes) - playlist.images = [img['image'] for img in playlist.images] + playlist.images = get_first_4_images(trackhashes=playlist.trackhashes) + playlist.images = [img["image"] for img in playlist.images] playlist.clear_lists() @@ -151,6 +160,9 @@ def get_playlist(playlistid: str): """ Gets a playlist by id, and if it exists, it gets all the tracks in the playlist and returns them. """ + no_tracks = request.args.get("no_tracks", False) + no_tracks = no_tracks == "true" + playlist = get_playlist_by_id(int(playlistid)) if playlist is None: @@ -165,15 +177,18 @@ def get_playlist(playlistid: str): playlist.set_duration(duration) if not playlist.has_image: - playlist.images = get_first_4_images(playlist.trackhashes) + playlist.images = get_first_4_images(tracks) if len(playlist.images) > 2: # swap 3rd image with first (3rd image is the visible image in UI) - playlist.images[2], playlist.images[0] = playlist.images[0], playlist.images[2] + playlist.images[2], playlist.images[0] = ( + playlist.images[0], + playlist.images[2], + ) playlist.clear_lists() - return {"info": playlist, "tracks": tracks} + return {"info": playlist, "tracks": tracks if not no_tracks else []} @api.route("/playlist//update", methods=["PUT"]) @@ -267,3 +282,21 @@ def update_image_position(pid: int): PL.update_banner_pos(pid, pos) return {"msg": "Image position saved"}, 200 + + +@api.route("/playlist//remove-tracks", methods=["POST"]) +def remove_tracks_from_playlist(pid: int): + data = request.get_json() + + if data is None: + return {"error": "Track index not provided"}, 400 + + # { + # trackhash: str; + # index: int; + # } + + tracks = data["tracks"] + PL.remove_tracks_from_playlist(pid, tracks) + + return {"msg": "Done"}, 200 diff --git a/app/db/sqlite/playlists.py b/app/db/sqlite/playlists.py index 68bd2d5..75e97f6 100644 --- a/app/db/sqlite/playlists.py +++ b/app/db/sqlite/playlists.py @@ -176,3 +176,34 @@ class SQLitePlaylistMethods: with SQLiteManager(userdata_db=True) as cur: cur.execute(sql, (pos, playlistid)) + + @staticmethod + def remove_tracks_from_playlist(playlistid: int, tracks: list[dict[str, int]]): + """ + Removes tracks from a playlist by trackhash and position. + """ + + sql = """UPDATE playlists SET trackhashes = ? WHERE id = ?""" + + with SQLiteManager(userdata_db=True) as cur: + cur.execute("SELECT trackhashes FROM playlists WHERE id = ?", (playlistid,)) + data = cur.fetchone() + + if data is None: + return + + trackhashes: list[str] = json.loads(data[0]) + print(tracks) + + for track in tracks: + # { + # trackhash: str; + # index: int; + # } + + index = trackhashes.index(track["trackhash"]) + + if index == track["index"]: + trackhashes.remove(track["trackhash"]) + + cur.execute(sql, (json.dumps(trackhashes), playlistid)) diff --git a/app/models/album.py b/app/models/album.py index 7bd9f90..83248e6 100644 --- a/app/models/album.py +++ b/app/models/album.py @@ -69,6 +69,11 @@ class Album: if "super_deluxe" in self.versions: self.versions.remove("deluxe") + t_ = "taylors_version" + if t_ in self.versions: + self.versions.remove(t_) + self.versions.insert(0, "taylor's version") + self.versions = [v.replace("_", " ") for v in self.versions] else: self.base_title = get_base_title_and_versions( diff --git a/app/utils/parsers.py b/app/utils/parsers.py index a9349b9..f14685a 100644 --- a/app/utils/parsers.py +++ b/app/utils/parsers.py @@ -120,12 +120,13 @@ class AlbumVersionEnum(Enum): Explicit = ("explicit",) - ANNIVERSARY = ("anniversary",) - DIAMOND = ("diamond",) - Centennial = ("centennial",) - GOLDEN = ("gold",) - PLATINUM = ("platinum",) - SILVER = ("silver",) + ANNIVERSARY_EDITION = ("anniversary",) + DIAMOND_EDITION = ("diamond",) + Centennial_EDITION = ("centennial",) + GOLDEN_EDITION = ("gold",) + PLATINUM_EDITION = ("platinum",) + SILVER_EDITION = ("silver",) + ULTIMATE_EDITION = ("ultimate",) EXPANDED = ("expanded",) EXTENDED = ("extended",) @@ -134,19 +135,20 @@ class AlbumVersionEnum(Enum): SUPER_DELUXE = ("super deluxe",) COMPLETE = ("complete",) - LEGACY = ("legacy",) - SPECIAL = ("special",) + LEGACY_EDITION = ("legacy",) + SPECIAL_EDITION = ("special",) COLLECTORS_EDITION = ("collector",) - ARCHIVE = ("archive",) + ARCHIVE_EDITION = ("archive",) Acoustic = ("acoustic",) DOUBLE_DISC = ("double disc", "double disk") - SUMMER = ("summer",) - WINTER = ("winter",) - SPRING = ("spring",) - FALL = ("fall",) + SUMMER_EDITION = ("summer",) + WINTER_EDITION = ("winter",) + SPRING_EDITION = ("spring",) + FALL_EDITION = ("fall",) + BONUS_EDITION = ("bonus",) BONUS_TRACK = ("bonus track",) ORIGINAL = ("original",) @@ -154,7 +156,7 @@ class AlbumVersionEnum(Enum): UK_VERSION = ("uk version",) US_VERSION = ("us version",) - Limited = ("limited",) + Limited_EDITION = ("limited",) MONO = ("mono",) STEREO = ("stereo",) @@ -163,7 +165,8 @@ class AlbumVersionEnum(Enum): RE_MIX = ("re-mix",) RE_RECORDED = ("re-recorded", "rerecorded") REISSUE = ("reissue",) - REMASTER = ("remaster",) + REMASTERED = ("remaster",) + TAYLORS_VERSION = ("taylor's version",) def get_anniversary(text: str) -> str | None: @@ -208,7 +211,7 @@ def get_base_title_and_versions( Extracts the base album title and version info from an album title string using regex. """ album_title, version_block = get_base_album_title(original_album_title) - + if version_block is None: return original_album_title, [] diff --git a/manage.py b/manage.py index 00fa80f..f1df73c 100644 --- a/manage.py +++ b/manage.py @@ -2,6 +2,7 @@ This file is used to run the application. """ import logging +import mimetypes from app.api import create_api from app.arg_handler import HandleArgs @@ -14,6 +15,18 @@ from app.utils.filesystem import get_home_res_path from app.utils.threading import background from alive_progress import config_handler +mimetypes.add_type("text/css", ".css") +mimetypes.add_type("text/javascript", ".js") +mimetypes.add_type("text/plain", ".txt") +mimetypes.add_type("text/html", ".html") +mimetypes.add_type("image/webp", ".webp") +mimetypes.add_type("image/svg+xml", ".svg") +mimetypes.add_type("image/png", ".png") +mimetypes.add_type("image/vnd.microsoft.icon", ".ico") +mimetypes.add_type("image/gif", ".gif") +mimetypes.add_type("font/woff", ".woff") +mimetypes.add_type("application/manifest+json", ".webmanifest") + werkzeug = logging.getLogger("werkzeug") werkzeug.setLevel(logging.ERROR)