From eb5c0185e7c518ade9d99528ef4873934bc08640 Mon Sep 17 00:00:00 2001 From: Anna Schumaker Date: Thu, 14 Jul 2016 07:51:05 -0400 Subject: [PATCH] core/tags/album: Album art fetching improvements - Allocate CaaCoverArt as needed, rather than sharing one object - Use MusicBrainz fuzzy search to match more albums - Escape most special characters in filenames Signed-off-by: Anna Schumaker --- core/tags/album.c | 103 ++++++++++++++++++++-------------------------- 1 file changed, 44 insertions(+), 59 deletions(-) diff --git a/core/tags/album.c b/core/tags/album.c index 226369cc..53db4b89 100644 --- a/core/tags/album.c +++ b/core/tags/album.c @@ -13,8 +13,10 @@ static struct database album_db; static inline void __album_init_file(struct album *al, struct cache_file *f) { + gchar *name = g_uri_escape_string(al->al_name, " ", true); cache_file_init(f, g_strdup_printf("%d", al->al_year), - g_strdup_printf("%s.jpg", al->al_name)); + g_strdup_printf("%s.jpg", name)); + g_free(name); } static inline void __album_deinit_file(struct cache_file *f) @@ -23,18 +25,22 @@ static inline void __album_deinit_file(struct cache_file *f) g_free(f->cf_name); } -static bool __album_fetch_cover(struct album *album, gchar *releaseid, - CaaCoverArt *caa) +static bool __album_fetch_cover(struct album *album, gchar *releaseid) { struct cache_file file; CaaImageData image; + CaaCoverArt *caa; gchar error[256]; + caa = caa_coverart_new(OCARINA_NAME); + if (!caa) + return false; + image = caa_coverart_fetch_front(caa, releaseid); if (!image) { caa_coverart_get_lasterrormessage(caa, error, sizeof(error)); g_printf("Cover Art Archive: %s\n", error); - return false; + goto out; } __album_init_file(album, &file); @@ -46,6 +52,8 @@ static bool __album_fetch_cover(struct album *album, gchar *releaseid, __album_deinit_file(&file); caa_imagedata_delete(image); +out: + caa_coverart_delete(caa); return album_artwork_exists(album); } @@ -54,37 +62,32 @@ static bool __album_foreach_fetch(struct album *album, Mb5Metadata metadata) Mb5ReleaseList list = mb5_metadata_get_releaselist(metadata); gchar releaseid[40]; Mb5Release release; - CaaCoverArt *caa; - bool ret = false; unsigned int i; - caa = caa_coverart_new(OCARINA_NAME); - if (!caa) - return false; - for (i = 0; i < mb5_release_list_size(list); i++) { release = mb5_release_list_item(list, i); if (!release) break; mb5_release_get_id(release, releaseid, sizeof(releaseid)); - ret = __album_fetch_cover(album, releaseid, caa); - if (ret) - break; + if (__album_fetch_cover(album, releaseid)) + return true; } - caa_coverart_delete(caa); - return ret; + return false; } -static bool __album_query_releaseid(struct album *album, gchar *param) +static bool __album_run_query(struct album *album, gchar *term1, + gchar *term2, gchar *term3) { + gchar *param, *query = "query"; Mb5Metadata data = NULL; - gchar *query = "query"; unsigned int code; gchar error[256]; bool ret = false; Mb5Query *mb5; + param = g_strjoin(" AND ", term1, term2, term3, NULL); + do { mb5 = mb5_query_new(OCARINA_NAME, NULL, 0); if (!mb5) @@ -105,62 +108,44 @@ static bool __album_query_releaseid(struct album *album, gchar *param) mb5_metadata_delete(data); } - return ret; -} - -static bool __album_query_name(struct album *album, gchar *extra, bool quoted) -{ - gchar *fmt = "release:%s%s%s%s"; - gchar *param = g_strdup_printf(fmt, quoted ? "\"" : "", - quoted ? album->al_name : album->al_lower, - quoted ? "\"" : "", - extra ? extra : ""); - bool ret = __album_query_releaseid(album, param); - g_free(param); - return ret; -} - -static bool __album_query_artist(struct album *album, bool quoted) -{ - struct artist *artist = album->al_artist; - gchar *fmt = " AND artist:%s%s%s"; - gchar *param = g_strdup_printf(fmt, quoted ? "\"" : "", - quoted ? artist->ar_name : artist->ar_lower, - quoted ? "\"" : ""); - bool ret = __album_query_name(album, param, !quoted); - g_free(param); - return ret; -} - -static bool __album_query_year(struct album *album) -{ - gchar *param = g_strdup_printf(" AND date:%d", album->al_year); - bool ret = __album_query_name(album, param, true); g_free(param); return ret; } static bool __album_fetch_artwork(struct album *album) { - Mb5Query *mb5; + struct artist *artist = album->al_artist; + gchar *terms[4] = {NULL, NULL, NULL, NULL}; + unsigned int i = 0; if (album_artwork_exists(album)) return true; + if (string_length(album->al_name) == 0) + return true; - mb5 = mb5_query_new(OCARINA_NAME, NULL, 0); - if (!mb5) - return false; + terms[i++] = g_strdup_printf("release:\"%s\"~", album->al_lower); + if (artist && strncmp(artist->ar_lower, "various", 7) != 0) + terms[i++] = g_strdup_printf("artist:\"%s\"~", artist->ar_name); + if (album->al_year > 0) + terms[i++] = g_strdup_printf("date:%d*", album->al_year); - if (album->al_artist && __album_query_artist(album, true)) + if (terms[2]) { + if (__album_run_query(album, terms[0], terms[1], terms[2])) + goto out; + if (__album_run_query(album, terms[0], terms[2], NULL)) + goto out; + if (__album_run_query(album, terms[1], terms[2], NULL)) + goto out; + } + + if (terms[1] && __album_run_query(album, terms[0], terms[1], NULL)) goto out; - if (album->al_artist && __album_query_artist(album, false)) - goto out; - if (album->al_year && __album_query_year(album)) - goto out; - __album_query_name(album, NULL, true); + + __album_run_query(album, terms[0], NULL, NULL); out: - mb5_query_delete(mb5); + for (i = 0; terms[i]; i++) + g_free(terms[i]); return true; }