119 lines
4.6 KiB
Python
119 lines
4.6 KiB
Python
# Copyright 2022 (c) Anna Schumaker
|
|
"""A custom Gio.ListModel for working with playlists."""
|
|
import sqlite3
|
|
from gi.repository import GObject
|
|
from . import playlist
|
|
|
|
|
|
class Playlist(playlist.Playlist):
|
|
"""Our custom Playlist with an image filepath."""
|
|
|
|
playlistid = GObject.Property(type=int)
|
|
image = GObject.Property(type=GObject.TYPE_PYOBJECT)
|
|
|
|
def do_update(self, column: str) -> None:
|
|
"""Update a playlist object."""
|
|
match (self.name, column, self.get_property(column)):
|
|
case ("Collection", "loop", "None"):
|
|
self.loop = "Playlist"
|
|
case ("Previous Tracks", "loop", "Playlist") | \
|
|
("Previous Tracks", "loop", "Track"):
|
|
self.loop = "None"
|
|
case ("Previous Tracks", "shuffle", True):
|
|
self.shuffle = False
|
|
case ("Previous Tracks", "sort-order", _):
|
|
if self.sort_order != "laststarted DESC":
|
|
self.sort_order = "laststarted DESC"
|
|
case (_, _, _): super().do_update(column)
|
|
|
|
def rename(self, new_name: str) -> bool:
|
|
"""Rename this playlist."""
|
|
return self.table.rename(self, new_name)
|
|
|
|
@property
|
|
def primary_key(self) -> int:
|
|
"""Get the playlist primary key."""
|
|
return self.playlistid
|
|
|
|
|
|
class Table(playlist.Table):
|
|
"""Our Playlist Table."""
|
|
|
|
collection = GObject.Property(type=Playlist)
|
|
favorites = GObject.Property(type=Playlist)
|
|
most_played = GObject.Property(type=Playlist)
|
|
new_tracks = GObject.Property(type=Playlist)
|
|
previous = GObject.Property(type=Playlist)
|
|
queued = GObject.Property(type=Playlist)
|
|
unplayed = GObject.Property(type=Playlist)
|
|
|
|
def __init__(self, sql: GObject.TYPE_PYOBJECT, **kwargs):
|
|
"""Initialize the Playlists Table."""
|
|
super().__init__(sql=sql, **kwargs)
|
|
|
|
def do_construct(self, **kwargs) -> Playlist:
|
|
"""Construct a new playlist."""
|
|
match (plist := Playlist(**kwargs)).name:
|
|
case "Collection": self.collection = plist
|
|
case "Favorite Tracks":
|
|
self.favorites = plist
|
|
self.favorites.user_tracks = True
|
|
case "Most Played Tracks": self.most_played = plist
|
|
case "New Tracks": self.new_tracks = plist
|
|
case "Previous Tracks": self.previous = plist
|
|
case "Queued Tracks":
|
|
self.queued = plist
|
|
self.queued.user_tracks = True
|
|
self.queued.tracks_movable = True
|
|
case "Unplayed Tracks": self.unplayed = plist
|
|
case _:
|
|
plist.user_tracks = True
|
|
plist.tracks_movable = True
|
|
return plist
|
|
|
|
def do_sql_delete(self, playlist: Playlist) -> sqlite3.Cursor:
|
|
"""Delete a playlist."""
|
|
return self.sql("DELETE FROM playlists WHERE playlistid=?",
|
|
playlist.playlistid)
|
|
|
|
def do_sql_glob(self, glob: str) -> sqlite3.Cursor:
|
|
"""Search for playlists matching the search text."""
|
|
return self.sql("""SELECT playlistid FROM playlists
|
|
WHERE CASEFOLD(name) GLOB ?""", glob)
|
|
|
|
def do_sql_insert(self, name: str, **kwargs) -> sqlite3.Cursor | None:
|
|
"""Insert a new playlist into the database."""
|
|
if (cur := self.sql("INSERT INTO playlists (name) VALUES (?)", name)):
|
|
return self.sql("SELECT * FROM playlists_view WHERE playlistid=?",
|
|
cur.lastrowid)
|
|
|
|
def do_sql_select_all(self) -> sqlite3.Cursor:
|
|
"""Load playlists from the database."""
|
|
return self.sql("SELECT * FROM playlists_view")
|
|
|
|
def do_sql_select_one(self, name: str) -> sqlite3.Cursor:
|
|
"""Look up a playlist by name."""
|
|
return self.sql("SELECT playlistid FROM playlists WHERE name=?", name)
|
|
|
|
def do_sql_update(self, playlist: Playlist,
|
|
column: str, newval) -> sqlite3.Cursor:
|
|
"""Update a playlist."""
|
|
return self.sql(f"UPDATE playlists SET {column}=? WHERE playlistid=?",
|
|
newval, playlist.playlistid)
|
|
|
|
def create(self, name: str) -> Playlist:
|
|
"""Create a new Playlist."""
|
|
if len(name := name.strip()) > 0:
|
|
return super().create(name)
|
|
|
|
def rename(self, playlist: Playlist, new_name: str) -> bool:
|
|
"""Rename a Playlist."""
|
|
if len(new_name := new_name.strip()) > 0:
|
|
if playlist.name != new_name:
|
|
if self.update(playlist, "name", new_name):
|
|
self.store.remove(playlist)
|
|
playlist.name = new_name
|
|
self.store.append(playlist)
|
|
return True
|
|
return False
|