db: Give playlists a default sort order

Most playlists sort by artist -> album -> year -> discno -> trackno, but
the Previous playlist sorts by rowid with the most recently added
tracks first, and the Up Next playlist sorts by rowid with the most
recently added tracks last.

Implements: Issue #13 (Give most playlists a default sort order)
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
Anna Schumaker 2021-10-14 14:18:36 -04:00
parent a52a815338
commit 0851aeb0cf
5 changed files with 35 additions and 15 deletions

View File

@ -61,7 +61,8 @@ class ParentPlaylist(Playlist):
class Model(table.Model):
def insert(self, *args, **kwargs):
loop = kwargs.pop("loop", False)
return super().insert(state.Table.insert(loop=loop), *args)
sort = kwargs.pop("sort", state.DefaultSort)
return super().insert(state.Table.insert(loop=loop,sort=sort), *args)
def delete(self, plist):
state.Table.delete(plist.plist_state)

View File

@ -9,6 +9,9 @@ from . import objects
from . import sql
from . import table
DefaultSort = [ "artists.sort ASC", "albums.sort ASC", "years.year ASC",
"discs.number ASC", "tracks.number ASC" ]
class PlaylistState(GObject.GObject):
def __init__(self, row):
GObject.GObject.__init__(self)
@ -39,11 +42,11 @@ class PlaylistState(GObject.GObject):
@current.setter
def current(self, newval): self._current = self.update("current", newval)
@GObject.Property(type=str)
def sort(self): return self._sort
@GObject.Property(type=GObject.TYPE_PYOBJECT)
def sort(self): return self._sort.split(",")
@sort.setter
def sort(self, newval): self._sort = self.update("sort", newval)
def sort(self, newval): self._sort = self.update("sort", ",".join(newval))
def update(self, column, newval):
sql.execute(f"UPDATE playlist_states SET {column}=? WHERE plstateid=?",
@ -67,9 +70,9 @@ class PlaylistStateTable(table.Table):
def do_factory(self, row):
return PlaylistState(row)
def do_insert(self, random=False, loop=False, sort=""):
def do_insert(self, random=False, loop=False, sort=DefaultSort):
return sql.execute("INSERT INTO playlist_states (random, loop, sort) "
"VALUES (?, ?, ?)", (random, loop, sort))
"VALUES (?, ?, ?)", (random, loop, ",".join(sort)))
Table = PlaylistStateTable()

View File

@ -39,11 +39,11 @@ class TestPlaylistState(unittest.TestCase):
def test_sort(self):
state = db.state.Table.insert()
self.assertEqual(state._sort, "")
self.assertEqual(state.sort, "")
self.assertEqual(state._sort, ",".join(db.state.DefaultSort))
self.assertEqual(state.sort, db.state.DefaultSort)
state.sort = "test"
self.assertEqual(state._sort, "test")
state.sort = [ "test", "sort" ]
self.assertEqual(state._sort, "test,sort" )
class TestPlaylistStateTable(unittest.TestCase):
@ -59,6 +59,13 @@ class TestPlaylistStateTable(unittest.TestCase):
db.sql.execute("SELECT plstateid,random,loop,current,sort "
"FROM playlist_states")
def test_default_sort(self):
self.assertEqual(db.state.DefaultSort[0], "artists.sort ASC")
self.assertEqual(db.state.DefaultSort[1], "albums.sort ASC")
self.assertEqual(db.state.DefaultSort[2], "years.year ASC")
self.assertEqual(db.state.DefaultSort[3], "discs.number ASC")
self.assertEqual(db.state.DefaultSort[4], "tracks.number ASC")
def test_insert(self):
table = db.state.PlaylistStateTable()
state = table.insert()
@ -66,7 +73,7 @@ class TestPlaylistStateTable(unittest.TestCase):
self.assertFalse(state.random)
self.assertFalse(state.loop)
self.assertEqual(state.current, -1)
self.assertEqual(state.sort, "")
self.assertEqual(state.sort, db.state.DefaultSort)
def test_lookup(self):
with self.assertRaises(NotImplementedError):

View File

@ -9,6 +9,7 @@ class TestCollection(unittest.TestCase):
collection = db.user.Table.find("Collection")
self.assertIsInstance(collection, db.user.UserPlaylist)
self.assertEqual(collection.icon_name, "media-playback-start")
self.assertTrue(collection.plist_state.loop)
class TestFavorites(unittest.TestCase):
@ -16,6 +17,7 @@ class TestFavorites(unittest.TestCase):
favorites = db.user.Table.find("Favorites")
self.assertIsInstance(favorites, db.user.UserPlaylist)
self.assertEqual(favorites.icon_name, "emmental-favorites")
self.assertFalse(favorites.plist_state.loop)
class TestNewTracks(unittest.TestCase):
@ -23,6 +25,7 @@ class TestNewTracks(unittest.TestCase):
new = db.user.Table.find("New Tracks")
self.assertIsInstance(new, db.user.UserPlaylist)
self.assertEqual(new.icon_name, "starred")
self.assertFalse(new.plist_state.loop)
class TestPrevious(unittest.TestCase):
@ -30,6 +33,8 @@ class TestPrevious(unittest.TestCase):
previous = db.user.Table.find("Previous")
self.assertIsInstance(previous, db.user.UserPlaylist)
self.assertEqual(previous.icon_name, "edit-undo")
self.assertEqual(previous.plist_state.sort, [ "rowid DESC" ])
self.assertFalse(previous.plist_state.loop)
class TestQueuedTracks(unittest.TestCase):
@ -37,6 +42,8 @@ class TestQueuedTracks(unittest.TestCase):
queued = db.user.Table.find("Queued Tracks")
self.assertIsInstance(queued, db.user.UserPlaylist)
self.assertEqual(queued.icon_name, "edit-redo")
self.assertEqual(queued.plist_state.sort, [ "rowid ASC" ])
self.assertFalse(queued.plist_state.loop)
class TestUserPlaylist(unittest.TestCase):
@ -46,6 +53,7 @@ class TestUserPlaylist(unittest.TestCase):
self.assertEqual(plist._name, "Test Playlist")
self.assertEqual(plist.get_property("name"), "Test Playlist")
self.assertEqual(plist.icon_name, "audio-x-generic")
self.assertFalse(plist.plist_state.loop)
def test_delete(self):
plist = db.user.Table.find("Test Playlist")

View File

@ -13,6 +13,7 @@ from gi.repository import GObject
from . import objects
from . import playlist
from . import sql
from . import state
from . import track
class UserPlaylist(playlist.Playlist):
@ -42,8 +43,8 @@ class UserTable(playlist.Model):
self.find("Collection", loop=True)
self.find("Favorites")
self.find("New Tracks")
self.find("Previous")
self.find("Queued Tracks")
self.find("Previous", sort=["rowid DESC"])
self.find("Queued Tracks", sort=["rowid ASC"])
def do_factory(self, row):
if row["name"] == "Collection":
@ -65,9 +66,9 @@ class UserTable(playlist.Model):
def do_lookup(self, name):
return sql.execute("SELECT * FROM playlists WHERE name=?", [ name ])
def find(self, name, loop=False):
def find(self, name, loop=False, sort=state.DefaultSort):
if (res := self.lookup(name)) == None:
res = self.insert(name, loop=loop)
res = self.insert(name, loop=loop, sort=sort)
return res