core/tags/album: Add artist and genre arguments to album_find()

And propegate these through the alloc steps to create an album with the
correct artist and genre tags set.

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
Anna Schumaker 2016-08-12 09:10:57 -04:00
parent ffd09d410c
commit 0ea75ccb29
4 changed files with 71 additions and 41 deletions

View File

@ -173,7 +173,8 @@ static gchar *__album_key(struct artist *artist, struct genre *genre,
genre_index(genre), year, name);
}
static struct album *__album_alloc(gchar *name, unsigned int year)
static struct album *__album_alloc(struct artist *artist, struct genre *genre,
gchar *name, unsigned int year)
{
struct album *album = g_malloc(sizeof(struct album));
@ -181,8 +182,8 @@ static struct album *__album_alloc(gchar *name, unsigned int year)
album->al_year = year;
album->al_name = name;
album->al_tokens = g_str_tokenize_and_fold(name, NULL, &album->al_alts);
album->al_artist = NULL;
album->al_genre = NULL;
album->al_artist = artist;
album->al_genre = genre;
if (!album_artwork_exists(album))
idle_schedule(IDLE_ASYNC, IDLE_FUNC(__album_fetch_artwork), album);
@ -190,14 +191,28 @@ static struct album *__album_alloc(gchar *name, unsigned int year)
}
static struct db_entry *album_alloc(const gchar *key)
static struct db_entry *__album_alloc_v0(const gchar *key)
{
unsigned int year;
gchar *name;
if (sscanf(key, "%u/%m[^\n]", &year, &name) == 1)
name = g_strdup("");
return &__album_alloc(name, year)->al_dbe;
return &__album_alloc(NULL, NULL, name, year)->al_dbe;
}
static struct db_entry *album_alloc(const gchar *key)
{
unsigned int artist_id, genre_id, year, n;
gchar *name;
n = sscanf(key, "%u/%u/%u/%m[^\n]", &artist_id, &genre_id, &year, &name);
if (n == 1)
return __album_alloc_v0(key);
else if (n == 3)
name = g_strdup("");
return &__album_alloc(artist_get(artist_id), genre_get(genre_id),
name, year)->al_dbe;
}
static void album_free(struct db_entry *dbe)
@ -224,7 +239,7 @@ static struct db_entry *album_read(struct file *file)
name = g_strdup("");
g_free(line);
return &__album_alloc(name, year)->al_dbe;
return &__album_alloc(NULL, NULL, name, year)->al_dbe;
}
static void album_write(struct file *file, struct db_entry *dbe)
@ -254,9 +269,10 @@ void album_db_deinit()
db_deinit(&album_db);
}
struct album *album_find(const gchar *name, unsigned int year)
struct album *album_find(struct artist *artist, struct genre *genre,
const gchar *name, unsigned int year)
{
gchar *key = __album_key(NULL, NULL, name, year);
gchar *key = __album_key(artist, genre, name, year);
struct album *album = ALBUM(db_find(&album_db, key));
g_free(key);
return album;

View File

@ -65,16 +65,12 @@ struct db_entry *track_alloc(const gchar *key)
tag = taglib_file_tag(file);
audio = taglib_file_audioproperties(file);
track->tr_album = album_find(taglib_tag_album(tag), taglib_tag_year(tag));
track->tr_artist = artist_find(taglib_tag_artist(tag));
track->tr_genre = genre_find(taglib_tag_genre(tag));
track->tr_album = album_find(track->tr_artist, track->tr_genre,
taglib_tag_album(tag), taglib_tag_year(tag));
track->tr_library = library;
if (track->tr_album->al_artist == NULL)
track->tr_album->al_artist = track->tr_artist;
if (track->tr_album->al_genre == NULL)
track->tr_album->al_genre = track->tr_genre;
unplayed_count++;
track->tr_count = 0;
track->tr_length = taglib_audioproperties_length(audio);
@ -124,6 +120,9 @@ static gchar *track_key(struct db_entry *dbe)
static struct db_entry *track_read(struct file *file)
{
unsigned int library_id, artist_id, album_id, genre_id;
struct artist *artist;
struct genre *genre;
struct album *album;
struct track *track = __track_alloc();
file_readf(file, "%u %u %u %u %hu", &library_id, &artist_id, &album_id,
@ -135,15 +134,17 @@ static struct db_entry *track_read(struct file *file)
if (track->tr_count == 0)
unplayed_count++;
track->tr_album = album_get(album_id);
track->tr_artist = artist_get(artist_id);
track->tr_genre = genre_get(genre_id);
track->tr_library = library_get(library_id);
album = album_get(album_id);
artist = artist_get(artist_id);
genre = genre_get(genre_id);
if (track->tr_album->al_artist == NULL)
track->tr_album->al_artist = track->tr_artist;
if (track->tr_album->al_genre == NULL)
track->tr_album->al_genre = track->tr_genre;
if (album->al_artist != artist || album->al_genre != genre)
album = album_find(artist, genre, album->al_name, album->al_year);
track->tr_album = album;
track->tr_artist = artist;
track->tr_genre = genre;
track->tr_library = library_get(library_id);
track->tr_title = file_readl(file);
track->tr_tokens = g_str_tokenize_and_fold(track->tr_title, NULL,

View File

@ -36,8 +36,9 @@ void album_db_init();
/* Called to clean up the album database. */
void album_db_deinit();
/* Called to find an album tag by name and year. */
struct album *album_find(const gchar *, unsigned int);
/* Called to find an album tag by artist, name and year. */
struct album *album_find(struct artist *, struct genre *,
const gchar *, unsigned int);
/* Called to get an album tag with a specific index. */
struct album *album_get(const unsigned int);

View File

@ -12,11 +12,13 @@ static void test_verify_empty(struct album *album)
g_assert_cmpstr(album->al_name, ==, "");
g_assert_null(album->al_tokens[0]);
g_assert_null(album->al_alts[0]);
g_assert_null(album->al_artist);
g_assert_cmpuint(album->al_year, ==, 0);
g_assert_cmpstr_free(album_ops->dbe_key(&album->al_dbe), ==, "0/");
}
static void test_verify_hyrule(struct album *album)
static void test_verify_hyrule(struct album *album, struct artist *artist,
struct genre *genre)
{
const struct db_ops *album_ops = test_album_ops();
gchar *key;
@ -26,10 +28,12 @@ static void test_verify_hyrule(struct album *album)
g_assert_cmpstr(album->al_tokens[1], ==, "symphony");
g_assert_null(album->al_tokens[2]);
g_assert_null(album->al_alts[0]);
g_assert(album->al_artist == artist);
g_assert(album->al_genre == genre);
g_assert_cmpuint(album->al_year, ==, 1998);
key = album_ops->dbe_key(&album->al_dbe);
if (album->al_artist)
if (artist && genre)
g_assert_cmpstr_free(key, ==, "0/0/1998/Hyrule Symphony");
else
g_assert_cmpstr_free(key, ==, "1998/Hyrule Symphony");
@ -48,11 +52,8 @@ static void test_album()
koji = artist_find("Koji Kondo");
genre = genre_find("Video Game Music");
album = ALBUM(album_ops->dbe_alloc("1998/Hyrule Symphony"));
test_verify_hyrule(album);
album->al_artist = koji;
album->al_genre = genre;
test_verify_hyrule(album);
album = ALBUM(album_ops->dbe_alloc("0/0/1998/Hyrule Symphony"));
test_verify_hyrule(album, koji, genre);
g_assert_true( album_match_token(album, "hyrule"));
g_assert_true( album_match_token(album, "symphony"));
g_assert_false(album_match_token(album, "skyward"));
@ -71,7 +72,7 @@ static void test_album()
album = ALBUM(album_ops->dbe_read(&f));
file_close(&f);
test_verify_hyrule(album);
test_verify_hyrule(album, NULL, NULL);
album_ops->dbe_free(&album->al_dbe);
}
@ -104,18 +105,29 @@ static void test_album_db()
{
const struct db_ops *album_ops = test_album_ops();
struct database album_db;
struct artist *koji;
struct genre *genre;
struct album *album;
album = album_find("Hyrule Symphony", 1998);
test_verify_hyrule(album);
g_assert(album_find("Hyrule Symphony", 1998) == album);
album = album_find(NULL, NULL, "Hyrule Symphony", 1998);
test_verify_hyrule(album, NULL, NULL);
g_assert(album_find(NULL, NULL, "Hyrule Symphony", 1998) == album);
g_assert(album_get(0) == album);
g_assert_null(album_get(1));
koji = artist_find("Koji Kondo");
genre = genre_find("Video Game Music");
album = album_find(koji, genre, "Hyrule Symphony", 1998);
test_verify_hyrule(album, koji, genre);
g_assert(album_find(NULL, NULL, "Hyrule Symphony", 1998) != album);
g_assert(album_find(koji, genre, "Hyrule Symphony", 1998) == album);
g_assert(album_get(0) != album);
g_assert(album_get(1) == album);
g_assert_null(album_get(2));
db_init(&album_db, "album.db", false, album_ops, 0, 0);
db_load(&album_db);
g_assert_cmpuint(album_db.db_size, ==, 1);
g_assert_cmpuint(album_db.db_size, ==, 2);
db_deinit(&album_db);
}
@ -136,10 +148,10 @@ static void test_album_artwork()
m_path = g_build_filename(cache, "ocarina-test", "core", "tags", "album", "2000", "Majora%27s Mask.jpg", NULL);
w_path = g_build_filename(cache, "ocarina-test", "core", "tags", "album", "0", "Wind Waker.jpg", NULL);
ocarina = album_find("Ocarina of Time", 1998);
majora = album_find("Majora's Mask", 2000);
wind = album_find("Wind Waker", 0);
koji = artist_find("Koji Kondo");
ocarina = album_find(koji, NULL, "Ocarina of Time", 1998);
majora = album_find(NULL, NULL, "Majora's Mask", 2000);
wind = album_find(NULL, NULL, "Wind Waker", 0);
ocarina->al_artist = koji;
g_assert_false(album_artwork_exists(ocarina));
@ -159,7 +171,7 @@ static void test_album_artwork()
g_assert_cmpstr_free(album_artwork_path(wind), ==, w_path);
/* Import the original Ocarina of Time album art. */
ocarina_3d = album_find("Ocarina of Time 3D", 2011);
ocarina_3d = album_find(NULL, NULL, "Ocarina of Time 3D", 2011);
g_assert_false(album_artwork_exists(ocarina_3d));
album_artwork_import(ocarina_3d, NULL);
g_assert_false(album_artwork_exists(ocarina_3d));