From 0042201bb387398494e75f24f69d4039251e59c9 Mon Sep 17 00:00:00 2001 From: Miika Pekkarinen Date: Sun, 16 Jul 2006 15:04:46 +0000 Subject: Initial changelog support (only export, no import yet) and added an option to search by filename. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@10219 a1c6a512-1295-4272-9138-f99709370657 --- apps/lang/english.lang | 14 ++++++ apps/settings_menu.c | 2 + apps/tagcache.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++++- apps/tagcache.h | 8 ++-- apps/tagnavi.config | 1 + apps/tagtree.c | 16 ++++++- apps/tagtree.h | 1 + 7 files changed, 156 insertions(+), 7 deletions(-) diff --git a/apps/lang/english.lang b/apps/lang/english.lang index 95d41ba264..0bf10055e6 100644 --- a/apps/lang/english.lang +++ b/apps/lang/english.lang @@ -8557,3 +8557,17 @@ *: "Auto update" + + id: LANG_TAGCACHE_EXPORT + desc: in tag cache settings + user: + + *: "Export modifications" + + + *: "Export modifications" + + + *: "Export modifications" + + diff --git a/apps/settings_menu.c b/apps/settings_menu.c index f00612a180..c85075d0b2 100644 --- a/apps/settings_menu.c +++ b/apps/settings_menu.c @@ -50,6 +50,7 @@ #include "dir.h" #include "dircache.h" #include "tagcache.h" +#include "tagtree.h" #include "rbunicode.h" #include "splash.h" #include "yesno.h" @@ -1568,6 +1569,7 @@ static bool tagcache_settings_menu(void) { ID2P(LANG_TAGCACHE_FORCE_UPDATE), tagcache_rebuild }, { ID2P(LANG_TAGCACHE_UPDATE), tagcache_update }, { ID2P(LANG_RUNTIMEDB_ACTIVE), tagcache_runtimedb }, + { ID2P(LANG_TAGCACHE_EXPORT), tagtree_export }, }; m=menu_init( items, sizeof(items) / sizeof(*items), NULL, diff --git a/apps/tagcache.c b/apps/tagcache.c index a5675850bf..47d9c4ed80 100644 --- a/apps/tagcache.c +++ b/apps/tagcache.c @@ -478,6 +478,7 @@ static bool build_lookup_list(struct tagcache_search *tcs) { struct index_entry *idx = &hdr->indices[i]; int seek; + char buf[256]; char *str = NULL; struct tagfile_entry *entry; @@ -485,8 +486,16 @@ static bool build_lookup_list(struct tagcache_search *tcs) if (!tagcache_is_numeric_tag(tcs->clause[j]->tag)) { - entry = (struct tagfile_entry *)&hdr->tags[tcs->clause[j]->tag][seek]; - str = entry->tag_data; + if (tcs->clause[j]->tag == tag_filename) + { + tagcache_retrieve(tcs, i, buf, sizeof buf); + str = buf; + } + else + { + entry = (struct tagfile_entry *)&hdr->tags[tcs->clause[j]->tag][seek]; + str = entry->tag_data; + } } @@ -2104,6 +2113,114 @@ static int open_master_fd(struct tagcache_header *hdr) return fd; } +static bool write_tag(int fd, const char *tagstr, const char *datastr) +{ + char buf[256]; + int i; + + snprintf(buf, sizeof buf, "%s=\"", tagstr); + for (i = strlen(buf); i < (long)sizeof(buf)-2; i++) + { + if (*datastr == '\0') + break; + + if (*datastr == '"') + { + buf[i] = '\\'; + *datastr++; + continue; + } + + buf[i] = *(datastr++); + } + + strcpy(&buf[i], "\" "); + + write(fd, buf, i + 2); + + return true; +} + +bool tagcache_create_changelog(struct tagcache_search *tcs) +{ + static const char *tags_str[] = { "artist", "album", "genre", "title", + "filename", "playcount", "playtime", "lastplayed" }; + static const int tags[] = { tag_artist, tag_album, tag_genre, tag_title, + tag_filename, tag_playcount, tag_playtime, tag_lastplayed }; + struct tagcache_header myhdr; + struct index_entry idx; + char buf[256]; + char temp[32]; + int clfd; + int i, j; + + if (!tagcache_search(tcs, tag_filename)) + return false; + + /* Initialize the changelog */ + clfd = open(TAGCACHE_FILE_CHANGELOG, O_WRONLY | O_CREAT | O_TRUNC); + if (clfd < 0) + { + logf("failure to open changelog"); + return false; + } + + if (tcs->masterfd < 0) + { + if ( (tcs->masterfd = open_master_fd(&myhdr)) < 0) + return false; + } + else + { + lseek(tcs->masterfd, 0, SEEK_SET); + read(tcs->masterfd, &myhdr, sizeof(struct tagcache_header)); + } + + write(clfd, "## Changelog version 1\n", 23); + + for (i = 0; i < myhdr.entry_count; i++) + { + if (read(tcs->masterfd, &idx, sizeof(struct index_entry)) + != sizeof(struct index_entry)) + { + logf("read error"); + tagcache_search_finish(tcs); + close(clfd); + return false; + } + + /* Skip until the entry found has been modified. */ + if (! (idx.flag & FLAG_DIRTYNUM) ) + continue; + + logf("Found!"); + + /* Now retrieve all tags. */ + for (j = 0; j < (long)(sizeof(tags) / sizeof(tags[0])); j++) + { + if (tagcache_is_numeric_tag(tags[j])) + { + snprintf(temp, sizeof temp, "%d", idx.tag_seek[tags[j]]); + write_tag(clfd, tags_str[j], temp); + continue; + } + + tcs->type = tags[j]; + tagcache_retrieve(tcs, i, buf, sizeof buf); + logf("tag: %s", buf); + write_tag(clfd, tags_str[j], buf); + } + + write(clfd, "\n", 1); + } + + close(clfd); + + tagcache_search_finish(tcs); + + return true; +} + bool tagcache_modify_numeric_entry(struct tagcache_search *tcs, int tag, long data) { diff --git a/apps/tagcache.h b/apps/tagcache.h index 04f9567936..e655088cc2 100644 --- a/apps/tagcache.h +++ b/apps/tagcache.h @@ -63,9 +63,10 @@ enum tag_type { tag_artist = 0, tag_album, tag_genre, tag_title, #define TAGCACHE_MAX_CLAUSES 10 /* Tag database files. */ -#define TAGCACHE_FILE_TEMP ROCKBOX_DIR "/tagcache_tmp.tcd" -#define TAGCACHE_FILE_MASTER ROCKBOX_DIR "/tagcache_idx.tcd" -#define TAGCACHE_FILE_INDEX ROCKBOX_DIR "/tagcache_%d.tcd" +#define TAGCACHE_FILE_TEMP ROCKBOX_DIR "/tagcache_tmp.tcd" +#define TAGCACHE_FILE_MASTER ROCKBOX_DIR "/tagcache_idx.tcd" +#define TAGCACHE_FILE_INDEX ROCKBOX_DIR "/tagcache_%d.tcd" +#define TAGCACHE_FILE_CHANGELOG ROCKBOX_DIR "/tagcache_changelog.txt" /* Flags */ #define FLAG_DELETED 0x0001 /* Entry has been removed from db */ @@ -137,6 +138,7 @@ bool tagcache_retrieve(struct tagcache_search *tcs, int idxid, char *buf, long size); void tagcache_search_finish(struct tagcache_search *tcs); long tagcache_get_numeric(const struct tagcache_search *tcs, int tag); +bool tagcache_create_changelog(struct tagcache_search *tcs); bool tagcache_modify_numeric_entry(struct tagcache_search *tcs, int tag, long data); diff --git a/apps/tagnavi.config b/apps/tagnavi.config index 285f826425..0ad30538ac 100644 --- a/apps/tagnavi.config +++ b/apps/tagnavi.config @@ -6,6 +6,7 @@ "Search by artist" artist ? artist ~ "" : album : title = "%02d. %s" tracknum title "Search by album" album ? album ~ "" : title = "%02d. %s" tracknum title "Search by title" title ? title ~ "" +"Search by filename" filename ? filename ~ "" "Search by year" artist ? year = "" : album : title = "%02d. %s" tracknum title "Search by score" title = "(%3d) %s" autoscore title ? autoscore > "" "Most played tracks" title = "(%d) %s" playcount title ? playcount > "1" diff --git a/apps/tagtree.c b/apps/tagtree.c index 396248d7ce..f5c100f6ea 100644 --- a/apps/tagtree.c +++ b/apps/tagtree.c @@ -137,6 +137,7 @@ static int get_tag(int *tag) MATCH(tag, buf, "genre", tag_genre); MATCH(tag, buf, "length", tag_length); MATCH(tag, buf, "title", tag_title); + MATCH(tag, buf, "filename", tag_filename); MATCH(tag, buf, "tracknum", tag_tracknumber); MATCH(tag, buf, "year", tag_year); MATCH(tag, buf, "playcount", tag_playcount); @@ -415,6 +416,17 @@ static void tagtree_unbuffer_event(struct mp3entry *id3, bool last_track) tagcache_search_finish(&tcs); } +bool tagtree_export(void) +{ + gui_syncsplash(0, true, str(LANG_WAIT)); + if (!tagcache_create_changelog(&tcs)) + { + gui_syncsplash(HZ*2, true, str(LANG_FAILED)); + } + + return false; +} + void tagtree_init(void) { int fd; @@ -553,7 +565,7 @@ int retrieve_entries(struct tree_context *c, struct tagcache_search *tcs, current_entry_count = 0; c->dirfull = false; - if (tag != tag_title) + if (tag != tag_title && tag != tag_filename) { if (offset == 0) { @@ -576,7 +588,7 @@ int retrieve_entries(struct tree_context *c, struct tagcache_search *tcs, dptr->newtable = navibrowse; dptr->extraseek = tcs->result_seek; - if (tag == tag_title) + if (tag == tag_title || tag == tag_filename) dptr->newtable = playtrack; if (!tcs->ramsearch || fmt->valid) diff --git a/apps/tagtree.h b/apps/tagtree.h index 81d900bbb6..2129176683 100644 --- a/apps/tagtree.h +++ b/apps/tagtree.h @@ -30,6 +30,7 @@ struct tagentry { int extraseek; }; +bool tagtree_export(void); void tagtree_init(void); int tagtree_enter(struct tree_context* c); void tagtree_exit(struct tree_context* c); -- cgit v1.2.3