Anna Schumaker
0754f10883
This was only used by system playlists to keep the unplayed, most played, and least played playlist up to date. We can handle this internally through the playlist_played() handler. Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
185 lines
4.2 KiB
C
185 lines
4.2 KiB
C
/*
|
|
* Copyright 2016 (c) Anna Schumaker.
|
|
*/
|
|
#include <core/idle.h>
|
|
#include <core/playlists/artist.h>
|
|
#include <core/string.h>
|
|
|
|
static struct queue_ops *artist_ops = NULL;
|
|
static struct file artist_file = FILE_INIT("playlist.artist", 0);
|
|
|
|
static struct playlist_ops pl_artist_ops = {
|
|
.pl_can_select = playlist_generic_can_select,
|
|
.pl_next = playlist_generic_next,
|
|
.pl_set_flag = playlist_generic_set_flag,
|
|
.pl_sort = playlist_generic_sort,
|
|
};
|
|
|
|
|
|
static struct playlist *__artist_pl_alloc(struct artist *artist)
|
|
{
|
|
struct playlist *playlist = g_malloc(sizeof(struct playlist));
|
|
|
|
playlist->pl_name = artist->ar_name;
|
|
playlist->pl_type = PL_ARTIST;
|
|
playlist->pl_id = artist_index(artist);
|
|
playlist->pl_ops = &pl_artist_ops;
|
|
playlist_generic_init(playlist, 0, artist_ops);
|
|
|
|
return playlist;
|
|
}
|
|
|
|
static void __artist_pl_free(struct playlist *playlist)
|
|
{
|
|
if (playlist) {
|
|
queue_deinit(&playlist->pl_queue);
|
|
g_free(playlist);
|
|
}
|
|
}
|
|
|
|
static bool __artist_pl_add(void *data)
|
|
{
|
|
struct playlist *playlist = (struct playlist *)data;
|
|
struct artist *artist = artist_lookup(playlist->pl_name);
|
|
struct db_entry *dbe, *next;
|
|
|
|
db_for_each(dbe, next, track_db_get()) {
|
|
if (TRACK(dbe)->tr_album->al_artist == artist)
|
|
queue_add_front(&playlist->pl_queue, TRACK(dbe));
|
|
}
|
|
|
|
queue_resort(&playlist->pl_queue);
|
|
return true;
|
|
}
|
|
|
|
static struct playlist *__artist_pl_lookup(const gchar *name)
|
|
{
|
|
struct artist *artist = artist_lookup(name);
|
|
return artist ? artist->ar_playlist : NULL;
|
|
}
|
|
|
|
static bool __artist_pl_load(void *data)
|
|
{
|
|
struct playlist *playlist;
|
|
unsigned int i, n;
|
|
gchar *name;
|
|
|
|
if (!file_open(&artist_file, OPEN_READ))
|
|
return true;
|
|
|
|
file_readf(&artist_file, "%u\n", &n);
|
|
for (i = 0; i < n; i++) {
|
|
name = file_readl(&artist_file);
|
|
playlist = __artist_pl_lookup(name);
|
|
g_free(name);
|
|
|
|
if (!playlist)
|
|
continue;
|
|
queue_load_flags(&playlist->pl_queue, &artist_file, true);
|
|
queue_iter_set(&playlist->pl_queue, &playlist->pl_queue.q_cur,
|
|
playlist->pl_queue.q_cur.it_pos);
|
|
}
|
|
|
|
file_close(&artist_file);
|
|
return true;
|
|
}
|
|
|
|
|
|
static void pl_artist_save(void)
|
|
{
|
|
struct db_entry *dbe, *next;
|
|
struct playlist *playlist;
|
|
|
|
if (!file_open(&artist_file, OPEN_WRITE))
|
|
return;
|
|
|
|
file_writef(&artist_file, "%u\n", artist_db_get()->db_size);
|
|
db_for_each(dbe, next, artist_db_get()) {
|
|
playlist = ARTIST(dbe)->ar_playlist;
|
|
file_writef(&artist_file, "%s\n", playlist->pl_name);
|
|
queue_save_flags(&playlist->pl_queue, &artist_file, true);
|
|
}
|
|
|
|
file_close(&artist_file);
|
|
}
|
|
|
|
static struct playlist *pl_artist_lookup(const gchar *name)
|
|
{
|
|
return __artist_pl_lookup(name);
|
|
}
|
|
|
|
static struct playlist *pl_artist_get(unsigned int id)
|
|
{
|
|
struct artist *artist = artist_get(id);
|
|
return artist ? artist->ar_playlist : NULL;
|
|
}
|
|
|
|
static void pl_artist_played(struct track *track)
|
|
{
|
|
struct artist *artist = track->tr_album->al_artist;
|
|
struct playlist *playlist = (struct playlist *)artist->ar_playlist;
|
|
if (playlist)
|
|
queue_updated(&playlist->pl_queue, track);
|
|
}
|
|
|
|
|
|
struct playlist_type pl_artist = {
|
|
.pl_save = pl_artist_save,
|
|
.pl_lookup = pl_artist_lookup,
|
|
.pl_get = pl_artist_get,
|
|
.pl_played = pl_artist_played,
|
|
};
|
|
|
|
|
|
void pl_artist_init(struct queue_ops *ops)
|
|
{
|
|
struct db_entry *dbe, *next;
|
|
struct playlist *playlist;
|
|
|
|
artist_ops = ops;
|
|
|
|
db_for_each(dbe, next, artist_db_get()) {
|
|
playlist = __artist_pl_alloc(ARTIST(dbe));
|
|
ARTIST(dbe)->ar_playlist = playlist;
|
|
|
|
idle_schedule(IDLE_SYNC, __artist_pl_add, playlist);
|
|
}
|
|
|
|
idle_schedule(IDLE_SYNC, __artist_pl_load, NULL);
|
|
}
|
|
|
|
void pl_artist_deinit()
|
|
{
|
|
struct db_entry *dbe, *next;
|
|
struct playlist *playlist;
|
|
|
|
db_for_each(dbe, next, artist_db_get()) {
|
|
playlist = ARTIST(dbe)->ar_playlist;
|
|
ARTIST(dbe)->ar_playlist = NULL;
|
|
|
|
__artist_pl_free(playlist);
|
|
}
|
|
}
|
|
|
|
void pl_artist_new_track(struct track *track)
|
|
{
|
|
struct artist *artist = track->tr_album->al_artist;
|
|
struct playlist *playlist = (struct playlist *)artist->ar_playlist;
|
|
|
|
if (!playlist) {
|
|
playlist = __artist_pl_alloc(artist);
|
|
artist->ar_playlist = playlist;
|
|
}
|
|
|
|
playlist_generic_add_track(playlist, track);
|
|
}
|
|
|
|
void pl_artist_delete_track(struct track *track)
|
|
{
|
|
struct artist *artist = track->tr_album->al_artist;
|
|
struct playlist *playlist = (struct playlist *)artist->ar_playlist;
|
|
|
|
if (playlist)
|
|
playlist_generic_remove_track(playlist, track);
|
|
}
|