From d0ac939c4948e3276e48954cafb0d73c74400618 Mon Sep 17 00:00:00 2001 From: Ulf Lilleengen Date: Sat, 9 Aug 2008 17:19:03 +0200 Subject: - Add lookup for album directory. --- include/mp3fs.h | 1 + src/mp3_subr.c | 40 +++++++++++++++++----- src/mp3_vnops.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 120 insertions(+), 22 deletions(-) diff --git a/include/mp3fs.h b/include/mp3fs.h index 847f047..9436966 100644 --- a/include/mp3fs.h +++ b/include/mp3fs.h @@ -52,6 +52,7 @@ void mp3_lookup_finish(struct lookuphandle *); void mp3_lookup_artist(const char *, struct filler_data *); void mp3_lookup_genre(const char *, struct filler_data *); +void mp3_lookup_album(const char *, struct filler_data *); char *mp3_gettoken(const char *, int); int mp3_numtoken(const char *); diff --git a/src/mp3_subr.c b/src/mp3_subr.c index 72f2994..a56e696 100644 --- a/src/mp3_subr.c +++ b/src/mp3_subr.c @@ -404,6 +404,33 @@ mp3_gettoken(const char *str, int toknum) return (ret); } +/* + * List album given a path. + */ +void +mp3_lookup_album(const char *path, struct filler_data *fd) +{ + struct lookuphandle *lh; + char *album; + + switch (mp3_numtoken(path)) { + case 1: + lh = mp3_lookup_start(0, fd, mp3_lookup_list, + "SELECT DISTINCT album FROM song"); + break; + case 2: + /* So, now we got to find out the artist and list its albums. */ + album = mp3_gettoken(path, 2); + if (album == NULL) + break; + lh = mp3_lookup_start(0, fd, mp3_lookup_list, + "SELECT DISTINCT title FROM song WHERE album LIKE ?"); + mp3_lookup_insert(lh, album, LIST_DATATYPE_STRING); + break; + } + mp3_lookup_finish(lh); +} + /* * List artist given a path. */ @@ -500,7 +527,7 @@ mp3_lookup_list(void *data, const char *str) fd = (struct filler_data *)data; fd->filler(fd->buf, str, NULL, 0); - return (1); + return (0); } /* @@ -512,11 +539,8 @@ mp3_lookup_open(void *data, const char *str) struct file_data *fd; fd = (struct file_data *)data; - if (!fd->found) { - fd->fd = open(str, O_RDONLY); - fd->found = 1; - return (0); - } + fd->fd = open(str, O_RDONLY); + fd->found = 1; return (1); } @@ -531,6 +555,6 @@ mp3_lookup_stat(void *data, const char *str) st = (struct stat *)data; if (stat(str, st) < 0) - return (-1); - return (0); + return (0); + return (1); } diff --git a/src/mp3_vnops.c b/src/mp3_vnops.c index b532556..8186c89 100755 --- a/src/mp3_vnops.c +++ b/src/mp3_vnops.c @@ -23,7 +23,7 @@ char *logpath = "/home/lulf/dev/mp3fs/mp3fs.log"; static int mp3_getattr (const char *path, struct stat *stbuf) { struct lookuphandle *lh; - char *title; + char *title, *album; int tokens; memset (stbuf, 0, sizeof (struct stat)); @@ -32,9 +32,8 @@ static int mp3_getattr (const char *path, struct stat *stbuf) stbuf->st_nlink = 2; return 0; } - if (strncmp(path, "/Artists", 8) == 0 || - strncmp(path, "/Genres", 7) == 0 || - strncmp(path, "/Albums", 7) == 0) { + if (strncmp(path, "/Genres", 7) == 0 || + strncmp(path, "/Artists", 8) == 0) { tokens = mp3_numtoken(path); switch (tokens) { case 1: @@ -50,6 +49,30 @@ static int mp3_getattr (const char *path, struct stat *stbuf) stbuf->st_size = 512; return 0; } + } else if (strncmp(path, "/Albums", 7) == 0) { + tokens = mp3_numtoken(path); + switch (tokens) { + case 1: + case 2: + stbuf->st_mode = S_IFDIR | 0444; + stbuf->st_nlink = 1; + stbuf->st_size = 12; + return (0); + case 3: + album = mp3_gettoken(path, 2); + if (album == NULL) + break; + title = mp3_gettoken(path, 3); + if (title == NULL) + break; + lh = mp3_lookup_start(0, stbuf, mp3_lookup_stat, + "SELECT filepath FROM song WHERE title LIKE ? AND " + "album LIKE ?"); + mp3_lookup_insert(lh, title, LIST_DATATYPE_STRING); + mp3_lookup_insert(lh, album, LIST_DATATYPE_STRING); + mp3_lookup_finish(lh); + return 0; + } } else if (strncmp(path, "/Tracks", 7) == 0) { tokens = mp3_numtoken(path); switch (tokens) { @@ -109,10 +132,8 @@ static int mp3_readdir (const char *path, void *buf, fuse_fill_dir_t filler, "SELECT DISTINCT title FROM song"); mp3_lookup_finish(lh); return (0); - } else if (strcmp(path, "/Albums") == 0) { - lh = mp3_lookup_start(0, &fd, mp3_lookup_list, - "SELECT DISTINCT album FROM song"); - mp3_lookup_finish(lh); + } else if (strncmp(path, "/Albums", 7) == 0) { + mp3_lookup_album(path, &fd); return (0); } @@ -123,7 +144,7 @@ static int mp3_open (const char *path, struct fuse_file_info *fi) { struct file_data fd; struct lookuphandle *lh; - char *title; + char *title, *album; lh = NULL; fd.fd = -1; @@ -151,6 +172,33 @@ static int mp3_open (const char *path, struct fuse_file_info *fi) return (-EIO); close(fd.fd); return (0); + } else if (strncmp(path, "/Albums", 7) == 0) { + switch (mp3_numtoken(path)) { + case 3: + album = mp3_gettoken(path, 2); + if (album == NULL) + break; + title = mp3_gettoken(path, 3); + if (title == NULL) + break; + lh = mp3_lookup_start(0, &fd, mp3_lookup_open, + "SELECT filepath FROM song WHERE title LIKE ? AND " + "album LIKE ?"); + if (lh == NULL) + return (-EIO); + mp3_lookup_insert(lh, title, LIST_DATATYPE_STRING); + mp3_lookup_insert(lh, album, LIST_DATATYPE_STRING); + break; + default: + return (-ENOENT); + } + mp3_lookup_finish(lh); + if (!fd.found) + return (-ENOENT); + if (fd.fd < 0) + return (-EIO); + close(fd.fd); + return (0); } /* * 1. Have a lookup cache for names?. @@ -168,16 +216,12 @@ static int mp3_read (const char *path, char *buf, size_t size, off_t offset, { struct file_data fd; struct lookuphandle *lh; - char *title; + char *title, *album; size_t bytes; lh = NULL; fd.fd = -1; fd.found = 0; - if (strcmp (path, "/Artists") == 0) { - memcpy (buf, "Oh you wish\n", 12); - return 12; - } /* Open a specific track. */ if (strncmp(path, "/Tracks", 7) == 0) { switch (mp3_numtoken(path)) { @@ -203,6 +247,35 @@ static int mp3_read (const char *path, char *buf, size_t size, off_t offset, bytes = read(fd.fd, buf, size); close(fd.fd); return (bytes); + } else if (strncmp(path, "/Albums", 7) == 0) { + switch (mp3_numtoken(path)) { + case 3: + album = mp3_gettoken(path, 2); + if (album == NULL) + break; + title = mp3_gettoken(path, 3); + if (title == NULL) + break; + lh = mp3_lookup_start(0, &fd, mp3_lookup_open, + "SELECT filepath FROM song WHERE title LIKE ? AND " + "album LIKE ?"); + if (lh == NULL) + return (-EIO); + mp3_lookup_insert(lh, title, LIST_DATATYPE_STRING); + mp3_lookup_insert(lh, album, LIST_DATATYPE_STRING); + break; + default: + return (-ENOENT); + } + mp3_lookup_finish(lh); + if (!fd.found) + return (-ENOENT); + if (fd.fd < 0) + return (-EIO); + lseek(fd.fd, offset, SEEK_CUR); + bytes = read(fd.fd, buf, size); + close(fd.fd); + return (bytes); } /* * 1. Find the mnode given the path. If not in cache, read through mp3 -- cgit v1.2.3