emmental/emmental/db/playlists.py

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