#include "music.h" #include "conf.h" #include #include struct directory *music_root = NULL; gboolean music_init() { gchar *path = conf_get_string("audist", "music_root"); if(path == NULL) { g_error("no music_root is set!"); } music_root = g_new0(struct directory, 1); music_root->path = path; g_debug("added music root %s", path); return 1; } gboolean music_scan(struct directory *directory) { GError *error = NULL; GDir *dir = g_dir_open(directory->path, 0, &error); if(dir == NULL) { g_error("%s", error->message); g_error_free(error); return 0; } const gchar *entry; while((entry = g_dir_read_name(dir)) != NULL) { struct stat st; gchar *fullpath = g_build_filename(directory->path, entry, NULL); if(fullpath == NULL) { g_error("g_build_filename returned NULL"); } if(g_stat(fullpath, &st) < 0) { g_warning("g_stat failed on %s", fullpath); } if(S_ISREG(st.st_mode)) { struct file *f = g_new0(struct file, 1); f->name = g_strdup(entry); directory->files = g_slist_prepend(directory->files, f); g_debug("added file %s to %s", entry, directory->path); struct tag *tag = tag_read(fullpath); if(tag) { f->tag = tag; } } else if(S_ISDIR(st.st_mode)) { struct directory *d = g_new0(struct directory, 1); d->path = g_build_filename(directory->path, entry, NULL); directory->sub = g_slist_prepend(directory->sub, d); g_debug("added subdir %s to %s", entry, directory->path); g_debug("recursing into %s", entry); music_scan(d); } g_free(fullpath); } g_dir_close(dir); return 1; } gboolean music_scan_root() { g_assert(music_root != NULL); return music_scan(music_root); } static struct directory *music_find_dir_rec(struct directory *root, const gchar *path) { if(g_strcmp0(root->path, path) == 0) return root; for(GSList *node = root->sub; node; node = g_slist_next(node)) { struct directory *d = node->data; g_debug(d->path); if(g_strcmp0(d->path, path) == 0) { return d; } struct directory *temp = music_find_dir_rec(d, path); if(temp) { return temp; } } return NULL; } struct directory *music_find_dir(const gchar *path) { gchar *real_path = g_build_filename(music_root->path, path, NULL); int len = strlen(real_path); if(real_path[len - 1] == '/') real_path[len - 1] = '\0'; struct directory *dir = music_find_dir_rec(music_root, real_path); g_free(real_path); return dir; } struct file *music_find_file(const gchar *path) { gchar *dirname = g_path_get_dirname(path); gchar *filename = g_path_get_basename(path); struct directory *directory = music_find_dir(dirname); g_free(dirname); if(directory == NULL) { g_free(filename); return NULL; } for(GSList *node = directory->files; node; node = g_slist_next(node)) { struct file *f = node->data; if(g_strcmp0(filename, f->name) == 0) { g_free(filename); return f; } } g_free(filename); return NULL; } static void music_do_free(struct directory *root) { g_assert(root != NULL); for(GSList *node = root->sub; node; node = g_slist_next(node)) { struct directory *d = node->data; music_do_free(d); } g_slist_free(root->sub); for(GSList *node = root->files; node; node = g_slist_next(node)) { struct file *f = node->data; g_free(f->name); g_free(f); } g_slist_free(root->files); g_free(root->path); g_free(root); } void music_free() { g_assert(music_root != NULL); music_do_free(music_root); music_root = NULL; } gchar *music_get_full_path(const gchar *path) { return g_build_filename(music_root->path, path, NULL); }