Users might have images or ripping logs mixed in with their tracks, so
let's make sure we don't crash if we try to scan one of these.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This lets me control size and justification of the text. Additionally, I
put everything into a scrolled window just in case a track has a really
long title name.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
I switch around the sidebar icons again, and also make the header bar
icons larger to make them easier to press with touchscreens
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
Library paths are directories on disk, so it makes sense to use the
folder-music icon to represent them.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
I'll eventually make this more complex when I add in more playlists, but
for now it just calls next on the Collection playlist
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
Converting between a TreeIter and a playlist is very useful, so
implement that functionality now.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
Some tracks in my library aren't formatted as expected, so let's improve
our parsing code to better handle integers.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This is a special tree model that translates our Playlist object into a
format that GTK understands.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
I was having trouble with bound methods when using notifications, since
all empty playlists were getting identified as the same empty list
object. Removing the inheritance fixes the problem.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This represents all tracks added to the collection, from across all
library paths. We also fix the value of Playlist.loop to "True" and
prevent changing it
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This makes removing tracks from playlists way easier, since there is
only ever one instance of the track.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
We want to make sure we get the expected results when calling next() on
empty playlists and with playlists that only have one track.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
I try to prevent the same track from getting selected twice in a row by
incrementing the current pointer rather than setting it directly, and
reducing the random range slightly.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
Now that we have a "new-track" notification, we can replace the add
function with a lookup function that more closely mirrors how we look up
album tags.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
We might want to use these outside of the playlist code, so let's move
this to a generic place so it can be easily used.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
The slash in the filepath was being intepreted as a subdirectory, so
let's change it into an underscore so everything is where we expect.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This replaces the code in playlist/__init__.py and turns it into a
class. This should make things easier to handle during testing, since we
can easily tear down the old instance and create a new one.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
I expect this will mostly get used by testing code as we create and
delete a bunch of different objects.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This is mostly needed by the UI but there are a few cases where we
might need it internally, such as adding newly creating tracks to all
the required playlists.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This playlist represents all tracks in a given subdirectory, and is how
we control adding or removing tracks.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
The intention is that different playlist types will create a subclass of
this class to do whatever work they need.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This lets us convert string fields into the corresponding track tag. I
intend to use this so playlists can have a custom sort function.
I eventually intend to add the matching __setitem__() function for
changing tags.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
I'll eventually need to be able to run everything as a single
application, so let's prepare for that now. This gives us a chance to
get the imports right from the start, rather than needing to go through
and fix things up again.
I also add a test to make sure everything works as expected.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
These functions pickle out the entire tag map onto disk. I also add a
stress test for the entire tags module that scans tracks using the
threadqueue, since that's how I intend everything to be used.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
There are cases, mostly during testing, where we might want to check if
a file exists or to remove it if it does. Let's add those functions
now so we can use them.
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>