// Copyright (c) 2012 Bryan Schumaker. #include #include #include #include #include #include #include #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 files; }; static void setup_scan_data(struct ScanData *scan, list &files) { list::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::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 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); }