mirror of
https://github.com/tcsenpai/swingmusic.git
synced 2025-06-06 03:05:35 +00:00
implement pinning playlists
+ update migrations to add pinned attr to plalist + misc
This commit is contained in:
parent
c3c9cb059f
commit
e3a61c109b
@ -97,7 +97,12 @@ def insert_playlist(name: str, image: str = None):
|
||||
"name": name,
|
||||
"trackhashes": json.dumps([]),
|
||||
"settings": json.dumps(
|
||||
{"has_gif": False, "banner_pos": 50, "square_img": True if image else False}
|
||||
{
|
||||
"has_gif": False,
|
||||
"banner_pos": 50,
|
||||
"square_img": True if image else False,
|
||||
"pinned": False,
|
||||
}
|
||||
),
|
||||
}
|
||||
|
||||
@ -170,12 +175,12 @@ def add_item_to_playlist(playlist_id: str):
|
||||
itemtype = None
|
||||
|
||||
try:
|
||||
itemhash = data["itemhash"]
|
||||
itemhash: str = data["itemhash"]
|
||||
except KeyError:
|
||||
itemhash = None
|
||||
|
||||
if itemtype == "track":
|
||||
trackhashes = [itemhash]
|
||||
if itemtype == "tracks":
|
||||
trackhashes = itemhash.split(",")
|
||||
elif itemtype == "folder":
|
||||
trackhashes = get_path_trackhashes(itemhash)
|
||||
elif itemtype == "album":
|
||||
@ -190,8 +195,6 @@ def add_item_to_playlist(playlist_id: str):
|
||||
if insert_count == 0:
|
||||
return {"error": "Item already exists in playlist"}, 409
|
||||
|
||||
PL.update_last_updated(int(playlist_id))
|
||||
|
||||
return {"msg": "Done"}, 200
|
||||
|
||||
|
||||
@ -220,13 +223,6 @@ def get_playlist(playlistid: str):
|
||||
if not playlist.has_image:
|
||||
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.clear_lists()
|
||||
|
||||
return {"info": playlist, "tracks": tracks if not no_tracks else []}
|
||||
@ -288,6 +284,28 @@ def update_playlist_info(playlistid: str):
|
||||
}
|
||||
|
||||
|
||||
@api.route("/playlist/<playlistid>/pin_unpin", methods=["GET"])
|
||||
def pin_unpin_playlist(playlistid: str):
|
||||
"""
|
||||
Pins or unpins a playlist.
|
||||
"""
|
||||
playlist = PL.get_playlist_by_id(int(playlistid))
|
||||
|
||||
if playlist is None:
|
||||
return {"error": "Playlist not found"}, 404
|
||||
|
||||
settings = playlist.settings
|
||||
|
||||
try:
|
||||
settings["pinned"] = not settings["pinned"]
|
||||
except KeyError:
|
||||
settings["pinned"] = True
|
||||
|
||||
PL.update_settings(int(playlistid), settings)
|
||||
|
||||
return {"msg": "Done"}, 200
|
||||
|
||||
|
||||
@api.route("/playlist/<playlistid>/remove-img", methods=["GET"])
|
||||
def remove_playlist_image(playlistid: str):
|
||||
"""
|
||||
@ -308,7 +326,6 @@ def remove_playlist_image(playlistid: str):
|
||||
|
||||
playlist.images = get_first_4_images(trackhashes=playlist.trackhashes)
|
||||
playlist.last_updated = date_string_to_time_passed(playlist.last_updated)
|
||||
PL.update_last_updated(pid)
|
||||
|
||||
return {"playlist": playlist}, 200
|
||||
|
||||
@ -334,24 +351,6 @@ def remove_playlist():
|
||||
return {"msg": "Done"}, 200
|
||||
|
||||
|
||||
@api.route("/playlist/<pid>/set-image-pos", methods=["POST"])
|
||||
def update_image_position(pid: int):
|
||||
data = request.get_json()
|
||||
message = {"msg": "No data provided"}
|
||||
|
||||
if data is None:
|
||||
return message, 400
|
||||
|
||||
try:
|
||||
pos = data["pos"]
|
||||
except KeyError:
|
||||
return message, 400
|
||||
|
||||
PL.update_banner_pos(pid, pos)
|
||||
|
||||
return {"msg": "Image position saved"}, 200
|
||||
|
||||
|
||||
@api.route("/playlist/<pid>/remove-tracks", methods=["POST"])
|
||||
def remove_tracks_from_playlist(pid: int):
|
||||
data = request.get_json()
|
||||
@ -366,7 +365,6 @@ def remove_tracks_from_playlist(pid: int):
|
||||
|
||||
tracks = data["tracks"]
|
||||
PL.remove_tracks_from_playlist(pid, tracks)
|
||||
PL.update_last_updated(pid)
|
||||
|
||||
return {"msg": "Done"}, 200
|
||||
|
||||
@ -404,30 +402,29 @@ def save_item_as_playlist():
|
||||
if itemtype is None or playlist_name is None or itemhash is None:
|
||||
return msg
|
||||
|
||||
if itemtype == "track":
|
||||
trackhashes = [itemhash]
|
||||
if itemtype == "tracks":
|
||||
trackhashes = itemhash.split(",")
|
||||
elif itemtype == "folder":
|
||||
trackhashes = get_path_trackhashes(itemhash)
|
||||
elif itemtype == "album":
|
||||
trackhashes = get_album_trackhashes(itemhash)
|
||||
elif itemtype == "artist":
|
||||
trackhashes = get_artist_trackhashes(itemhash)
|
||||
elif itemtype == "queue":
|
||||
trackhashes = itemhash.split(",")
|
||||
else:
|
||||
trackhashes = []
|
||||
|
||||
if len(trackhashes) == 0:
|
||||
return {"error": "No tracks founds"}, 404
|
||||
|
||||
image = itemhash + ".webp" if itemtype != "folder" and itemtype != "queue" else None
|
||||
image = itemhash + ".webp" if itemtype != "folder" and itemtype != "tracks" else None
|
||||
|
||||
playlist = insert_playlist(playlist_name, image)
|
||||
|
||||
if playlist is None:
|
||||
return {"error": "Playlist could not be created"}, 500
|
||||
|
||||
if itemtype != "folder" and itemtype != "queue":
|
||||
# save image
|
||||
if itemtype != "folder" and itemtype != "tracks":
|
||||
filename = itemhash + ".webp"
|
||||
|
||||
base_path = (
|
||||
@ -444,6 +441,5 @@ def save_item_as_playlist():
|
||||
)
|
||||
|
||||
PL.add_tracks_to_playlist(playlist.id, trackhashes)
|
||||
PL.update_last_updated(playlist.id)
|
||||
|
||||
return {"playlist": playlist}, 201
|
||||
|
@ -13,6 +13,14 @@ class SQLitePlaylistMethods:
|
||||
This class contains methods for interacting with the playlists table.
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def update_last_updated(playlist_id: int):
|
||||
"""Updates the last updated date of a playlist."""
|
||||
sql = """UPDATE playlists SET last_updated = ? WHERE id = ?"""
|
||||
|
||||
with SQLiteManager(userdata_db=True) as cur:
|
||||
cur.execute(sql, (create_new_date(), playlist_id))
|
||||
|
||||
@staticmethod
|
||||
def insert_one_playlist(playlist: dict):
|
||||
# banner_pos,
|
||||
@ -92,8 +100,8 @@ class SQLitePlaylistMethods:
|
||||
|
||||
# FIXME: Extract the "add_track_to_playlist" method to use it for both the artisthash and trackhash lists.
|
||||
|
||||
@staticmethod
|
||||
def add_item_to_json_list(playlist_id: int, field: str, items: set[str]):
|
||||
@classmethod
|
||||
def add_item_to_json_list(cls, playlist_id: int, field: str, items: set[str]):
|
||||
"""
|
||||
Adds a string item to a json dumped list using a playlist id and field name.
|
||||
Takes the playlist ID, a field name, an item to add to the field.
|
||||
@ -118,6 +126,8 @@ class SQLitePlaylistMethods:
|
||||
cur.execute(sql, (json.dumps(db_items), playlist_id))
|
||||
return len(items)
|
||||
|
||||
cls.update_last_updated(playlist_id)
|
||||
|
||||
@classmethod
|
||||
def add_tracks_to_playlist(cls, playlist_id: int, trackhashes: list[str]):
|
||||
"""
|
||||
@ -125,8 +135,8 @@ class SQLitePlaylistMethods:
|
||||
"""
|
||||
return cls.add_item_to_json_list(playlist_id, "trackhashes", trackhashes)
|
||||
|
||||
@staticmethod
|
||||
def update_playlist(playlist_id: int, playlist: dict):
|
||||
@classmethod
|
||||
def update_playlist(cls, playlist_id: int, playlist: dict):
|
||||
sql = """UPDATE playlists SET
|
||||
image = ?,
|
||||
last_updated = ?,
|
||||
@ -145,13 +155,16 @@ class SQLitePlaylistMethods:
|
||||
with SQLiteManager(userdata_db=True) as cur:
|
||||
cur.execute(sql, params)
|
||||
|
||||
@staticmethod
|
||||
def update_last_updated(playlist_id: int):
|
||||
"""Updates the last updated date of a playlist."""
|
||||
sql = """UPDATE playlists SET last_updated = ? WHERE id = ?"""
|
||||
cls.update_last_updated(playlist_id)
|
||||
|
||||
@classmethod
|
||||
def update_settings(cls, playlist_id: int, settings: dict):
|
||||
sql = """UPDATE playlists SET settings = ? WHERE id = ?"""
|
||||
|
||||
with SQLiteManager(userdata_db=True) as cur:
|
||||
cur.execute(sql, (create_new_date(), playlist_id))
|
||||
cur.execute(sql, (json.dumps(settings), playlist_id))
|
||||
|
||||
cls.update_last_updated(playlist_id)
|
||||
|
||||
@staticmethod
|
||||
def delete_playlist(pid: str):
|
||||
@ -160,21 +173,6 @@ class SQLitePlaylistMethods:
|
||||
with SQLiteManager(userdata_db=True) as cur:
|
||||
cur.execute(sql, (pid,))
|
||||
|
||||
@staticmethod
|
||||
def update_banner_pos(playlistid: int, pos: int):
|
||||
playlist = SQLitePlaylistMethods.get_playlist_by_id(playlistid)
|
||||
|
||||
if playlist is None:
|
||||
return
|
||||
|
||||
playlist.settings["banner_pos"] = pos
|
||||
settings_str = json.dumps(playlist.settings)
|
||||
|
||||
sql = """UPDATE playlists SET settings = ? WHERE id = ?"""
|
||||
|
||||
with SQLiteManager(userdata_db=True) as cur:
|
||||
cur.execute(sql, (settings_str, playlistid))
|
||||
|
||||
@staticmethod
|
||||
def remove_banner(playlistid: int):
|
||||
sql = """UPDATE playlists SET image = NULL WHERE id = ?"""
|
||||
@ -182,8 +180,8 @@ class SQLitePlaylistMethods:
|
||||
with SQLiteManager(userdata_db=True) as cur:
|
||||
cur.execute(sql, (playlistid,))
|
||||
|
||||
@staticmethod
|
||||
def remove_tracks_from_playlist(playlistid: int, tracks: list[dict[str, int]]):
|
||||
@classmethod
|
||||
def remove_tracks_from_playlist(cls, playlistid: int, tracks: list[dict[str, int]]):
|
||||
"""
|
||||
Removes tracks from a playlist by trackhash and position.
|
||||
"""
|
||||
@ -211,3 +209,5 @@ class SQLitePlaylistMethods:
|
||||
trackhashes.remove(track["trackhash"])
|
||||
|
||||
cur.execute(sql, (json.dumps(trackhashes), playlistid))
|
||||
|
||||
cls.update_last_updated(playlistid)
|
||||
|
@ -40,8 +40,8 @@ def extract_thumb(filepath: str, webp_path: str, overwrite=False) -> bool:
|
||||
img.resize((tsize, tsize), Image.ANTIALIAS).save(lg_img_path, "webp")
|
||||
img.resize((sm_tsize, sm_tsize), Image.ANTIALIAS).save(sm_img_path, "webp")
|
||||
|
||||
if not overwrite and os.path.exists(lg_img_path):
|
||||
img_size = os.path.getsize(lg_img_path)
|
||||
if not overwrite and os.path.exists(sm_img_path):
|
||||
img_size = os.path.getsize(sm_img_path)
|
||||
|
||||
if img_size > 0:
|
||||
return True
|
||||
|
@ -69,8 +69,6 @@ class AddSettingsToPlaylistTable(Migration):
|
||||
|
||||
@staticmethod
|
||||
def migrate():
|
||||
# existing_playlists = []
|
||||
|
||||
select_playlists_sql = "SELECT * FROM playlists"
|
||||
|
||||
with SQLiteManager(userdata_db=True) as cur:
|
||||
@ -117,6 +115,7 @@ class AddSettingsToPlaylistTable(Migration):
|
||||
"has_gif": False,
|
||||
"banner_pos": playlist[1],
|
||||
"square_img": False,
|
||||
"pinned": False,
|
||||
}
|
||||
),
|
||||
}
|
||||
|
@ -22,13 +22,15 @@ class Playlist:
|
||||
duration: int = 0
|
||||
has_image: bool = False
|
||||
images: list[str] = dataclasses.field(default_factory=list)
|
||||
pinned: bool = False
|
||||
|
||||
def __post_init__(self):
|
||||
self.trackhashes = json.loads(str(self.trackhashes))
|
||||
self.count = len(self.trackhashes)
|
||||
|
||||
if isinstance(self.settings, str):
|
||||
self.settings = json.loads(self.settings)
|
||||
self.settings = dict(json.loads(self.settings))
|
||||
self.pinned = self.settings.get("pinned", False)
|
||||
|
||||
self.has_image = (
|
||||
Path(settings.Paths.get_playlist_img_path()) / str(self.image)
|
||||
|
Loading…
x
Reference in New Issue
Block a user