ocarina/libsaria/library/update.cpp

128 lines
2.8 KiB
C++

// Copyright (c) 2012 Bryan Schumaker.
#include <library.h>
#include <notify.h>
#include <track.h>
#include <print.h>
#include <deck.h>
#include <idle.h>
#include <fs.h>
#include "library.h"
static unsigned int MAX_SCAN = 20;
static void validate_path(void *d)
{
struct libsaria::library::Path *path;
libsaria::Track *track;
unsigned int i = 0;
path = (struct libsaria::library::Path *)d;
while (i < path->tracks.size()) {
track = path->tracks[i];
if (!libsaria::exists(track->filepath)) {
println("Reaping: " + track->filepath);
lib_playlist.remove_track(track);
path->tracks.erase(path->tracks.begin() + i);
} else
i++;
}
libsaria::notify(PATH_UPDATED, path);
save_path(path);
}
struct ScanData {
struct libsaria::library::Path *path;
list<string> files;
};
static void setup_scan_data(struct ScanData *scan, list<string> &files)
{
list<string>::iterator it;
if (files.size() <= MAX_SCAN)
it = files.end();
else {
it = files.begin();
for (unsigned int i = 0; i < MAX_SCAN; i++)
it++;
}
scan->files.splice(scan->files.begin(), files, files.begin(), it);
}
static bool find_file(libsaria::library::Path *path, string &file)
{
for (unsigned int i = 0; i < path->tracks.size(); i++) {
if (path->tracks[i]->filepath == file)
return true;
}
return false;
}
static void scan_path(void *data)
{
struct ScanData *scan = (struct ScanData *)data;
list<string>::iterator it;
libsaria::library::Path *path = scan->path;
libsaria::Track *track;
for (it = scan->files.begin(); it != scan->files.end(); it++) {
/*
* TODO: What I really should do for this check is build up
* a path component tree right before scanning, and then walk
* the tree to check if the path exists. It'll be much faster
* than having to walk the same list over and over...
*/
if (find_file(path, *it))
continue;
try {
track = new libsaria::Track(*it, path);
path->tracks.push_back(track);
lib_playlist.push_back(track);
} catch (string message) {
println(message);
}
}
libsaria::notify(PATH_UPDATED, path);
delete scan;
}
static void update_path(void *d)
{
struct libsaria::library::Path *path;
list<string> file_list;
unsigned int i;
struct ScanData *data;
path = (struct libsaria::library::Path *)d;
libsaria::list_dir(path->path, file_list);
println("Found: %d files to scan", file_list.size());
i = 0;
while (file_list.size() > 0) {
data = new ScanData;
data->path = path;
setup_scan_data(data, file_list);
libsaria::idle::schedule(scan_path, data);
if ((i++ % 50) == 0)
save_path(path);
}
save_path(path);
}
void do_update_path(struct libsaria::library::Path *path)
{
println("Updating path: " + path->path);
if (!libsaria::exists(path->path)) {
libsaria::library::delete_path(path);
return;
}
libsaria::idle::schedule(validate_path, path);
libsaria::idle::schedule(update_path, path);
}