diff --git a/core/tags/album.c b/core/tags/album.c index 386c15c5..7d6a4265 100644 --- a/core/tags/album.c +++ b/core/tags/album.c @@ -112,7 +112,8 @@ static bool __album_run_query(struct album *album, gchar *term1, return ret; } -static bool __album_query_artist(struct album *album, struct artist *al_artist) +static bool __album_query_artist(struct album *album, struct artist *al_artist, + gchar *lower) { gchar *release, *artist, *year; bool found; @@ -120,7 +121,7 @@ static bool __album_query_artist(struct album *album, struct artist *al_artist) if (!al_artist || strncmp(al_artist->ar_lower, "various", 7) == 0) return false; - release = g_strdup_printf("release:\"%s\"~", album->al_lower); + release = g_strdup_printf("release:\"%s\"~", lower); artist = g_strdup_printf("artist:\"%s\"~", al_artist->ar_name); year = g_strdup_printf("date:%d*", album->al_year); @@ -129,9 +130,9 @@ static bool __album_query_artist(struct album *album, struct artist *al_artist) if (!found) found = __album_run_query(album, release, artist, NULL); if (!found && album->al_year > 0) - found = __album_run_query(album, album->al_lower, artist, year); + found = __album_run_query(album, lower, artist, year); if (!found) - found = __album_run_query(album, album->al_lower, artist, NULL); + found = __album_run_query(album, lower, artist, NULL); g_free(release); g_free(artist); @@ -141,13 +142,18 @@ static bool __album_query_artist(struct album *album, struct artist *al_artist) static bool __album_fetch_artwork(struct album *album) { + gchar *lower; + if (album_artwork_exists(album)) return true; if (string_length(album->al_name) == 0) return true; - if (!__album_query_artist(album, album->al_artist)) - __album_run_query(album, album->al_lower, NULL, NULL); + lower = g_strjoinv(" ", album->al_tokens); + if (!__album_query_artist(album, album->al_artist, lower)) + __album_run_query(album, lower, NULL, NULL); + + g_free(lower); return true; } @@ -163,7 +169,7 @@ static struct album *__album_alloc(gchar *name, unsigned int year) dbe_init(&album->al_dbe, album); album->al_year = year; album->al_name = name; - album->al_lower = string_lowercase(album->al_name); + album->al_tokens = g_str_tokenize_and_fold(name, NULL, &album->al_alts); album->al_artist = NULL; if (!album_artwork_exists(album)) @@ -185,7 +191,8 @@ static struct db_entry *album_alloc(const gchar *key) static void album_free(struct db_entry *dbe) { g_free(ALBUM(dbe)->al_name); - g_free(ALBUM(dbe)->al_lower); + g_strfreev(ALBUM(dbe)->al_tokens); + g_strfreev(ALBUM(dbe)->al_alts); g_free(ALBUM(dbe)); } @@ -249,7 +256,7 @@ struct album *album_get(const unsigned int index) int album_compare(struct album *lhs, struct album *rhs) { - return string_compare(lhs->al_lower, rhs->al_lower); + return string_compare_tokens(lhs->al_tokens, rhs->al_tokens); } int album_compare_year(struct album *lhs, struct album *rhs) diff --git a/core/tags/track.c b/core/tags/track.c index 00fcffba..2efc7fb1 100644 --- a/core/tags/track.c +++ b/core/tags/track.c @@ -95,6 +95,7 @@ out: static void track_free(struct db_entry *dbe) { struct track *track = TRACK(dbe); + unsigned int i; play_count -= track->tr_count; if (track->tr_count == 0) @@ -104,7 +105,11 @@ static void track_free(struct db_entry *dbe) filter_remove(track->tr_lower, track); filter_remove(track->tr_artist->ar_lower, track); - filter_remove(track->tr_album->al_lower, track); + + for (i = 0; track->tr_album->al_tokens[i]; i++) + filter_remove(track->tr_album->al_tokens[i], track); + for (i = 0; track->tr_album->al_alts[i]; i++) + filter_remove(track->tr_album->al_alts[i], track); g_free(track->tr_title); g_free(track->tr_lower); @@ -114,10 +119,16 @@ static void track_free(struct db_entry *dbe) static void track_setup(struct db_entry *dbe) { struct track *track = TRACK(dbe); + unsigned int i; filter_add(track->tr_lower, track); filter_add(track->tr_artist->ar_lower, track); - filter_add(track->tr_album->al_lower, track); + + for (i = 0; track->tr_album->al_tokens[i]; i++) + filter_add(track->tr_album->al_tokens[i], track); + for (i = 0; track->tr_album->al_alts[i]; i++) + filter_add(track->tr_album->al_alts[i], track); + track->tr_library->li_size++; } diff --git a/include/core/tags/album.h b/include/core/tags/album.h index 1af0f1d4..43029e11 100644 --- a/include/core/tags/album.h +++ b/include/core/tags/album.h @@ -18,9 +18,10 @@ #include struct album { - unsigned int al_year; /* This album's year. */ - gchar *al_name; /* This album's name. */ - gchar *al_lower; /* This album's name (lowercased). */ + unsigned int al_year; /* This album's year. */ + gchar *al_name; /* This album's name. */ + gchar **al_tokens; /* This album's tokenized strings. */ + gchar **al_alts; /* This album's alternate ascii tokens. */ struct artist *al_artist; struct db_entry al_dbe; }; diff --git a/tests/core/tags/album.c b/tests/core/tags/album.c index 87889492..9bae1d2c 100644 --- a/tests/core/tags/album.c +++ b/tests/core/tags/album.c @@ -9,7 +9,8 @@ static void test_verify_empty(struct album *album) { const struct db_ops *album_ops = test_album_ops(); test_equal(album->al_name, ""); - test_equal(album->al_lower, ""); + test_equal((void *)album->al_tokens[0], NULL); + test_equal((void *)album->al_alts[0], NULL); test_equal(album->al_year, 0); test_str_equal(album_ops->dbe_key(&album->al_dbe), "0/"); } @@ -18,7 +19,10 @@ static void test_verify_hyrule(struct album *album) { const struct db_ops *album_ops = test_album_ops(); test_equal(album->al_name, "Hyrule Symphony"); - test_equal(album->al_lower, "hyrule symphony"); + test_equal(album->al_tokens[0], "hyrule"); + test_equal(album->al_tokens[1], "symphony"); + test_equal((void *)album->al_tokens[2], NULL); + test_equal((void *)album->al_alts[0], NULL); test_equal(album->al_year, 1998); test_str_equal(album_ops->dbe_key(&album->al_dbe), "1998/Hyrule Symphony"); }