2014-09-13 10:38:54 -04:00
|
|
|
/**
|
2013-10-27 17:25:26 -04:00
|
|
|
* Copyright 2013 (c) Anna Schumaker.
|
|
|
|
*/
|
2014-06-05 10:19:22 -04:00
|
|
|
#include <core/idle.h>
|
|
|
|
#include <core/library.h>
|
2014-12-02 08:24:36 -05:00
|
|
|
#include <core/print.h>
|
2013-10-27 17:25:26 -04:00
|
|
|
|
|
|
|
#include <glib.h>
|
|
|
|
|
2013-11-10 17:37:35 -05:00
|
|
|
|
2014-05-24 12:47:33 -04:00
|
|
|
class LibraryQueue : public Queue {
|
|
|
|
private:
|
2015-09-10 08:00:42 -04:00
|
|
|
file f;
|
2014-05-24 12:47:33 -04:00
|
|
|
|
|
|
|
public:
|
|
|
|
|
2015-09-10 10:33:24 -04:00
|
|
|
LibraryQueue() : Queue(Q_ENABLED | Q_REPEAT)
|
2014-05-24 12:47:33 -04:00
|
|
|
{
|
2015-09-10 10:33:24 -04:00
|
|
|
file_init(&f, "library.q", 0);
|
2014-05-24 12:47:33 -04:00
|
|
|
Queue :: sort(SORT_ARTIST, true);
|
|
|
|
Queue :: sort(SORT_YEAR, false);
|
|
|
|
Queue :: sort(SORT_TRACK, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
void save()
|
|
|
|
{
|
|
|
|
std::vector<struct sort_info>::iterator it;
|
|
|
|
|
2015-09-10 09:46:33 -04:00
|
|
|
file_open(&f, OPEN_WRITE);
|
2015-10-08 09:41:51 -04:00
|
|
|
file_writef(&f, "%u %u", _flags, _sort_order.size());
|
2014-05-24 12:47:33 -04:00
|
|
|
for (it = _sort_order.begin(); it != _sort_order.end(); it++)
|
2015-10-08 09:41:51 -04:00
|
|
|
file_writef(&f, " %u %d", it->field, it->ascending);
|
|
|
|
file_writef(&f, "\n");
|
2015-09-10 09:12:48 -04:00
|
|
|
file_close(&f);
|
2014-05-24 12:47:33 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void load()
|
|
|
|
{
|
|
|
|
unsigned int field;
|
2015-10-08 11:16:38 -04:00
|
|
|
int ascending;
|
2014-05-24 12:47:33 -04:00
|
|
|
unsigned int n;
|
|
|
|
|
2015-09-10 09:46:33 -04:00
|
|
|
if (!file_open(&f, OPEN_READ))
|
2014-05-24 12:47:33 -04:00
|
|
|
return;
|
|
|
|
|
2015-10-08 11:16:38 -04:00
|
|
|
file_readf(&f, "%u %u", &_flags, &n);
|
2014-05-24 12:47:33 -04:00
|
|
|
for (unsigned int i = 0; i < n; i++) {
|
2015-10-08 11:16:38 -04:00
|
|
|
file_readf(&f, "%u %d", &field, &ascending);
|
2014-05-24 12:47:33 -04:00
|
|
|
Queue :: sort((sort_t)field, (i == 0) ? true : false);
|
|
|
|
if (ascending == false)
|
|
|
|
Queue :: sort((sort_t)field, false);
|
|
|
|
}
|
2015-09-10 09:12:48 -04:00
|
|
|
file_close(&f);
|
2014-05-24 12:47:33 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void set_flag(queue_flags f) { Queue :: set_flag(f); save(); }
|
|
|
|
void unset_flag(queue_flags f) { Queue :: unset_flag(f); save(); }
|
|
|
|
|
|
|
|
void sort(sort_t field, bool ascending)
|
|
|
|
{
|
|
|
|
Queue :: sort(field, ascending);
|
|
|
|
save();
|
|
|
|
};
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
static LibraryQueue library_q;
|
|
|
|
|
2014-01-01 13:34:25 -05:00
|
|
|
struct scan_info {
|
2015-10-23 10:21:12 -04:00
|
|
|
struct library *library;
|
2014-01-01 13:34:25 -05:00
|
|
|
std :: string path;
|
|
|
|
};
|
2013-11-10 16:09:31 -05:00
|
|
|
|
2014-05-24 12:47:33 -04:00
|
|
|
static void scan_path(struct scan_info &);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Scanning functions are here
|
|
|
|
*/
|
2015-10-23 10:21:12 -04:00
|
|
|
static void tag_track(struct library *library, const std::string &filepath)
|
2014-12-02 08:24:36 -05:00
|
|
|
{
|
2015-10-31 10:53:40 -04:00
|
|
|
struct track *track = track_add(library, filepath);
|
2014-12-02 08:24:36 -05:00
|
|
|
if (track)
|
|
|
|
library_q.add(track);
|
|
|
|
}
|
2013-11-10 16:09:31 -05:00
|
|
|
|
2015-10-23 10:21:12 -04:00
|
|
|
static void process_path(struct library *library, const std :: string &dir,
|
2013-11-10 16:09:31 -05:00
|
|
|
const std :: string &name)
|
|
|
|
{
|
2014-05-24 12:47:33 -04:00
|
|
|
struct scan_info scan = {
|
|
|
|
.library = library,
|
|
|
|
.path = dir + "/" + name,
|
|
|
|
};
|
|
|
|
|
|
|
|
if (g_file_test(scan.path.c_str(), G_FILE_TEST_IS_DIR) == true)
|
|
|
|
idle :: schedule (scan_path, scan);
|
2014-12-02 08:24:36 -05:00
|
|
|
else
|
|
|
|
tag_track(library, scan.path);
|
2013-11-10 17:37:35 -05:00
|
|
|
}
|
|
|
|
|
2014-05-24 12:47:33 -04:00
|
|
|
static void scan_path(struct scan_info &scan)
|
2013-11-10 16:09:31 -05:00
|
|
|
{
|
|
|
|
GDir *dir;
|
|
|
|
const char *name;
|
|
|
|
|
2014-01-01 13:34:25 -05:00
|
|
|
dir = g_dir_open(scan.path.c_str(), 0, NULL);
|
2013-11-10 16:09:31 -05:00
|
|
|
if (dir == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
name = g_dir_read_name(dir);
|
|
|
|
while (name != NULL) {
|
2014-03-29 11:44:39 -04:00
|
|
|
process_path(scan.library, scan.path, name);
|
2013-11-10 16:09:31 -05:00
|
|
|
name = g_dir_read_name(dir);
|
|
|
|
}
|
2014-01-15 20:40:24 -05:00
|
|
|
|
2015-09-28 15:39:26 -04:00
|
|
|
track_db_commit();
|
2013-11-10 16:09:31 -05:00
|
|
|
}
|
|
|
|
|
2015-10-23 10:21:12 -04:00
|
|
|
static void validate_library(struct library *&library)
|
2013-12-22 15:38:27 -05:00
|
|
|
{
|
2015-10-25 05:06:23 -04:00
|
|
|
struct track *track, *next;
|
2013-12-22 15:38:27 -05:00
|
|
|
|
2015-10-25 05:06:23 -04:00
|
|
|
db_for_each(track, next, track_db_get()) {
|
2015-10-27 17:25:18 -04:00
|
|
|
if (track->tr_library != library)
|
2013-12-22 15:38:27 -05:00
|
|
|
continue;
|
|
|
|
|
2015-10-29 02:43:39 -04:00
|
|
|
if (g_file_test(track_path(track).c_str(), G_FILE_TEST_EXISTS) == false) {
|
2014-05-24 12:47:33 -04:00
|
|
|
library_q.del(track);
|
2015-10-25 04:41:03 -04:00
|
|
|
track_remove(track);
|
2013-12-22 15:38:27 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-10 16:09:31 -05:00
|
|
|
|
|
|
|
|
2013-10-27 17:25:26 -04:00
|
|
|
/*
|
2014-05-24 12:47:33 -04:00
|
|
|
* External API begins here
|
2013-10-27 17:25:26 -04:00
|
|
|
*/
|
|
|
|
|
2015-10-23 10:21:12 -04:00
|
|
|
void collection :: init()
|
2013-11-03 16:03:01 -05:00
|
|
|
{
|
2015-10-25 05:06:23 -04:00
|
|
|
struct track *track, *next;
|
2014-05-24 12:47:33 -04:00
|
|
|
|
|
|
|
library_q.load();
|
2014-02-01 17:29:31 -05:00
|
|
|
|
2015-10-25 05:06:23 -04:00
|
|
|
db_for_each(track, next, track_db_get()) {
|
2015-10-27 17:25:18 -04:00
|
|
|
if (track->tr_library->li_enabled)
|
2014-12-02 08:16:22 -05:00
|
|
|
library_q.add(track);
|
2014-01-25 13:19:40 -05:00
|
|
|
}
|
2013-11-03 16:03:01 -05:00
|
|
|
}
|
|
|
|
|
2015-10-23 10:21:12 -04:00
|
|
|
struct library *collection :: add(const std::string &dir)
|
2013-10-27 17:25:26 -04:00
|
|
|
{
|
2015-10-23 10:21:12 -04:00
|
|
|
struct library *library = NULL;
|
2013-10-27 17:25:26 -04:00
|
|
|
|
2014-05-24 12:47:33 -04:00
|
|
|
if (g_file_test(dir.c_str(), G_FILE_TEST_IS_DIR) == false)
|
|
|
|
return library;
|
2014-01-15 20:40:24 -05:00
|
|
|
|
2015-09-28 10:00:06 -04:00
|
|
|
library = library_find(dir);
|
2014-05-24 12:47:33 -04:00
|
|
|
if (library)
|
|
|
|
update(library);
|
|
|
|
return library;
|
2013-10-27 17:25:26 -04:00
|
|
|
}
|
|
|
|
|
2015-10-23 10:21:12 -04:00
|
|
|
void collection :: remove(struct library *library)
|
2013-10-27 17:25:26 -04:00
|
|
|
{
|
2014-05-24 12:47:33 -04:00
|
|
|
if (library) {
|
|
|
|
set_enabled(library, false);
|
2015-10-25 04:43:39 -04:00
|
|
|
track_remove_all(library);
|
2015-09-28 09:55:29 -04:00
|
|
|
library_remove(library);
|
2014-01-16 22:23:36 -05:00
|
|
|
}
|
2013-10-27 17:25:26 -04:00
|
|
|
}
|
|
|
|
|
2015-10-23 10:21:12 -04:00
|
|
|
void collection :: update(struct library *library)
|
2013-11-10 16:09:31 -05:00
|
|
|
{
|
2014-05-24 12:47:33 -04:00
|
|
|
struct scan_info scan = {
|
|
|
|
.library = library,
|
|
|
|
};
|
|
|
|
|
|
|
|
if (library) {
|
2014-11-12 08:31:09 -05:00
|
|
|
scan.path = library->primary_key();
|
2014-05-24 12:47:33 -04:00
|
|
|
idle :: schedule(validate_library, library);
|
|
|
|
idle :: schedule(scan_path, scan);
|
|
|
|
}
|
2013-11-10 16:09:31 -05:00
|
|
|
}
|
|
|
|
|
2015-10-23 10:21:12 -04:00
|
|
|
void collection :: update_all()
|
2014-01-12 13:04:16 -05:00
|
|
|
{
|
2015-10-23 13:32:20 -04:00
|
|
|
struct library *library, *next;
|
2014-03-09 14:58:06 -04:00
|
|
|
|
2015-10-23 13:32:20 -04:00
|
|
|
db_for_each(library, next, library_db_get())
|
|
|
|
update(library);
|
2014-01-12 13:04:16 -05:00
|
|
|
}
|
|
|
|
|
2015-10-23 10:21:12 -04:00
|
|
|
void collection :: set_enabled(struct library *library, bool enabled)
|
2014-01-18 12:32:41 -05:00
|
|
|
{
|
2015-10-25 05:06:23 -04:00
|
|
|
struct track *track, *next;
|
2014-05-24 12:47:33 -04:00
|
|
|
|
2015-10-23 14:10:59 -04:00
|
|
|
if (!library || (library->li_enabled == enabled))
|
2014-05-24 12:47:33 -04:00
|
|
|
return;
|
2014-01-18 12:32:41 -05:00
|
|
|
|
2015-10-23 14:19:42 -04:00
|
|
|
library_set_enabled(library, enabled);
|
2014-03-29 11:44:39 -04:00
|
|
|
|
2015-10-25 05:06:23 -04:00
|
|
|
db_for_each(track, next, track_db_get()) {
|
2015-10-27 17:25:18 -04:00
|
|
|
if (track->tr_library == library) {
|
2014-01-18 12:32:41 -05:00
|
|
|
if (enabled)
|
2014-12-02 08:16:22 -05:00
|
|
|
library_q.add(track);
|
2014-01-18 12:32:41 -05:00
|
|
|
else
|
2014-12-02 08:16:22 -05:00
|
|
|
library_q.del(track);
|
2014-01-18 12:32:41 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-23 10:21:12 -04:00
|
|
|
Queue *collection :: get_queue()
|
2013-10-27 17:25:26 -04:00
|
|
|
{
|
2014-05-24 12:47:33 -04:00
|
|
|
return &library_q;
|
2013-10-27 17:25:26 -04:00
|
|
|
}
|