diff options
author | Victor Toso <me@victortoso.com> | 2013-05-16 01:40:55 -0300 |
---|---|---|
committer | Juan A. Suarez Romero <jasuarez@igalia.com> | 2013-05-22 15:19:33 +0000 |
commit | dc9dd8b10f08dcfd5d0711b695e2ab5cca92c751 (patch) | |
tree | f1129f090d9661e76dfe30b5725b198d5e599f45 | |
parent | 744174d64fba52b2ace9108aa6826ee196ef98fe (diff) |
magnatune: Implementing browse operation
Application can browse throw Artists, Albums and Genres.
https://bugzilla.gnome.org/show_bug.cgi?id=698523
-rw-r--r-- | src/magnatune/grl-magnatune.c | 260 |
1 files changed, 260 insertions, 0 deletions
diff --git a/src/magnatune/grl-magnatune.c b/src/magnatune/grl-magnatune.c index 0d11fa2..3c82d32 100644 --- a/src/magnatune/grl-magnatune.c +++ b/src/magnatune/grl-magnatune.c @@ -58,6 +58,46 @@ GRL_LOG_DOMAIN_STATIC(magnatune_log_domain); "OR (son.name like '%%%s%%') " \ "LIMIT %u OFFSET %u" +#define GRL_SQL_ARTISTS_QUERY_ALL \ + "SELECT DISTINCT art.artists_id, art.name " \ + "FROM artists art " \ + "LIMIT %u OFFSET %u" + +#define GRL_SQL_ALBUMS_QUERY_ALL \ + "SELECT DISTINCT alb.album_id, alb.name " \ + "FROM albums alb " \ + "LIMIT %u OFFSET %u" + +#define GRL_SQL_GENRES_QUERY_ALL \ + "SELECT DISTINCT gen.genre_id, gen.name " \ + "FROM genres gen " \ + "LIMIT %u OFFSET %u" + +#define GRL_SQL_ALBUMS_BY_GENRE \ + "SELECT DISTINCT alb.album_id, alb.name " \ + "FROM albums alb " \ + "LEFT OUTER JOIN genres_albums genalb " \ + "ON (alb.album_id = genalb.album_id) " \ + "WHERE (genalb.genre_id = %u) " \ + "LIMIT %u OFFSET %u" + +#define GRL_SQL_ALBUMS_BY_ARTIST \ + "SELECT DISTINCT alb.album_id, alb.name " \ + "FROM albums alb " \ + "WHERE (alb.artist_id = %u) " \ + "LIMIT %u OFFSET %u" + +#define GRL_SQL_SONGS_BY_ALBUM \ + "SELECT DISTINCT son.song_id, art.name, alb.name, son.name, " \ + "son.track_no, son.duration, son.mp3 " \ + "FROM songs son " \ + "LEFT OUTER JOIN albums alb " \ + "ON (alb.album_id = son.album_id) " \ + "LEFT OUTER JOIN artists art " \ + "ON (art.artists_id = alb.artist_id) " \ + "WHERE (alb.album_id = %u) " \ + "LIMIT %u OFFSET %u" + /* --- Files --- */ #define GRL_SQL_DB "grl-magnatune.db" @@ -77,6 +117,12 @@ GRL_LOG_DOMAIN_STATIC(magnatune_log_domain); #define DB_UPDATE_TIME_INTERVAL (60 * 60 * 24 * 7) #define CRC_UPDATE_TIME_INTERVAL (60 * 60 * 12) +#define MAGNATUNE_ROOT_ARTIST _("Artists") +#define MAGNATUNE_ROOT_ALBUM _("Albums") +#define MAGNATUNE_ROOT_GENRE _("Genres") + +#define MAGNATUNE_NAME_ID_SEP "-" + /* --- Plugin information --- */ #define SOURCE_ID "grl-magnatune" @@ -93,6 +139,13 @@ enum { MAGNATUNE_TRACK_URL_TO_MP3, }; +typedef enum { + MAGNATUNE_ARTIST_CAT, + MAGNATUNE_ALBUM_CAT, + MAGNATUNE_GENRE_CAT, + MAGNATUNE_NUM_CAT, +} MagnatuneCategory; + struct _GrlMagnatunePrivate { sqlite3 *db; }; @@ -109,6 +162,7 @@ struct _OperationSpec { const gchar *text; GrlMagnatuneExecCb magnatune_cb; GrlSourceResultCb callback; + GrlMedia *container; gpointer user_data; guint error_code; }; @@ -126,6 +180,9 @@ static const GList *grl_magnatune_source_supported_keys(GrlSource *source); static void grl_magnatune_source_search(GrlSource *source, GrlSourceSearchSpec *ss); +static void grl_magnatune_source_browse(GrlSource *source, + GrlSourceBrowseSpec *bs); + static gboolean magnatune_has_network_conn(void); static void magnatune_get_db_async(OperationSpec *os); @@ -188,6 +245,7 @@ grl_magnatune_source_class_init(GrlMagnatuneSourceClass * klass) source_class->supported_keys = grl_magnatune_source_supported_keys; source_class->search = grl_magnatune_source_search; + source_class->browse = grl_magnatune_source_browse; g_type_class_add_private(klass, sizeof(GrlMagnatunePrivate)); } @@ -607,6 +665,25 @@ build_media_track_from_stmt(sqlite3_stmt *sql_stmt) return media; } +static GrlMedia* +build_media_id_name_from_stmt(sqlite3_stmt *sql_stmt) +{ + GrlMedia *media = NULL; + guint media_id = 0; + gchar *id = NULL; + const gchar *media_name = NULL; + + media = grl_media_box_new(); + media_id = (guint) sqlite3_column_int(sql_stmt, 0); + media_name = (gchar *) sqlite3_column_text(sql_stmt, 1); + id = g_strdup_printf("%d", media_id); + grl_media_set_id(media, id); + grl_media_set_title(media, media_name); + g_free(id); + + return media; +} + static GList* magnatune_sqlite_execute(OperationSpec *os, gchar *sql, @@ -665,6 +742,162 @@ end_sqlite_execute: } static void +magnatune_browse_root(OperationSpec *os) +{ + GrlMedia *media = NULL; + guint num = 0; + gchar *id = NULL; + + GRL_DEBUG("magnatune_browse_root"); + + if (os->skip > 1 || os->count == 0) { + os->callback(os->source, os->operation_id, NULL, 0, os->user_data, NULL); + return; + } + + num = (os->count > MAGNATUNE_NUM_CAT) ? MAGNATUNE_NUM_CAT: os->count; + + media = grl_media_box_new(); + grl_media_set_title(media, MAGNATUNE_ROOT_ARTIST); + id = g_strdup_printf("root-%d", MAGNATUNE_ARTIST_CAT); + grl_media_set_id(media, id); + num--; + os->callback(os->source, os->operation_id, media, num, os->user_data, NULL); + g_free(id); + + if (num == 0) + return; + + media = grl_media_box_new(); + grl_media_set_title(media, MAGNATUNE_ROOT_ALBUM); + id = g_strdup_printf("root-%d", MAGNATUNE_ALBUM_CAT); + grl_media_set_id(media, id); + num--; + os->callback(os->source, os->operation_id, media, num, os->user_data, NULL); + g_free(id); + + if (num == 0) + return; + + media = grl_media_box_new(); + grl_media_set_title(media, MAGNATUNE_ROOT_GENRE); + id = g_strdup_printf("root-%d", MAGNATUNE_GENRE_CAT); + grl_media_set_id(media, id); + num--; + os->callback(os->source, os->operation_id, media, num, os->user_data, NULL); + g_free(id); +} + +static void +magnatune_execute_browse(OperationSpec *os) +{ + MagnatuneBuildMediaFn *build_fn; + GrlMedia *media = NULL; + const gchar *container_id = NULL; + gchar *sql = NULL; + gchar **touple = NULL; + gchar *box_id = NULL; + gchar *category_str_id = NULL; + gint id = 0; + gint num_medias = 0; + static GList *iter = NULL; + static GList *list_medias = NULL; + GError *err = NULL; + + GRL_DEBUG("magnatune_execute_browse"); + + container_id = grl_media_get_id(os->container); + if (container_id == NULL) { + magnatune_browse_root(os); + goto end_browse; + } + + touple = g_strsplit_set(container_id, MAGNATUNE_NAME_ID_SEP, 0); + id = g_ascii_strtoll(touple[1], NULL, 10); + build_fn = build_media_id_name_from_stmt; + + if (strcmp(touple[0], "root") == 0) { + switch (id) { + case MAGNATUNE_ARTIST_CAT: + category_str_id = g_strdup("artist"); + sql = g_strdup_printf(GRL_SQL_ARTISTS_QUERY_ALL, os->count, os->skip); + break; + + case MAGNATUNE_ALBUM_CAT: + category_str_id = g_strdup("album"); + sql = g_strdup_printf(GRL_SQL_ALBUMS_QUERY_ALL, os->count, os->skip); + break; + + case MAGNATUNE_GENRE_CAT: + category_str_id = g_strdup("genre"); + sql = g_strdup_printf(GRL_SQL_GENRES_QUERY_ALL, os->count, os->skip); + break; + } + + } else if (strcmp(touple[0], "artist") == 0) { + category_str_id = g_strdup("album"); + sql = g_strdup_printf(GRL_SQL_ALBUMS_BY_ARTIST, id, os->count, os->skip); + + } else if (strcmp(touple[0], "album") == 0) { + category_str_id = g_strdup("track"); + sql = g_strdup_printf(GRL_SQL_SONGS_BY_ALBUM, id, os->count, os->skip); + build_fn = build_media_track_from_stmt; + + } else if (strcmp(touple[0], "genre") == 0) { + category_str_id = g_strdup("album"); + sql = g_strdup_printf(GRL_SQL_ALBUMS_BY_GENRE, id, os->count, os->skip); + + } else { + err = g_error_new(GRL_CORE_ERROR, + GRL_CORE_ERROR_BROWSE_FAILED, + _("Invalid container identifier %s"), + container_id); + } + g_strfreev(touple); + + if (sql == NULL || err != NULL) + goto end_browse; + + /* We have the right sql-query, execute */ + list_medias = magnatune_sqlite_execute(os, sql, build_fn, &err); + g_free(sql); + + if (list_medias == NULL) + goto end_browse; + + num_medias = g_list_length(list_medias) - 1;; + for (iter = list_medias; iter; iter = iter->next) { + media = iter->data; + box_id = g_strdup_printf("%s-%s", + category_str_id, + grl_media_get_id(media)); + grl_media_set_id(media, box_id); + g_free(box_id); + + os->callback(os->source, + os->operation_id, + media, + num_medias, + os->user_data, + NULL); + num_medias--; + } + + g_list_free(list_medias); + +end_browse: + if (err != NULL) { + os->callback(os->source, os->operation_id, NULL, 0, os->user_data, err); + g_error_free(err); + } + + if (category_str_id != NULL) + g_free(category_str_id); + + g_slice_free(OperationSpec, os); +} + +static void magnatune_execute_search(OperationSpec *os) { GrlMedia *media = NULL; @@ -761,3 +994,30 @@ grl_magnatune_source_search(GrlSource *source, GrlSourceSearchSpec *ss) magnatune_check_update(); } } + +static void +grl_magnatune_source_browse(GrlSource *source, GrlSourceBrowseSpec *bs) +{ + OperationSpec *os = NULL; + + os = g_slice_new0(OperationSpec); + os->source = bs->source; + os->operation_id = bs->operation_id; + os->container = bs->container; + os->count = grl_operation_options_get_count(bs->options); + os->skip = grl_operation_options_get_skip(bs->options); + os->callback = bs->callback; + os->user_data = bs->user_data; + os->error_code = GRL_CORE_ERROR_BROWSE_FAILED; + os->magnatune_cb = NULL; + + if (GRL_MAGNATUNE_SOURCE(source)->priv->db == NULL) { + /* Get database first, then execute the browse */ + os->magnatune_cb = magnatune_execute_browse; + magnatune_get_crc_async(); + magnatune_get_db_async(os); + } else { + magnatune_execute_browse(os); + magnatune_check_update(); + } +} |