summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlulf@nobby.studby.ntnu.no <lulf@nobby.studby.ntnu.no>2008-04-30 03:16:47 +0200
committerlulf@nobby.studby.ntnu.no <lulf@nobby.studby.ntnu.no>2008-04-30 03:16:47 +0200
commitc881ab427c8de1bf906797b64434263ddd4653c4 (patch)
tree09085c740d214c5b6f9d0d3ee974e84af38d2bad
parent6432307b18665e8d562ba50884019eb5d199d8db (diff)
- Fix issues with getting filler to work.
- Fix problems with query matching by adding a flag saying what parameters we want. Could perhaps do this better though.
-rw-r--r--include/mp3fs.h18
-rw-r--r--src/mp3_subr.c46
-rwxr-xr-xsrc/mp3_vnops.c16
3 files changed, 54 insertions, 26 deletions
diff --git a/include/mp3fs.h b/include/mp3fs.h
index a8593e2..05e84e7 100644
--- a/include/mp3fs.h
+++ b/include/mp3fs.h
@@ -24,8 +24,24 @@ traverse_fn_t mp3_scan;
/*
* Functions performing queries on the collection.
+ * Usage:
+ * To list all artists:
+ mp3_select(SELECT_ARTIST, NULL, NULL, NULL);
+ * To list one artist "Haddaway":
+ mp3_select(SELECT_ARTIST, "Haddaway", NULL, NULL);
+ * To list unique artists in genre "Rock"
+ mp3_select(SELECT_ARTIST | SELECT_GENRE, NULL, NULL, "Rock");
+
+ * So, one can say that the first parameter specifies which fields should be
+ * taken into account when comparing for duplicates, and the field parameters
+ * determines if * there are some fields of that paramters which it must match.
+
+ * I hope to improve this soon.
*/
-struct collection *mp3_select(char *, char *, char *);
+#define SELECT_ARTIST 0x1
+#define SELECT_TITLE 0x2
+#define SELECT_GENRE 0x4
+struct collection *mp3_select(int, char *, char *, char *);
/*
* Use a selection to input a certain tag field into a filler.
diff --git a/src/mp3_subr.c b/src/mp3_subr.c
index 925c95e..3c5798c 100644
--- a/src/mp3_subr.c
+++ b/src/mp3_subr.c
@@ -16,6 +16,7 @@
#include <mnode.h>
#include <queue.h>
#include <debug.h>
+#include <log.h>
struct queryvector {
@@ -25,10 +26,10 @@ struct queryvector {
};
/* Local prototypes. */
-static int isduplicate(struct collection *, struct queryvector *);
+static int isduplicate(struct collection *, struct queryvector *, int);
static void free_query_vector(struct queryvector *);
static void fill_query_vector(struct queryvector *, struct mnode *);
-static int query_matches(struct queryvector *, struct queryvector *);
+static int query_matches(struct queryvector *, struct queryvector *, int);
/* Simple list containing our nodes. */
struct collection allmusic;
@@ -113,10 +114,10 @@ mp3_filter(struct collection *selection, int filter, struct filler_data *fd)
{
TagLib_Tag *tag;
struct mnode *mp;
- char *field, *tmp;
+ char *field, name[MAXPATHLEN];
- fd->filler(fd->buf, "LOL", NULL, 0);
LIST_FOREACH(mp, &selection->head, sel_next) {
+
tag = taglib_file_tag(mp->tag);
switch (filter) {
case FILTER_ARTIST:
@@ -132,14 +133,11 @@ mp3_filter(struct collection *selection, int filter, struct filler_data *fd)
err(1, "invalid filter given");
break;
}
- if (field == NULL)
+ if (field == NULL || !strcmp(field, ""))
continue;
/* XXX: check if we need to free this or not. */
- tmp = strdup(field);
- if (tmp == NULL)
- err(1, "not enough memory in filter");
- fd->filler(fd->buf, tmp, NULL, 0);
- taglib_tag_free_strings();
+ strlcpy(name, field, sizeof(name));
+ fd->filler(fd->buf, name, NULL, 0);
}
}
@@ -147,15 +145,18 @@ mp3_filter(struct collection *selection, int filter, struct filler_data *fd)
* Perform a query selecting artists given a filter.
*/
struct collection *
-mp3_select(char *artist, char *title, char *genre)
+mp3_select(int flags, char *artist, char *title, char *genre)
{
struct mnode *mp;
struct collection *selection;
struct queryvector qv, qv2;
- qv.artist = artist;
- qv.title = title;
- qv.genre = genre;
+ if (flags & SELECT_ARTIST)
+ qv.artist = artist;
+ if (flags & SELECT_TITLE)
+ qv.title = title;
+ if (flags & SELECT_GENRE)
+ qv.genre = genre;
/* Initialize selection structure. */
selection = malloc(sizeof(struct collection));
@@ -164,13 +165,16 @@ mp3_select(char *artist, char *title, char *genre)
LIST_INIT(&selection->head);
/* Filter our collection. */
+
LIST_FOREACH(mp, &allmusic.head, coll_next) {
/* First make sure it matches our criteria. */
fill_query_vector(&qv2, mp);
- if (query_matches(&qv2, &qv) && !isduplicate(selection, &qv2))
+ if (query_matches(&qv2, &qv, flags) && !isduplicate(selection,
+ &qv2, flags))
LIST_INSERT_HEAD(&selection->head, mp, sel_next);
free_query_vector(&qv2);
}
+
return (selection);
}
@@ -178,7 +182,7 @@ mp3_select(char *artist, char *title, char *genre)
* Filter out unique fields.
*/
static int
-isduplicate(struct collection *selection, struct queryvector *qv)
+isduplicate(struct collection *selection, struct queryvector *qv, int flags)
{
struct mnode *mp2;
struct queryvector qv_entry;
@@ -186,7 +190,7 @@ isduplicate(struct collection *selection, struct queryvector *qv)
LIST_FOREACH(mp2, &selection->head, sel_next) {
/* Compare to determine if it's a duplicate. */
fill_query_vector(&qv_entry, mp2);
- if (query_matches(&qv_entry, qv)) {
+ if (query_matches(&qv_entry, qv, flags)) {
free_query_vector(&qv_entry);
return (1);
}
@@ -223,19 +227,19 @@ free_query_vector(struct queryvector *qv)
/* Determine if two query vectors matches. */
static int
-query_matches(struct queryvector *qv1, struct queryvector *qv2)
+query_matches(struct queryvector *qv1, struct queryvector *qv2, int flags)
{
/* Check if it matches the different fields. */
- if (qv1->artist != NULL && qv2->artist != NULL) {
+ if ((flags & SELECT_ARTIST) && qv1->artist != NULL && qv2->artist != NULL) {
if (strcmp(qv1->artist, qv2->artist))
return (0);
}
- if (qv1->title != NULL && qv2->title != NULL) {
+ if ((flags & SELECT_TITLE) && qv1->title != NULL && qv2->title != NULL) {
if (strcmp(qv1->title, qv2->title))
return (0);
}
- if (qv1->genre != NULL && qv2->genre != NULL) {
+ if ((flags & SELECT_GENRE) && qv1->genre != NULL && qv2->genre != NULL) {
if (strcmp(qv1->genre, qv2->genre))
return (0);
}
diff --git a/src/mp3_vnops.c b/src/mp3_vnops.c
index e8e3da4..39ad651 100755
--- a/src/mp3_vnops.c
+++ b/src/mp3_vnops.c
@@ -13,10 +13,11 @@
#include <tag_c.h>
#include <mp3fs.h>
-
#include <debug.h>
+#include <log.h>
char musicpath[MAXPATHLEN]; // = "/home/lulf/dev/mp3fs/music";
+char *logpath = "/home/lulf/dev/mp3fs/mp3fs.log";
static int mp3_getattr (const char *path, struct stat *stbuf)
{
@@ -59,11 +60,14 @@ static int mp3_readdir (const char *path, void *buf, fuse_fill_dir_t filler,
* 2. Find the mp3s that matches the tags given from the path.
* 3. Return the list of those mp3s.
*/
- filler(buf, "LOllll", NULL, 0);
if (!strcmp(path, "/Artists")) {
/* List artists. */
+
/* XXX: need to free selection structure!. */
- selection = mp3_select(NULL, NULL, NULL);
+ selection = mp3_select(SELECT_ARTIST, NULL, NULL, NULL);
+ /* Could we save a loop iteration here? Doesn' really matter
+ * since it has much lower complexity than mp3_select.
+ */
mp3_filter(selection, FILTER_ARTIST, &fd);
free(selection);
return (0);
@@ -133,6 +137,7 @@ static int mp3fs_opt_proc (void *data, const char *arg, int key,
int
mp3_run(int argc, char **argv)
{
+ int ret;
/*
* XXX: Build index of mp3's.
*/
@@ -149,7 +154,10 @@ mp3_run(int argc, char **argv)
exit (1);
DEBUG("musicpath: %s\n", musicpath);
+ log_open(logpath);
mp3_initscan(musicpath);
- return (fuse_main(args.argc, args.argv, &mp3_ops, NULL));
+ ret = fuse_main(args.argc, args.argv, &mp3_ops, NULL);
+ log_close();
+ return (ret);
}