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 <Anna@OcarinaProject.net>
This commit is contained in:
Anna Schumaker 2016-07-14 07:51:05 -04:00
parent 617088c89b
commit eb5c0185e7
1 changed files with 44 additions and 59 deletions

View File

@ -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;
}