I also adjust how filtering Artists works so an Artist remains visible
if one of its Media matches the query.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
We create a filter on the Media table for each Album object, but
only match Media that have a name set. I also adjust filtering to
display Albums that have a matching Medium.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This table represents an individual medium in an album (such as a single
CD). Each medium has an associated album, number, type, and (optional)
title. This means we can have multiple media for a given album as long
as they each have a different number or type.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
I use a sql link table to accomplish this so a single album can be added
to multiple album-artists. Additionally, I set up a view on Artists and
Albums to make filtering easier without needing to use a complicated
join every time.
Additionally, I use the Playlist.add_children() function to set up a
filter on the Album list model for each Artist's albums.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This table allows us to work with Album playlists that have a name,
album artist, release date, (optional) mbid, and (optional) cover.
Note that we can insert multiple albums with the same name as long as
their mbid, artist, or release date is different.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This table allows us to work with Artist playlists that have a name and
(optional) mbid. Note that we can insert multiple artists with the same
name into the database as long as they have different mbids.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This inherits from our base playlist Table class, and implements
functions for creating and renaming playlists. Additionally, the
Playlist object allows for setting a custom image to display as an icon
in the sidebar.
Finally, I add in a custom sqlite3 adapter and converter to support
pathlib.Path types in the database.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This is an implementation of an emmental.db.table.Table that adds
support for creating Playlists, updating playlist properties, sorting
based on playlist name, and displaying playlists with their child
playlists in a tree structure.
Additionally, I create a playlist_properties table in the database to store
properties that all playlists have.
Implements: #17 ("Save currently selected playlist")
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This object inherits from the table.Row base class. It adds in
properties for name, active state, and propertyid and a rename()
function for updating the Table sort order during a rename.
Additionally, child playlists can be enabled by calling add_children().
This will set up a Gtk.FilterListModel using the provide child Table and
Filter.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
Tables use the idle queue to load their data or filter rows in the
background. Tables will create a new queue by default, but can accept a
pre-constructed queue through the queue= parameter.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This is intended to be used as a base class for other task-specific
Queues, and runs each task under a single transaction. Queue
implementations should override the do_run_task() function for their
implementation-specific work.
The push_many() function can be used to efficiently add several tasks to
the Queue at the same time.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This creates a new class to dynamically create GObject Properties, save
them to the database, and make it easy to bind application properties to
specific settings properties.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This is a Gtk.FilterListModel containing a store.SortedList to store
individual rows in sorted order. I also implemented some convenience
functions to make it easier to add, remove, look up, and filter rows.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This filter takes a set of primary keys for rows that should be visible
during filtering. Passing None as a value means that all rows are shown.
It also has functions for adding or removing individual rows from the
filter.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This will be shared between settings, playlists, and tracks so we have a
common interface for working with database rows.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This inherits from the base Connection manager and adds in reading our
sql script to set up the database. It will also eventually hold pointers
to table objects that we can access directly.
Finally, I add a db property to the Application instance. The db is
connected during the ::startup signal handler, and disconnected during
the ::shutdown signal handler.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This is a wrapper around the sqlite3.Connection objct that adds some
nice functionality to make working with SQL easier.
I defined the following magic methods:
* __enter__() to manually begin a transaction
* __exit__() to commit or rollback a manual transaction
* __call__() to execute a SQL statement with either positional or
keyword arguments.
Additionally:
* I define a "CASEFOLD" function that can be used in queries
to lowercase unicode text when searching.
* I set foreign_keys = ON so foreign keys checking is always enabled
* I provide an executemany() function for running running the same
statement multiple times with different arguments.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>