summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuan A. Suarez Romero <jasuarez@igalia.com>2010-03-12 21:24:39 +0100
committerJuan A. Suarez Romero <jasuarez@igalia.com>2010-03-12 21:24:39 +0100
commite230523509d075223ec53adcbb02bebf1dce084c (patch)
tree530b6b345694f2badffb1f5d82903a6441d793c7
parenta800d4b946e352b4f530d5b446b32d539469c3d1 (diff)
parentb6a2a65689f0563d0990bbdb8fa57d297d61329f (diff)
downloadgrilo-plugins-e230523509d075223ec53adcbb02bebf1dce084c.tar.gz
Merge commit 'grilo-plugins-0.1.4' into debian
-rw-r--r--NEWS23
-rw-r--r--configure.ac42
-rw-r--r--src/Makefile.am6
-rw-r--r--src/apple-trailers/grl-apple-trailers.c36
-rw-r--r--src/bookmarks/grl-bookmarks.c60
-rw-r--r--src/fake-metadata/grl-fake-metadata.c65
-rw-r--r--src/filesystem/grl-filesystem.c50
-rw-r--r--src/flickr/grl-flickr.c77
-rw-r--r--src/jamendo/grl-jamendo.c96
-rw-r--r--src/lastfm-albumart/grl-lastfm-albumart.c20
-rw-r--r--src/metadata-store/Makefile.am26
-rw-r--r--src/metadata-store/grl-metadata-store.c681
-rw-r--r--src/metadata-store/grl-metadata-store.h75
-rw-r--r--src/podcasts/grl-podcasts.c160
-rw-r--r--src/shoutcast/grl-shoutcast.c54
-rw-r--r--src/upnp/grl-upnp.c55
-rw-r--r--src/youtube/TODO6
-rw-r--r--src/youtube/grl-youtube.c93
-rw-r--r--test/main.c140
19 files changed, 1375 insertions, 390 deletions
diff --git a/NEWS b/NEWS
index d5a49f9..a63094c 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,23 @@
-New in 0.1.3
+NEW in 0.1.4
+============
+
+ * General
+ * Updates related with changes in Grilo API
+
+ * Bookmarks
+ * Small improvements
+
+ * Flickr plugin
+ * Use the new configuration system
+
+ * Metadata-Store plugin
+ * New plugin where to save metadata
+
+ * Podcasts plugin
+ * Small improvements
+
+
+NEW in 0.1.3
============
* General
@@ -10,7 +29,7 @@ New in 0.1.3
* Bookmarks plugin
* Small improvements
- * Podcats plugin
+ * Podcasts plugin
* Small improvements
* Shoutcast plugin
diff --git a/configure.ac b/configure.ac
index cd3542a..dde5f14 100644
--- a/configure.ac
+++ b/configure.ac
@@ -6,7 +6,7 @@
# Copyright (C) 2010 Igalia S.L.. All rights reserved.
m4_define([prj_name], [grilo-plugins])
-m4_define([prj_version], [0.1.3])
+m4_define([prj_version], [0.1.4])
AC_INIT([prj_name], [prj_version])
@@ -65,7 +65,7 @@ AC_DEFINE_UNQUOTED(GRL_PLUGINS_DIR, "$GRL_PLUGINS_DIR", [Plugins directory])
PKG_CHECK_MODULES(DEPS, glib-2.0 \
gobject-2.0 \
gmodule-2.0 \
- grilo-0.1 >= 0.1.3)
+ grilo-0.1 >= 0.1.4)
AC_SUBST(DEPS_CFLAGS)
AC_SUBST(DEPS_LIBS)
@@ -149,8 +149,8 @@ AM_CONDITIONAL([DEBUG], [test "x$enable_debug" = "xyes"])
AC_ARG_ENABLE(fakemetadata,
AC_HELP_STRING([--enable-fakemetadata],
- [enable Fake Metadata plugin (default: yes)]),,
- [enable_fakemetadata=yes])
+ [enable Fake Metadata plugin (default: no)]),,
+ [enable_fakemetadata=no])
AM_CONDITIONAL([FAKEMETADATA_PLUGIN], [test "x$enable_fakemetadata" = "xyes"])
GRL_PLUGINS_ALL="$GRL_PLUGINS_ALL fakemetadata"
@@ -321,7 +321,7 @@ fi
# ----------------------------------------------------------
AC_ARG_ENABLE(flickr,
- AC_HELP_STRING([--flickr],
+ AC_HELP_STRING([--enable-flickr],
[enable Flickr plugin (default: auto)]),
[
case "$enableval" in
@@ -502,6 +502,37 @@ then
fi
# ----------------------------------------------------------
+# BUILD METADATA-STORE PLUGIN
+# ----------------------------------------------------------
+
+AC_ARG_ENABLE(metadata-store,
+ AC_HELP_STRING([--enable-metadata-store],
+ [enable Metadata Store plugin (default: auto)]),
+ [
+ case "$enableval" in
+ yes)
+ if test "x$HAVE_SQLITE" = "xno"; then
+ AC_MSG_ERROR([sqlite3 not found, install it or use --disable-metadata-store])
+ fi
+ ;;
+ esac
+ ],
+ [
+ if test "x$HAVE_SQLITE" = "xyes"; then
+ enable_metadata_store=yes
+ else
+ enable_metadata_store=no
+ fi
+ ])
+
+AM_CONDITIONAL([METADATA_STORE_PLUGIN], [test "x$enable_metadata_store" = "xyes"])
+GRL_PLUGINS_ALL="$GRL_PLUGINS_ALL metadata-store"
+if test "x$enable_metadata_store" = "xyes"
+then
+ GRL_PLUGINS_ENABLED="$GRL_PLUGINS_ENABLED metadata-store"
+fi
+
+# ----------------------------------------------------------
# GETTEXT
# ----------------------------------------------------------
@@ -536,6 +567,7 @@ AC_CONFIG_FILES([
src/bookmarks/Makefile
src/shoutcast/Makefile
src/apple-trailers/Makefile
+ src/metadata-store/Makefile
test/Makefile
debian/grilo-0.1-plugins.install
])
diff --git a/src/Makefile.am b/src/Makefile.am
index fc8dc4f..c45f9d3 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -51,7 +51,11 @@ if APPLE_TRAILERS_PLUGIN
SUBDIRS += apple-trailers
endif
-DIST_SUBDIRS = youtube fake-metadata filesystem jamendo lastfm-albumart upnp flickr podcasts bookmarks shoutcast apple-trailers
+if METADATA_STORE_PLUGIN
+SUBDIRS += metadata-store
+endif
+
+DIST_SUBDIRS = youtube fake-metadata filesystem jamendo lastfm-albumart upnp flickr podcasts bookmarks shoutcast apple-trailers metadata-store
MAINTAINERCLEANFILES = \
*.in \
diff --git a/src/apple-trailers/grl-apple-trailers.c b/src/apple-trailers/grl-apple-trailers.c
index f0bb2d7..37afc4d 100644
--- a/src/apple-trailers/grl-apple-trailers.c
+++ b/src/apple-trailers/grl-apple-trailers.c
@@ -73,7 +73,8 @@ typedef struct {
static GrlAppleTrailersSource *grl_apple_trailers_source_new (void);
gboolean grl_apple_trailers_plugin_init (GrlPluginRegistry *registry,
- const GrlPluginInfo *plugin);
+ const GrlPluginInfo *plugin,
+ GList *configs);
static const GList *grl_apple_trailers_source_supported_keys (GrlMetadataSource *source);
@@ -87,7 +88,8 @@ static void grl_apple_trailers_source_cancel (GrlMediaSource *source,
gboolean
grl_apple_trailers_plugin_init (GrlPluginRegistry *registry,
- const GrlPluginInfo *plugin)
+ const GrlPluginInfo *plugin,
+ GList *configs)
{
g_debug ("apple_trailers_plugin_init\n");
@@ -189,10 +191,10 @@ runtime_to_seconds (const gchar *runtime)
return seconds;
}
-static GrlContentMedia *
+static GrlMedia *
build_media_from_movie (xmlNodePtr node)
{
- GrlContentMedia * media;
+ GrlMedia * media;
gchar *movie_author;
gchar *movie_date;
gchar *movie_description;
@@ -203,7 +205,7 @@ build_media_from_movie (xmlNodePtr node)
gchar *movie_title;
gchar *movie_url;
- media = grl_content_video_new ();
+ media = grl_media_video_new ();
movie_id = (gchar *) xmlGetProp (node, (const xmlChar *) "id");
@@ -223,17 +225,17 @@ build_media_from_movie (xmlNodePtr node)
movie_url = get_node_value (node_dup, "/movieinfo/preview/large");
xmlFreeDoc (xml_doc);
- grl_content_media_set_id (media, movie_id);
- grl_content_media_set_author (media, movie_author);
- grl_content_media_set_date (media, movie_date);
- grl_content_media_set_description (media, movie_description);
- grl_content_media_set_duration (media, runtime_to_seconds (movie_duration));
- grl_content_media_set_title (media, movie_title);
- grl_content_set_string (GRL_CONTENT (media),
- GRL_METADATA_KEY_GENRE,
- movie_genre);
- grl_content_media_set_thumbnail (media, movie_thumbnail);
- grl_content_media_set_url (media, movie_url);
+ grl_media_set_id (media, movie_id);
+ grl_media_set_author (media, movie_author);
+ grl_media_set_date (media, movie_date);
+ grl_media_set_description (media, movie_description);
+ grl_media_set_duration (media, runtime_to_seconds (movie_duration));
+ grl_media_set_title (media, movie_title);
+ grl_data_set_string (GRL_DATA (media),
+ GRL_METADATA_KEY_GENRE,
+ movie_genre);
+ grl_media_set_thumbnail (media, movie_thumbnail);
+ grl_media_set_url (media, movie_url);
g_free (movie_id);
g_free (movie_author);
@@ -251,7 +253,7 @@ build_media_from_movie (xmlNodePtr node)
static gboolean
send_movie_info (OperationData *op_data)
{
- GrlContentMedia *media;
+ GrlMedia *media;
gboolean last = FALSE;
if (op_data->cancelled) {
diff --git a/src/bookmarks/grl-bookmarks.c b/src/bookmarks/grl-bookmarks.c
index 8b3c1aa..e341288 100644
--- a/src/bookmarks/grl-bookmarks.c
+++ b/src/bookmarks/grl-bookmarks.c
@@ -177,7 +177,8 @@ static void grl_bookmarks_source_remove (GrlMediaSource *source,
static gboolean
grl_bookmarks_plugin_init (GrlPluginRegistry *registry,
- const GrlPluginInfo *plugin)
+ const GrlPluginInfo *plugin,
+ GList *configs)
{
g_debug ("grl_bookmarks_plugin_init\n");
@@ -313,10 +314,10 @@ mime_is_audio (const gchar *mime)
return mime && strstr (mime, "audio") != NULL;
}
-static GrlContentMedia *
-build_media_from_stmt (GrlContentMedia *content, sqlite3_stmt *sql_stmt)
+static GrlMedia *
+build_media_from_stmt (GrlMedia *content, sqlite3_stmt *sql_stmt)
{
- GrlContentMedia *media = NULL;
+ GrlMedia *media = NULL;
gchar *id;
gchar *title;
gchar *url;
@@ -341,30 +342,30 @@ build_media_from_stmt (GrlContentMedia *content, sqlite3_stmt *sql_stmt)
if (!media) {
if (type == BOOKMARK_TYPE_CATEGORY) {
- media = GRL_CONTENT_MEDIA (grl_content_box_new ());
+ media = GRL_MEDIA (grl_media_box_new ());
} else if (mime_is_audio (mime)) {
- media = GRL_CONTENT_MEDIA (grl_content_media_new ());
+ media = GRL_MEDIA (grl_media_new ());
} else if (mime_is_video (mime)) {
- media = GRL_CONTENT_MEDIA (grl_content_media_new ());
+ media = GRL_MEDIA (grl_media_new ());
} else {
- media = GRL_CONTENT_MEDIA (grl_content_media_new ());
+ media = GRL_MEDIA (grl_media_new ());
}
}
- grl_content_media_set_id (media, id);
- grl_content_media_set_title (media, title);
+ grl_media_set_id (media, id);
+ grl_media_set_title (media, title);
if (url) {
- grl_content_media_set_url (media, url);
+ grl_media_set_url (media, url);
}
if (desc) {
- grl_content_media_set_description (media, desc);
+ grl_media_set_description (media, desc);
}
if (date) {
- grl_content_media_set_date (media, date);
+ grl_media_set_date (media, date);
}
if (type == BOOKMARK_TYPE_CATEGORY) {
- grl_content_box_set_childcount (GRL_CONTENT_BOX (media), childcount);
+ grl_media_box_set_childcount (GRL_MEDIA_BOX (media), childcount);
}
return media;
@@ -384,10 +385,10 @@ bookmark_metadata (GrlMediaSourceMetadataSpec *ms)
db = GRL_BOOKMARKS_SOURCE (ms->source)->priv->db;
- id = grl_content_media_get_id (ms->media);
+ id = grl_media_get_id (ms->media);
if (!id) {
/* Root category: special case */
- grl_content_media_set_title (ms->media, "");
+ grl_media_set_title (ms->media, "");
ms->callback (ms->source, ms->media, ms->user_data, NULL);
return;
}
@@ -430,7 +431,7 @@ produce_bookmarks_from_sql (OperationSpec *os, const gchar *sql)
gint r;
sqlite3_stmt *sql_stmt = NULL;
sqlite3 *db;
- GrlContentMedia *media;
+ GrlMedia *media;
GError *error = NULL;
GList *medias = NULL;
guint count = 0;
@@ -475,7 +476,7 @@ produce_bookmarks_from_sql (OperationSpec *os, const gchar *sql)
medias = g_list_reverse (medias);
iter = medias;
while (iter) {
- media = GRL_CONTENT_MEDIA (iter->data);
+ media = GRL_MEDIA (iter->data);
os->callback (os->source,
os->operation_id,
media,
@@ -556,8 +557,8 @@ remove_bookmark (sqlite3 *db, const gchar *bookmark_id, GError **error)
static void
store_bookmark (sqlite3 *db,
- GrlContentBox *parent,
- GrlContentMedia *bookmark,
+ GrlMediaBox *parent,
+ GrlMedia *bookmark,
GError **error)
{
gint r;
@@ -570,20 +571,21 @@ store_bookmark (sqlite3 *db,
const gchar *mime;
gchar *date;
guint type;
+ gchar *id;
g_debug ("store_bookmark");
- title = grl_content_media_get_title (bookmark);
- url = grl_content_media_get_url (bookmark);
- desc = grl_content_media_get_description (bookmark);
- mime = grl_content_media_get_mime (bookmark);
+ title = grl_media_get_title (bookmark);
+ url = grl_media_get_url (bookmark);
+ desc = grl_media_get_description (bookmark);
+ mime = grl_media_get_mime (bookmark);
g_get_current_time (&now);
date = g_time_val_to_iso8601 (&now);
if (!parent) {
parent_id = "0";
} else {
- parent_id = grl_content_media_get_id (parent);
+ parent_id = grl_media_get_id (parent);
}
if (!parent_id) {
parent_id = "0";
@@ -604,7 +606,7 @@ store_bookmark (sqlite3 *db,
g_debug ("URL: '%s'", url);
- if (GRL_IS_CONTENT_BOX (bookmark)) {
+ if (GRL_IS_MEDIA_BOX (bookmark)) {
type = BOOKMARK_TYPE_CATEGORY;
} else {
type = BOOKMARK_TYPE_STREAM;
@@ -646,6 +648,10 @@ store_bookmark (sqlite3 *db,
}
sqlite3_finalize (sql_stmt);
+
+ id = g_strdup_printf ("%llu", sqlite3_last_insert_rowid (db));
+ grl_media_set_id (bookmark, id);
+ g_free (id);
}
/* ================== API Implementation ================ */
@@ -690,7 +696,7 @@ grl_bookmarks_source_browse (GrlMediaSource *source,
os = g_new0 (OperationSpec, 1);
os->source = bs->source;
os->operation_id = bs->browse_id;
- os->media_id = grl_content_media_get_id (bs->container);
+ os->media_id = grl_media_get_id (bs->container);
os->count = bs->count;
os->skip = bs->skip;
os->callback = bs->callback;
diff --git a/src/fake-metadata/grl-fake-metadata.c b/src/fake-metadata/grl-fake-metadata.c
index d0bacae..25e0e17 100644
--- a/src/fake-metadata/grl-fake-metadata.c
+++ b/src/fake-metadata/grl-fake-metadata.c
@@ -49,20 +49,27 @@ static GrlFakeMetadataSource *grl_fake_metadata_source_new (void);
static void grl_fake_metadata_source_resolve (GrlMetadataSource *source,
GrlMetadataSourceResolveSpec *rs);
+static void grl_fake_metadata_source_set_metadata (GrlMetadataSource *source,
+ GrlMetadataSourceSetMetadataSpec *sms);
+
static const GList *grl_fake_metadata_source_supported_keys (GrlMetadataSource *source);
static const GList *grl_fake_metadata_source_key_depends (GrlMetadataSource *source,
GrlKeyID key_id);
+static const GList *grl_fake_metadata_source_writable_keys (GrlMetadataSource *source);
+
gboolean grl_fake_metadata_source_plugin_init (GrlPluginRegistry *registry,
- const GrlPluginInfo *plugin);
+ const GrlPluginInfo *plugin,
+ GList *configs);
/* =================== GrlFakeMetadata Plugin =============== */
gboolean
grl_fake_metadata_source_plugin_init (GrlPluginRegistry *registry,
- const GrlPluginInfo *plugin)
+ const GrlPluginInfo *plugin,
+ GList *configs)
{
g_debug ("grl_fake_metadata_source_plugin_init");
GrlFakeMetadataSource *source = grl_fake_metadata_source_new ();
@@ -102,6 +109,8 @@ grl_fake_metadata_source_class_init (GrlFakeMetadataSourceClass * klass)
metadata_class->supported_keys = grl_fake_metadata_source_supported_keys;
metadata_class->key_depends = grl_fake_metadata_source_key_depends;
metadata_class->resolve = grl_fake_metadata_source_resolve;
+ metadata_class->set_metadata = grl_fake_metadata_source_set_metadata;
+ metadata_class->writable_keys = grl_fake_metadata_source_writable_keys;
}
static void
@@ -116,37 +125,37 @@ G_DEFINE_TYPE (GrlFakeMetadataSource,
/* ======================= Utilities ==================== */
static void
-fill_metadata (GrlContentMedia *media, GrlKeyID key_id)
+fill_metadata (GrlMedia *media, GrlKeyID key_id)
{
switch (key_id) {
case GRL_METADATA_KEY_AUTHOR:
- grl_content_media_set_author (media, "fake author");
+ grl_media_set_author (media, "fake author");
break;
case GRL_METADATA_KEY_ARTIST:
- grl_content_set_string (GRL_CONTENT (media),
- GRL_METADATA_KEY_ARTIST, "fake artist");
+ grl_data_set_string (GRL_DATA (media),
+ GRL_METADATA_KEY_ARTIST, "fake artist");
break;
case GRL_METADATA_KEY_ALBUM:
- grl_content_set_string (GRL_CONTENT (media),
- GRL_METADATA_KEY_ALBUM, "fake album");
+ grl_data_set_string (GRL_DATA (media),
+ GRL_METADATA_KEY_ALBUM, "fake album");
break;
case GRL_METADATA_KEY_GENRE:
- grl_content_set_string (GRL_CONTENT (media),
- GRL_METADATA_KEY_GENRE, "fake genre");
+ grl_data_set_string (GRL_DATA (media),
+ GRL_METADATA_KEY_GENRE, "fake genre");
break;
case GRL_METADATA_KEY_DESCRIPTION:
- grl_content_media_set_description (media, "fake description");
+ grl_media_set_description (media, "fake description");
break;
case GRL_METADATA_KEY_DURATION:
- grl_content_media_set_duration (media, 99);
+ grl_media_set_duration (media, 99);
break;
case GRL_METADATA_KEY_DATE:
- grl_content_set_string (GRL_CONTENT (media),
- GRL_METADATA_KEY_DATE, "01/01/1970");
+ grl_data_set_string (GRL_DATA (media),
+ GRL_METADATA_KEY_DATE, "01/01/1970");
break;
case GRL_METADATA_KEY_THUMBNAIL:
- grl_content_media_set_thumbnail (media,
- "http://fake.thumbnail.com/fake-image.jpg");
+ grl_media_set_thumbnail (media,
+ "http://fake.thumbnail.com/fake-image.jpg");
break;
default:
break;
@@ -200,6 +209,19 @@ grl_fake_metadata_source_key_depends (GrlMetadataSource *source,
return NULL;
}
+static const GList *
+grl_fake_metadata_source_writable_keys (GrlMetadataSource *source)
+{
+ static GList *keys = NULL;
+ if (!keys) {
+ keys = grl_metadata_key_list_new (GRL_METADATA_KEY_ALBUM,
+ GRL_METADATA_KEY_ARTIST,
+ GRL_METADATA_KEY_GENRE,
+ NULL);
+ }
+ return keys;
+}
+
static void
grl_fake_metadata_source_resolve (GrlMetadataSource *source,
GrlMetadataSourceResolveSpec *rs)
@@ -211,9 +233,18 @@ grl_fake_metadata_source_resolve (GrlMetadataSource *source,
iter = rs->keys;
while (iter) {
GrlKeyID key_id = POINTER_TO_GRLKEYID (iter->data);
- fill_metadata (GRL_CONTENT_MEDIA (rs->media), key_id);
+ fill_metadata (GRL_MEDIA (rs->media), key_id);
iter = g_list_next (iter);
}
rs->callback (source, rs->media, rs->user_data, NULL);
}
+
+static void
+grl_fake_metadata_source_set_metadata (GrlMetadataSource *source,
+ GrlMetadataSourceSetMetadataSpec *sms)
+{
+ g_debug ("grl_fake_metadata_source_set_metadata");
+ g_debug (" Faking set metadata for %d keys!", g_list_length (sms->keys));
+ sms->callback (sms->source, sms->media, NULL, sms->user_data, NULL);
+}
diff --git a/src/filesystem/grl-filesystem.c b/src/filesystem/grl-filesystem.c
index db3bc6a..7ad140d 100644
--- a/src/filesystem/grl-filesystem.c
+++ b/src/filesystem/grl-filesystem.c
@@ -79,7 +79,8 @@ typedef struct {
static GrlFilesystemSource *grl_filesystem_source_new (void);
gboolean grl_filesystem_plugin_init (GrlPluginRegistry *registry,
- const GrlPluginInfo *plugin);
+ const GrlPluginInfo *plugin,
+ GList *configs);
static const GList *grl_filesystem_source_supported_keys (GrlMetadataSource *source);
@@ -94,7 +95,8 @@ static void grl_filesystem_source_browse (GrlMediaSource *source,
gboolean
grl_filesystem_plugin_init (GrlPluginRegistry *registry,
- const GrlPluginInfo *plugin)
+ const GrlPluginInfo *plugin,
+ GList *configs)
{
g_debug ("filesystem_plugin_init\n");
@@ -234,7 +236,7 @@ file_is_valid_content (const gchar *path, gboolean fast)
static void
set_container_childcount (const gchar *path,
- GrlContentMedia *media,
+ GrlMedia *media,
gboolean fast)
{
GDir *dir;
@@ -276,15 +278,15 @@ set_container_childcount (const gchar *path,
g_dir_close (dir);
- grl_content_box_set_childcount (GRL_CONTENT_BOX (media), count);
+ grl_media_box_set_childcount (GRL_MEDIA_BOX (media), count);
}
-static GrlContentMedia *
-create_content (GrlContentMedia *content,
+static GrlMedia *
+create_content (GrlMedia *content,
const gchar *path,
gboolean only_fast)
{
- GrlContentMedia *media = NULL;
+ GrlMedia *media = NULL;
gchar *str;
const gchar *mime;
GError *error = NULL;
@@ -304,7 +306,7 @@ create_content (GrlContentMedia *content,
if (error) {
g_warning ("Failed to get info for file '%s': %s", path, error->message);
if (!media) {
- media = grl_content_media_new ();
+ media = grl_media_new ();
}
/* Title */
@@ -312,56 +314,56 @@ create_content (GrlContentMedia *content,
if (!str) {
str = (gchar *) path;
}
- grl_content_media_set_title (media, str);
+ grl_media_set_title (media, str);
g_error_free (error);
} else {
mime = g_file_info_get_content_type (info);
if (!media) {
if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY) {
- media = GRL_CONTENT_MEDIA (grl_content_box_new ());
+ media = GRL_MEDIA (grl_media_box_new ());
} else {
if (mime_is_video (mime)) {
- media = grl_content_video_new ();
+ media = grl_media_video_new ();
} else if (mime_is_audio (mime)) {
- media = grl_content_audio_new ();
+ media = grl_media_audio_new ();
} else if (mime_is_image (mime)) {
- media = grl_content_image_new ();
+ media = grl_media_image_new ();
} else {
- media = grl_content_media_new ();
+ media = grl_media_new ();
}
}
}
- if (!GRL_IS_CONTENT_BOX (media)) {
- grl_content_media_set_mime (GRL_CONTENT (media), mime);
+ if (!GRL_IS_MEDIA_BOX (media)) {
+ grl_media_set_mime (GRL_DATA (media), mime);
}
/* Title */
str = (gchar *) g_file_info_get_display_name (info);
- grl_content_media_set_title (media, str);
+ grl_media_set_title (media, str);
/* Date */
GTimeVal time;
gchar *time_str;
g_file_info_get_modification_time (info, &time);
time_str = g_time_val_to_iso8601 (&time);
- grl_content_media_set_date (GRL_CONTENT (media), time_str);
+ grl_media_set_date (GRL_DATA (media), time_str);
g_free (time_str);
g_object_unref (info);
}
/* ID */
- grl_content_media_set_id (media, path);
+ grl_media_set_id (media, path);
/* URL */
str = g_strconcat ("file://", path, NULL);
- grl_content_media_set_url (media, str);
+ grl_media_set_url (media, str);
g_free (str);
/* Childcount */
- if (GRL_IS_CONTENT_BOX (media)) {
+ if (GRL_IS_MEDIA_BOX (media)) {
set_container_childcount (path, media, only_fast);
}
@@ -383,7 +385,7 @@ browse_emit_idle (gpointer user_data)
count = 0;
do {
gchar *entry_path;
- GrlContentMedia *content;
+ GrlMedia *content;
entry_path = (gchar *) idle_data->current->data;
content = create_content (NULL,
@@ -520,7 +522,7 @@ grl_filesystem_source_browse (GrlMediaSource *source,
g_debug ("grl_filesystem_source_browse");
- id = grl_content_media_get_id (bs->container);
+ id = grl_media_get_id (bs->container);
path = id ? id : G_DIR_SEPARATOR_S;
produce_from_path (bs, path);
}
@@ -534,7 +536,7 @@ grl_filesystem_source_metadata (GrlMediaSource *source,
g_debug ("grl_filesystem_source_metadata");
- id = grl_content_media_get_id (ms->media);
+ id = grl_media_get_id (ms->media);
path = id ? id : G_DIR_SEPARATOR_S;
if (g_file_test (path, G_FILE_TEST_EXISTS)) {
diff --git a/src/flickr/grl-flickr.c b/src/flickr/grl-flickr.c
index 4c52b16..11ac1e3 100644
--- a/src/flickr/grl-flickr.c
+++ b/src/flickr/grl-flickr.c
@@ -43,13 +43,6 @@
#undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "grl-flickr"
-/* ----- Security tokens ---- */
-
-#define FLICKR_KEY "fa037bee8120a921b34f8209d715a2fa"
-#define FLICKR_SECRET "9f6523b9c52e3317"
-#define FLICKR_FROB "416-357-743"
-#define FLICKR_TOKEN "72157623286932154-c90318d470e96a29"
-
/* --- Plugin information --- */
#define PLUGIN_ID "grl-flickr"
@@ -77,7 +70,8 @@ struct _GrlFlickrSourcePrivate {
static GrlFlickrSource *grl_flickr_source_new (void);
gboolean grl_flickr_plugin_init (GrlPluginRegistry *registry,
- const GrlPluginInfo *plugin);
+ const GrlPluginInfo *plugin,
+ GList *configs);
static const GList *grl_flickr_source_supported_keys (GrlMetadataSource *source);
@@ -91,19 +85,45 @@ static void grl_flickr_source_search (GrlMediaSource *source,
gboolean
grl_flickr_plugin_init (GrlPluginRegistry *registry,
- const GrlPluginInfo *plugin)
+ const GrlPluginInfo *plugin,
+ GList *configs)
{
+ const gchar *flickr_key;
+ const gchar *flickr_secret;
+ const gchar *flickr_token;
+ const GrlConfig *config;
+ gint config_count;
+
g_debug ("flickr_plugin_init\n");
- GrlFlickrSource *source = grl_flickr_source_new ();
- if (source) {
- grl_plugin_registry_register_source (registry,
- plugin,
- GRL_MEDIA_PLUGIN (source));
- return TRUE;
- } else {
+ if (!configs) {
+ g_warning ("Missing configuration");
return FALSE;
}
+
+ config_count = g_list_length (configs);
+ if (config_count > 1) {
+ g_warning ("Provided %d configs, but will only use one", config_count);
+ }
+
+ config = GRL_CONFIG (configs->data);
+
+ flickr_key = grl_config_get_api_key (config);
+ flickr_token = grl_config_get_api_token (config);
+ flickr_secret = grl_config_get_api_secret (config);
+
+ if (!flickr_key || ! flickr_token || !flickr_secret) {
+ g_warning ("Required configuration keys not set up");
+ return FALSE;
+ }
+
+ GrlFlickrSource *source = grl_flickr_source_new ();
+ source->priv->flickr = g_flickr_new (flickr_key, flickr_token, flickr_secret);
+
+ grl_plugin_registry_register_source (registry,
+ plugin,
+ GRL_MEDIA_PLUGIN (source));
+ return TRUE;
}
GRL_PLUGIN_REGISTER (grl_flickr_plugin_init,
@@ -147,7 +167,6 @@ static void
grl_flickr_source_init (GrlFlickrSource *source)
{
source->priv = GRL_FLICKR_SOURCE_GET_PRIVATE (source);
- source->priv->flickr = g_flickr_new (FLICKR_KEY, FLICKR_TOKEN, FLICKR_SECRET);
}
G_DEFINE_TYPE (GrlFlickrSource, grl_flickr_source, GRL_TYPE_MEDIA_SOURCE);
@@ -155,7 +174,7 @@ G_DEFINE_TYPE (GrlFlickrSource, grl_flickr_source, GRL_TYPE_MEDIA_SOURCE);
/* ======================= Utilities ==================== */
static void
-update_media (GrlContentMedia *media, GHashTable *photo)
+update_media (GrlMedia *media, GHashTable *photo)
{
gchar *author;
gchar *date;
@@ -189,32 +208,32 @@ update_media (GrlContentMedia *media, GHashTable *photo)
}
if (author) {
- grl_content_media_set_author (media, author);
+ grl_media_set_author (media, author);
}
if (date) {
- grl_content_media_set_date (media, date);
+ grl_media_set_date (media, date);
}
if (description) {
- grl_content_media_set_description (media, description);
+ grl_media_set_description (media, description);
}
if (id) {
- grl_content_media_set_id (media, id);
+ grl_media_set_id (media, id);
}
if (thumbnail) {
- grl_content_media_set_thumbnail (media, thumbnail);
+ grl_media_set_thumbnail (media, thumbnail);
g_free (thumbnail);
}
if (title) {
- grl_content_media_set_title (media, title);
+ grl_media_set_title (media, title);
}
if (url) {
- grl_content_media_set_url (media, url);
+ grl_media_set_url (media, url);
g_free (url);
}
}
@@ -234,7 +253,7 @@ getInfo_cb (GFlickr *f, GHashTable *photo, gpointer user_data)
static void
search_cb (GFlickr *f, GList *photolist, gpointer user_data)
{
- GrlContentMedia *media;
+ GrlMedia *media;
SearchData *sd = (SearchData *) user_data;
gchar *media_type;
@@ -256,9 +275,9 @@ search_cb (GFlickr *f, GList *photolist, gpointer user_data)
while (photolist && sd->ss->count) {
media_type = g_hash_table_lookup (photolist->data, "photo_media");
if (strcmp (media_type, "photo") == 0) {
- media = grl_content_image_new ();
+ media = grl_media_image_new ();
} else {
- media = grl_content_video_new ();
+ media = grl_media_video_new ();
}
update_media (media, photolist->data);
sd->ss->callback (sd->ss->source,
@@ -306,7 +325,7 @@ grl_flickr_source_metadata (GrlMediaSource *source,
{
const gchar *id;
- if (!ms->media || (id = grl_content_media_get_id (ms->media)) == NULL) {
+ if (!ms->media || (id = grl_media_get_id (ms->media)) == NULL) {
ms->callback (ms->source, ms->media, ms->user_data, NULL);
return;
}
diff --git a/src/jamendo/grl-jamendo.c b/src/jamendo/grl-jamendo.c
index 5137c3c..fef13c5 100644
--- a/src/jamendo/grl-jamendo.c
+++ b/src/jamendo/grl-jamendo.c
@@ -141,7 +141,8 @@ typedef struct {
static GrlJamendoSource *grl_jamendo_source_new (void);
gboolean grl_jamendo_plugin_init (GrlPluginRegistry *registry,
- const GrlPluginInfo *plugin);
+ const GrlPluginInfo *plugin,
+ GList *configs);
static const GList *grl_jamendo_source_supported_keys (GrlMetadataSource *source);
@@ -164,7 +165,8 @@ static void grl_jamendo_source_cancel (GrlMediaSource *source,
gboolean
grl_jamendo_plugin_init (GrlPluginRegistry *registry,
- const GrlPluginInfo *plugin)
+ const GrlPluginInfo *plugin,
+ GList *configs)
{
g_debug ("jamendo_plugin_init\n");
@@ -409,7 +411,7 @@ xml_parse_entry (xmlDocPtr doc, xmlNodePtr entry)
}
static void
-update_media_from_entry (GrlContentMedia *media, const Entry *entry)
+update_media_from_entry (GrlMedia *media, const Entry *entry)
{
gchar *id;
@@ -420,90 +422,90 @@ update_media_from_entry (GrlContentMedia *media, const Entry *entry)
}
/* Common fields */
- grl_content_media_set_id (media, id);
+ grl_media_set_id (media, id);
g_free (id);
if (entry->artist_name) {
- grl_content_set_string (GRL_CONTENT (media),
- GRL_METADATA_KEY_ARTIST,
- entry->artist_name);
+ grl_data_set_string (GRL_DATA (media),
+ GRL_METADATA_KEY_ARTIST,
+ entry->artist_name);
}
if (entry->album_name) {
- grl_content_set_string (GRL_CONTENT (media),
- GRL_METADATA_KEY_ALBUM,
- entry->album_name);
+ grl_data_set_string (GRL_DATA (media),
+ GRL_METADATA_KEY_ALBUM,
+ entry->album_name);
}
/* Fields for artist */
if (entry->category == JAMENDO_ARTIST_CAT) {
if (entry->artist_name) {
- grl_content_media_set_title (media, entry->artist_name);
+ grl_media_set_title (media, entry->artist_name);
}
if (entry->artist_genre) {
- grl_content_set_string (GRL_CONTENT (media),
- GRL_METADATA_KEY_GENRE,
- entry->artist_genre);
+ grl_data_set_string (GRL_DATA (media),
+ GRL_METADATA_KEY_GENRE,
+ entry->artist_genre);
}
if (entry->artist_url) {
- grl_content_media_set_site (media, entry->artist_url);
+ grl_media_set_site (media, entry->artist_url);
}
if (entry->artist_image) {
- grl_content_media_set_thumbnail (media, entry->artist_image);
+ grl_media_set_thumbnail (media, entry->artist_image);
}
/* Fields for album */
} else if (entry->category == JAMENDO_ALBUM_CAT) {
if (entry->album_name) {
- grl_content_media_set_title (media, entry->album_name);
+ grl_media_set_title (media, entry->album_name);
}
if (entry->album_genre) {
- grl_content_set_string (GRL_CONTENT (media),
- GRL_METADATA_KEY_GENRE,
- entry->album_genre);
+ grl_data_set_string (GRL_DATA (media),
+ GRL_METADATA_KEY_GENRE,
+ entry->album_genre);
}
if (entry->album_url) {
- grl_content_media_set_site (media, entry->album_url);
+ grl_media_set_site (media, entry->album_url);
}
if (entry->album_image) {
- grl_content_media_set_thumbnail (media, entry->album_image);
+ grl_media_set_thumbnail (media, entry->album_image);
}
if (entry->album_duration) {
- grl_content_media_set_duration (media, atoi (entry->album_duration));
+ grl_media_set_duration (media, atoi (entry->album_duration));
}
/* Fields for track */
} else if (entry->category == JAMENDO_TRACK_CAT) {
if (entry->track_name) {
- grl_content_media_set_title (media, entry->track_name);
+ grl_media_set_title (media, entry->track_name);
}
if (entry->album_genre) {
- grl_content_audio_set_genre (GRL_CONTENT_AUDIO (media),
- entry->album_genre);
+ grl_media_audio_set_genre (GRL_MEDIA_AUDIO (media),
+ entry->album_genre);
}
if (entry->track_url) {
- grl_content_media_set_site (media, entry->track_url);
+ grl_media_set_site (media, entry->track_url);
}
if (entry->album_image) {
- grl_content_media_set_thumbnail (media, entry->album_image);
+ grl_media_set_thumbnail (media, entry->album_image);
}
if (entry->track_stream) {
- grl_content_media_set_url (media, entry->track_stream);
+ grl_media_set_url (media, entry->track_stream);
}
if (entry->track_duration) {
- grl_content_media_set_duration (media, atoi (entry->track_duration));
+ grl_media_set_duration (media, atoi (entry->track_duration));
}
}
}
@@ -513,7 +515,7 @@ xml_parse_entries_idle (gpointer user_data)
{
XmlParseEntries *xpe = (XmlParseEntries *) user_data;
gboolean parse_more;
- GrlContentMedia *media;
+ GrlMedia *media;
Entry *entry;
g_debug ("xml_parse_entries_idle");
@@ -523,9 +525,9 @@ xml_parse_entries_idle (gpointer user_data)
if (parse_more) {
entry = xml_parse_entry (xpe->doc, xpe->node);
if (entry->category == JAMENDO_TRACK_CAT) {
- media = grl_content_audio_new ();
+ media = grl_media_audio_new ();
} else {
- media = grl_content_box_new ();
+ media = grl_media_box_new ();
}
update_media_from_entry (media, entry);
@@ -642,7 +644,7 @@ read_done_cb (GObject *source_object,
error = g_error_new (GRL_ERROR,
GRL_ERROR_METADATA_FAILED,
"Unable to get information: '%s'",
- grl_content_media_get_id (xpe->spec.ms->media));
+ grl_media_get_id (xpe->spec.ms->media));
}
goto invoke_cb;
}
@@ -703,14 +705,14 @@ read_url_async (const gchar *url, gpointer user_data)
}
static void
-update_media_from_root (GrlContentMedia *media)
+update_media_from_root (GrlMedia *media)
{
- grl_content_media_set_title (media, JAMENDO_ROOT_NAME);
- grl_content_box_set_childcount (GRL_CONTENT_BOX (media), 2);
+ grl_media_set_title (media, JAMENDO_ROOT_NAME);
+ grl_media_box_set_childcount (GRL_MEDIA_BOX (media), 2);
}
static void
-update_media_from_artists (GrlContentMedia *media)
+update_media_from_artists (GrlMedia *media)
{
Entry *entry;
@@ -722,7 +724,7 @@ update_media_from_artists (GrlContentMedia *media)
}
static void
-update_media_from_albums (GrlContentMedia *media)
+update_media_from_albums (GrlMedia *media)
{
Entry *entry;
@@ -736,13 +738,13 @@ update_media_from_albums (GrlContentMedia *media)
static void
send_toplevel_categories (GrlMediaSourceBrowseSpec *bs)
{
- GrlContentMedia *media;
+ GrlMedia *media;
- media = grl_content_box_new ();
+ media = grl_media_box_new ();
update_media_from_artists (media);
bs->callback (bs->source, bs->browse_id, media, 1, bs->user_data, NULL);
- media = grl_content_box_new ();
+ media = grl_media_box_new ();
update_media_from_albums (media);
bs->callback (bs->source, bs->browse_id, media, 0, bs->user_data, NULL);
}
@@ -831,15 +833,15 @@ grl_jamendo_source_metadata (GrlMediaSource *source,
g_debug ("grl_jamendo_source_metadata");
if (!ms->media ||
- !grl_content_key_is_known (GRL_CONTENT (ms->media),
- GRL_METADATA_KEY_ID)) {
+ !grl_data_key_is_known (GRL_DATA (ms->media),
+ GRL_METADATA_KEY_ID)) {
/* Get info from root */
if (!ms->media) {
- ms->media = grl_content_box_new ();
+ ms->media = grl_media_box_new ();
}
update_media_from_root (ms->media);
} else {
- id = grl_content_media_get_id (ms->media);
+ id = grl_media_get_id (ms->media);
id_split = g_strsplit (id, JAMENDO_ID_SEP, 0);
if (g_strv_length (id_split) == 0) {
@@ -942,7 +944,7 @@ grl_jamendo_source_browse (GrlMediaSource *source,
g_debug ("grl_jamendo_source_browse");
- container_id = grl_content_media_get_id (bs->container);
+ container_id = grl_media_get_id (bs->container);
if (!container_id) {
/* Root category: return top-level predefined categories */
diff --git a/src/lastfm-albumart/grl-lastfm-albumart.c b/src/lastfm-albumart/grl-lastfm-albumart.c
index 8a2dbc3..40bfa7e 100644
--- a/src/lastfm-albumart/grl-lastfm-albumart.c
+++ b/src/lastfm-albumart/grl-lastfm-albumart.c
@@ -69,14 +69,16 @@ static const GList *grl_lastfm_albumart_source_key_depends (GrlMetadataSource *s
GrlKeyID key_id);
gboolean grl_lastfm_albumart_source_plugin_init (GrlPluginRegistry *registry,
- const GrlPluginInfo *plugin);
+ const GrlPluginInfo *plugin,
+ GList *configs);
/* =================== Last.FM-AlbumArt Plugin =============== */
gboolean
grl_lastfm_albumart_source_plugin_init (GrlPluginRegistry *registry,
- const GrlPluginInfo *plugin)
+ const GrlPluginInfo *plugin,
+ GList *configs)
{
g_debug ("grl_lastfm_albumart_source_plugin_init");
GrlLastfmAlbumartSource *source = grl_lastfm_albumart_source_new ();
@@ -199,9 +201,9 @@ read_done_cb (GObject *source_object,
image = xml_get_image (content);
g_free (content);
if (image) {
- grl_content_set_string (GRL_CONTENT (rs->media),
- GRL_METADATA_KEY_THUMBNAIL,
- image);
+ grl_data_set_string (GRL_DATA (rs->media),
+ GRL_METADATA_KEY_THUMBNAIL,
+ image);
g_free (image);
}
@@ -286,11 +288,11 @@ grl_lastfm_albumart_source_resolve (GrlMetadataSource *source,
g_debug ("No supported key was requested");
rs->callback (source, rs->media, rs->user_data, NULL);
} else {
- artist = grl_content_get_string (GRL_CONTENT (rs->media),
- GRL_METADATA_KEY_ARTIST);
+ artist = grl_data_get_string (GRL_DATA (rs->media),
+ GRL_METADATA_KEY_ARTIST);
- album = grl_content_get_string (GRL_CONTENT (rs->media),
- GRL_METADATA_KEY_ALBUM);
+ album = grl_data_get_string (GRL_DATA (rs->media),
+ GRL_METADATA_KEY_ALBUM);
if (!artist || !album) {
g_debug ("Missing dependencies");
diff --git a/src/metadata-store/Makefile.am b/src/metadata-store/Makefile.am
new file mode 100644
index 0000000..4f6e9d2
--- /dev/null
+++ b/src/metadata-store/Makefile.am
@@ -0,0 +1,26 @@
+#
+# Makefile.am
+#
+# Author: Iago Toral Quiroga <itoral@igalia.com>
+#
+# Copyright (C) 2010 Igalia S.L. All rights reserved.
+
+lib_LTLIBRARIES = libgrlmetadatastore.la
+
+libgrlmetadatastore_la_CFLAGS = \
+ $(DEPS_CFLAGS) \
+ $(SQLITE_CFLAGS)
+
+libgrlmetadatastore_la_LIBADD = \
+ $(DEPS_LIBS) \
+ $(SQLITE_LIBS)
+
+libgrlmetadatastore_la_SOURCES = grl-metadata-store.c grl-metadata-store.h
+
+libdir=$(GRL_PLUGINS_DIR)
+
+MAINTAINERCLEANFILES = \
+ *.in \
+ *~
+
+DISTCLEANFILES = $(MAINTAINERCLEANFILES)
diff --git a/src/metadata-store/grl-metadata-store.c b/src/metadata-store/grl-metadata-store.c
new file mode 100644
index 0000000..0899fbf
--- /dev/null
+++ b/src/metadata-store/grl-metadata-store.c
@@ -0,0 +1,681 @@
+/*
+ * Copyright (C) 2010 Igalia S.L.
+ *
+ * Contact: Iago Toral Quiroga <itoral@igalia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <grilo.h>
+#include <sqlite3.h>
+#include <string.h>
+
+#include "grl-metadata-store.h"
+
+#define GRL_METADATA_STORE_GET_PRIVATE(object) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((object), \
+ GRL_METADATA_STORE_SOURCE_TYPE, \
+ GrlMetadataStorePrivate))
+
+#undef G_LOG_DOMAIN
+#define G_LOG_DOMAIN "grl-metadata-store"
+
+#define PLUGIN_ID "grl-metadata-store"
+#define PLUGIN_NAME "Metadata Store"
+#define PLUGIN_DESC "A plugin for storing extra metadata information"
+
+#define SOURCE_ID "grl-metadata-store"
+#define SOURCE_NAME "Metadata Store"
+#define SOURCE_DESC "A plugin for storing extra metadata information"
+
+#define AUTHOR "Igalia S.L."
+#define LICENSE "LGPL"
+#define SITE "http://www.igalia.com"
+
+#define GRL_SQL_DB ".grl-metadata-store"
+
+#define GRL_SQL_CREATE_TABLE_STORE \
+ "CREATE TABLE IF NOT EXISTS store (" \
+ "source_id TEXT," \
+ "media_id TEXT," \
+ "play_count INTEGER," \
+ "rating REAL," \
+ "last_position INTEGER," \
+ "last_played DATE)"
+
+#define GRL_SQL_GET_METADATA \
+ "SELECT * FROM store " \
+ "WHERE source_id='%s' AND media_id='%s' " \
+ "LIMIT 1"
+
+#define GRL_SQL_UPDATE_METADATA \
+ "UPDATE store SET %s " \
+ "WHERE source_id=? AND media_id=?"
+
+#define GRL_SQL_INSERT_METADATA \
+ "INSERT INTO store " \
+ "(%s source_id, media_id) VALUES " \
+ "(%s ?, ?)"
+
+struct _GrlMetadataStorePrivate {
+ sqlite3 *db;
+};
+
+enum {
+ STORE_SOURCE_ID = 0,
+ STORE_MEDIA_ID,
+ STORE_PLAY_COUNT,
+ STORE_RATING,
+ STORE_LAST_POSITION,
+ STORE_LAST_PLAYED,
+};
+
+static GrlMetadataStoreSource *grl_metadata_store_source_new (void);
+
+static void grl_metadata_store_source_resolve (GrlMetadataSource *source,
+ GrlMetadataSourceResolveSpec *rs);
+
+static void grl_metadata_store_source_set_metadata (GrlMetadataSource *source,
+ GrlMetadataSourceSetMetadataSpec *sms);
+
+static const GList *grl_metadata_store_source_supported_keys (GrlMetadataSource *source);
+
+static const GList *grl_metadata_store_source_key_depends (GrlMetadataSource *source,
+ GrlKeyID key_id);
+static const GList *grl_metadata_store_source_writable_keys (GrlMetadataSource *source);
+
+gboolean grl_metadata_store_source_plugin_init (GrlPluginRegistry *registry,
+ const GrlPluginInfo *plugin,
+ GList *configs);
+
+
+/* =================== GrlMetadataStore Plugin =============== */
+
+gboolean
+grl_metadata_store_source_plugin_init (GrlPluginRegistry *registry,
+ const GrlPluginInfo *plugin,
+ GList *configs)
+{
+ g_debug ("grl_metadata_store_source_plugin_init");
+ GrlMetadataStoreSource *source = grl_metadata_store_source_new ();
+ grl_plugin_registry_register_source (registry,
+ plugin,
+ GRL_MEDIA_PLUGIN (source));
+ return TRUE;
+}
+
+GRL_PLUGIN_REGISTER (grl_metadata_store_source_plugin_init,
+ NULL,
+ PLUGIN_ID,
+ PLUGIN_NAME,
+ PLUGIN_DESC,
+ PACKAGE_VERSION,
+ AUTHOR,
+ LICENSE,
+ SITE);
+
+/* ================== GrlMetadataStore GObject ================ */
+
+static GrlMetadataStoreSource *
+grl_metadata_store_source_new (void)
+{
+ g_debug ("grl_metadata_store_source_new");
+ return g_object_new (GRL_METADATA_STORE_SOURCE_TYPE,
+ "source-id", SOURCE_ID,
+ "source-name", SOURCE_NAME,
+ "source-desc", SOURCE_DESC,
+ NULL);
+}
+
+static void
+grl_metadata_store_source_class_init (GrlMetadataStoreSourceClass * klass)
+{
+ GrlMetadataSourceClass *metadata_class = GRL_METADATA_SOURCE_CLASS (klass);
+ metadata_class->supported_keys = grl_metadata_store_source_supported_keys;
+ metadata_class->key_depends = grl_metadata_store_source_key_depends;
+ metadata_class->writable_keys = grl_metadata_store_source_writable_keys;
+ metadata_class->resolve = grl_metadata_store_source_resolve;
+ metadata_class->set_metadata = grl_metadata_store_source_set_metadata;
+
+ g_type_class_add_private (klass, sizeof (GrlMetadataStorePrivate));
+}
+
+static void
+grl_metadata_store_source_init (GrlMetadataStoreSource *source)
+{
+ gint r;
+ const gchar *home;
+ gchar *db_path;
+ gchar *sql_error = NULL;
+
+ source->priv = GRL_METADATA_STORE_GET_PRIVATE (source);
+ memset (source->priv, 0, sizeof (GrlMetadataStorePrivate));
+
+ home = g_getenv ("HOME");
+ if (!home) {
+ g_warning ("$HOME not set, cannot open database");
+ return;
+ }
+
+ g_debug ("Opening database connection...");
+ db_path = g_strconcat (home, G_DIR_SEPARATOR_S, GRL_SQL_DB, NULL);
+ r = sqlite3_open (db_path, &source->priv->db);
+ if (r) {
+ g_critical ("Failed to open database '%s': %s",
+ db_path, sqlite3_errmsg (source->priv->db));
+ sqlite3_close (source->priv->db);
+ return;
+ }
+ g_debug (" OK");
+
+ g_debug ("Checking database tables...");
+ r = sqlite3_exec (source->priv->db, GRL_SQL_CREATE_TABLE_STORE,
+ NULL, NULL, &sql_error);
+
+ if (r) {
+ if (sql_error) {
+ g_warning ("Failed to create database tables: %s", sql_error);
+ sqlite3_free (sql_error);
+ sql_error = NULL;
+ } else {
+ g_warning ("Failed to create database tables.");
+ }
+ sqlite3_close (source->priv->db);
+ return;
+ }
+ g_debug (" OK");
+
+ g_free (db_path);
+}
+
+G_DEFINE_TYPE (GrlMetadataStoreSource, grl_metadata_store_source,
+ GRL_TYPE_METADATA_SOURCE);
+
+/* ======================= Utilities ==================== */
+
+static sqlite3_stmt *
+query_metadata_store (sqlite3 *db,
+ const gchar *source_id,
+ const gchar *media_id)
+{
+ gint r;
+ sqlite3_stmt *sql_stmt = NULL;
+ gchar *sql;
+
+ g_debug ("get_metadata");
+
+ sql = g_strdup_printf (GRL_SQL_GET_METADATA, source_id, media_id);
+ g_debug ("%s", sql);
+ r = sqlite3_prepare_v2 (db, sql, strlen (sql), &sql_stmt, NULL);
+ g_free (sql);
+
+ if (r != SQLITE_OK) {
+ g_warning ("Failed to get metadata: %s", sqlite3_errmsg (db));
+ return NULL;
+ }
+
+ return sql_stmt;
+}
+
+static void
+fill_metadata (GrlMedia *media, GList *keys, sqlite3_stmt *stmt)
+{
+ GList *iter;
+ gint play_count, last_position;
+ gdouble rating;
+ gchar *last_played, *rating_str;
+ gint r;
+
+ while ((r = sqlite3_step (stmt)) == SQLITE_BUSY);
+
+ if (r != SQLITE_ROW) {
+ /* No info in DB for this item, bail out silently */
+ sqlite3_finalize (stmt);
+ return;
+ }
+
+ iter = keys;
+ while (iter) {
+ GrlKeyID key_id = POINTER_TO_GRLKEYID (iter->data);
+ switch (key_id) {
+ case GRL_METADATA_KEY_PLAY_COUNT:
+ play_count = sqlite3_column_int (stmt, STORE_PLAY_COUNT);
+ grl_media_set_play_count (media, play_count);
+ break;
+ case GRL_METADATA_KEY_RATING:
+ rating = sqlite3_column_double (stmt, STORE_RATING);
+ rating_str = g_strdup_printf ("%.2f", rating);
+ grl_media_set_rating (media, rating_str, "5");
+ g_free (rating_str);
+ break;
+ case GRL_METADATA_KEY_LAST_PLAYED:
+ last_played = (gchar *) sqlite3_column_text (stmt, STORE_LAST_PLAYED);
+ grl_media_set_last_played (media, last_played);
+ break;
+ case GRL_METADATA_KEY_LAST_POSITION:
+ last_position = sqlite3_column_int (stmt, STORE_LAST_POSITION);
+ grl_media_set_last_position (media, last_position);
+ break;
+ default:
+ break;
+ }
+ iter = g_list_next (iter);
+ }
+
+ sqlite3_finalize (stmt);
+}
+
+static const gchar *
+get_column_name_from_key_id (GrlKeyID key_id)
+{
+ static const gchar *col_names[] = {"rating", "last_played", "last_position",
+ "play_count"};
+ switch (key_id) {
+ case GRL_METADATA_KEY_RATING:
+ return col_names[0];
+ case GRL_METADATA_KEY_LAST_PLAYED:
+ return col_names[1];
+ case GRL_METADATA_KEY_LAST_POSITION:
+ return col_names[2];
+ case GRL_METADATA_KEY_PLAY_COUNT:
+ return col_names[3];
+ default:
+ return NULL;
+ }
+}
+
+static gboolean
+bind_and_exec (sqlite3 *db,
+ const gchar *sql,
+ const gchar *source_id,
+ const gchar *media_id,
+ GList *col_names,
+ GList *keys,
+ GrlMedia *media)
+{
+ gint r;
+ const gchar *char_value;
+ gint int_value;
+ double double_value;
+ GList *iter_names, *iter_keys;
+ guint count;
+ sqlite3_stmt *stmt;
+
+ /* Create statement from sql */
+ g_debug ("%s", sql);
+ r = sqlite3_prepare_v2 (db, sql, strlen (sql), &stmt, NULL);
+
+ if (r != SQLITE_OK) {
+ g_warning ("Failed to update metadata for '%s - %s': %s",
+ source_id, media_id, sqlite3_errmsg (db));
+ sqlite3_finalize (stmt);
+ return FALSE;
+ }
+
+ /* Bind column values */
+ count = 1;
+ iter_names = col_names;
+ iter_keys = keys;
+ while (iter_names) {
+ if (iter_names->data) {
+ GrlKeyID key_id = POINTER_TO_GRLKEYID (iter_keys->data);
+ switch (key_id) {
+ case GRL_METADATA_KEY_RATING:
+ char_value = grl_media_get_rating (media);
+ if (char_value) {
+ double_value = g_ascii_strtod (char_value, NULL);
+ } else {
+ double_value = 0;
+ }
+ sqlite3_bind_double (stmt, count, double_value);
+ break;
+ case GRL_METADATA_KEY_PLAY_COUNT:
+ int_value = grl_media_get_play_count (media);
+ sqlite3_bind_int (stmt, count, int_value);
+ break;
+ case GRL_METADATA_KEY_LAST_POSITION:
+ int_value = grl_media_get_last_position (media);
+ sqlite3_bind_int (stmt, count, int_value);
+ break;
+ case GRL_METADATA_KEY_LAST_PLAYED:
+ char_value = grl_media_get_last_played (media);
+ sqlite3_bind_text (stmt, count, char_value, -1, SQLITE_STATIC);
+ break;
+ default:
+ break;
+ }
+ count++;
+ }
+ iter_keys = g_list_next (iter_keys);
+ iter_names = g_list_next (iter_names);
+ }
+
+ sqlite3_bind_text (stmt, count++, source_id, -1, SQLITE_STATIC);
+ sqlite3_bind_text (stmt, count++, media_id, -1, SQLITE_STATIC);
+
+ /* execute query */
+ while ((r = sqlite3_step (stmt)) == SQLITE_BUSY);
+
+ sqlite3_finalize (stmt);
+
+ return (r == SQLITE_DONE);
+}
+
+static gboolean
+prepare_and_exec_update (sqlite3 *db,
+ const gchar *source_id,
+ const gchar *media_id,
+ GList *col_names,
+ GList *keys,
+ GrlMedia *media)
+{
+ gchar *sql;
+ gint r;
+ GList *iter_names;
+ GString *sql_buf;
+ gchar *sql_set;
+ guint count;
+
+ g_debug ("prepare_and_exec_update");
+
+ /* Prepare sql "set" for update query */
+ count = 0;
+ sql_buf = g_string_new ("");
+ iter_names = col_names;
+ while (iter_names) {
+ gchar *col_name = (gchar *) iter_names->data;
+ if (col_name) {
+ if (count > 0) {
+ g_string_append (sql_buf, " AND ");
+ }
+ g_string_append_printf (sql_buf, "%s=?", col_name);
+ count++;
+ }
+ iter_names = g_list_next (iter_names);
+ }
+ sql_set = g_string_free (sql_buf, FALSE);
+
+ /* Execute query */
+ sql = g_strdup_printf (GRL_SQL_UPDATE_METADATA, sql_set);
+ r = bind_and_exec (db, sql, source_id, media_id, col_names, keys, media);
+ g_free (sql);
+ g_free (sql_set);
+
+ return r;
+}
+
+static gboolean
+prepare_and_exec_insert (sqlite3 *db,
+ const gchar *source_id,
+ const gchar *media_id,
+ GList *col_names,
+ GList *keys,
+ GrlMedia *media)
+{
+ gchar *sql;
+ gint r;
+ GList *iter_names;
+ GString *sql_buf_cols, *sql_buf_values;
+ gchar *sql_cols, *sql_values;
+
+ g_debug ("prepare_and_exec_insert");
+
+ /* Prepare sql for insert query */
+ sql_buf_cols = g_string_new ("");
+ sql_buf_values = g_string_new ("");
+ iter_names = col_names;
+ while (iter_names) {
+ gchar *col_name = (gchar *) iter_names->data;
+ if (col_name) {
+ g_string_append_printf (sql_buf_cols, "%s, ", col_name);
+ g_string_append (sql_buf_values, "?, ");
+ }
+ iter_names = g_list_next (iter_names);
+ }
+ sql_cols = g_string_free (sql_buf_cols, FALSE);
+ sql_values = g_string_free (sql_buf_values, FALSE);
+
+ /* Execute query */
+ sql = g_strdup_printf (GRL_SQL_INSERT_METADATA, sql_cols, sql_values);
+ r = bind_and_exec (db, sql, source_id, media_id, col_names, keys, media);
+ g_free (sql);
+ g_free (sql_cols);
+ g_free (sql_values);
+
+ return r;
+}
+
+static GList *
+write_keys (sqlite3 *db,
+ const gchar *source_id,
+ const gchar *media_id,
+ GrlMetadataSourceSetMetadataSpec *sms,
+ GError **error)
+{
+ GList *col_names = NULL;
+ GList *iter;
+ GList *failed_keys = NULL;
+ guint supported_keys = 0;
+ gint r;
+
+ /* Get DB column names for each key to be updated */
+ iter = sms->keys;
+ while (iter) {
+ GrlKeyID key_id = POINTER_TO_GRLKEYID (iter->data);
+ const gchar *col_name = get_column_name_from_key_id (key_id);
+ if (!col_name) {
+ g_warning ("Key %u is not supported for writing, ignoring...", key_id);
+ failed_keys = g_list_prepend (failed_keys, GRLKEYID_TO_POINTER (key_id));
+ } else {
+ supported_keys++;
+ }
+ col_names = g_list_prepend (col_names, (gchar *) col_name);
+ iter = g_list_next (iter);
+ }
+ col_names = g_list_reverse (col_names);
+
+ if (supported_keys == 0) {
+ g_warning ("Failed to update metadata, none of the specified "
+ "keys is writable");
+ *error = g_error_new (GRL_ERROR,
+ GRL_ERROR_SET_METADATA_FAILED,
+ "Failed to update metadata, "
+ "specified keys are not writable");
+ goto done;
+ }
+
+ r = prepare_and_exec_update (db,
+ source_id,
+ media_id,
+ col_names,
+ sms->keys,
+ sms->media);
+
+ if (!r) {
+ g_warning ("Failed to update metadata for '%s - %s': %s",
+ source_id, media_id, sqlite3_errmsg (db));
+ g_list_free (failed_keys);
+ failed_keys = g_list_copy (sms->keys);
+ *error = g_error_new (GRL_ERROR,
+ GRL_ERROR_SET_METADATA_FAILED,
+ "Failed to update metadata");
+ goto done;
+ }
+
+ if (sqlite3_changes (db) == 0) {
+ /* We have to create the row */
+ r = prepare_and_exec_insert (db,
+ source_id,
+ media_id,
+ col_names,
+ sms->keys,
+ sms->media);
+ }
+
+ if (!r) {
+ g_warning ("Failed to update metadata for '%s - %s': %s",
+ source_id, media_id, sqlite3_errmsg (db));
+ g_list_free (failed_keys);
+ failed_keys = g_list_copy (sms->keys);
+ *error = g_error_new (GRL_ERROR,
+ GRL_ERROR_SET_METADATA_FAILED,
+ "Failed to update metadata");
+ goto done;
+ }
+
+ done:
+ g_list_free (col_names);
+ return failed_keys;
+}
+
+/* ================== API Implementation ================ */
+
+static const GList *
+grl_metadata_store_source_supported_keys (GrlMetadataSource *source)
+{
+ static GList *keys = NULL;
+ if (!keys) {
+ keys = grl_metadata_key_list_new (GRL_METADATA_KEY_RATING,
+ GRL_METADATA_KEY_PLAY_COUNT,
+ GRL_METADATA_KEY_LAST_PLAYED,
+ GRL_METADATA_KEY_LAST_POSITION,
+ NULL);
+ }
+ return keys;
+}
+
+static const GList *
+grl_metadata_store_source_writable_keys (GrlMetadataSource *source)
+{
+ static GList *keys = NULL;
+ if (!keys) {
+ keys = grl_metadata_key_list_new (GRL_METADATA_KEY_RATING,
+ GRL_METADATA_KEY_PLAY_COUNT,
+ GRL_METADATA_KEY_LAST_PLAYED,
+ GRL_METADATA_KEY_LAST_POSITION,
+ NULL);
+ }
+ return keys;
+}
+
+static const GList *
+grl_metadata_store_source_key_depends (GrlMetadataSource *source,
+ GrlKeyID key_id)
+{
+ static GList *deps = NULL;
+ if (!deps) {
+ deps = grl_metadata_key_list_new (GRL_METADATA_KEY_ID, NULL);
+ }
+
+ switch (key_id) {
+ case GRL_METADATA_KEY_RATING:
+ case GRL_METADATA_KEY_PLAY_COUNT:
+ case GRL_METADATA_KEY_LAST_PLAYED:
+ case GRL_METADATA_KEY_LAST_POSITION:
+ return deps;
+ default:
+ break;
+ }
+
+ return NULL;
+}
+
+static void
+grl_metadata_store_source_resolve (GrlMetadataSource *source,
+ GrlMetadataSourceResolveSpec *rs)
+{
+ g_debug ("grl_metadata_store_source_resolve");
+
+ const gchar *source_id, *media_id;
+ sqlite3_stmt *stmt;
+ GError *error = NULL;
+
+ source_id = grl_media_get_source (rs->media);
+ media_id = grl_media_get_id (rs->media);
+
+ /* We need the source id */
+ if (!source_id) {
+ g_warning ("Failed to resolve metadata: source-id not available");
+ error = g_error_new (GRL_ERROR,
+ GRL_ERROR_RESOLVE_FAILED,
+ "source-id not available, cannot resolve metadata.");
+ rs->callback (rs->source, rs->media, rs->user_data, error);
+ g_error_free (error);
+ return;
+ }
+
+ /* Special case for root categories */
+ if (!media_id) {
+ media_id = "";
+ }
+
+ stmt = query_metadata_store (GRL_METADATA_STORE_SOURCE (source)->priv->db,
+ source_id, media_id);
+ if (stmt) {
+ fill_metadata (rs->media, rs->keys, stmt);
+ rs->callback (rs->source, rs->media, rs->user_data, NULL);
+ } else {
+ g_warning ("Failed to resolve metadata");
+ error = g_error_new (GRL_ERROR,
+ GRL_ERROR_RESOLVE_FAILED,
+ "Failed to resolve metadata.");
+ rs->callback (rs->source, rs->media, rs->user_data, error);
+ g_error_free (error);
+ }
+}
+
+static void
+grl_metadata_store_source_set_metadata (GrlMetadataSource *source,
+ GrlMetadataSourceSetMetadataSpec *sms)
+{
+ g_debug ("grl_metadata_store_source_set_metadata");
+
+ const gchar *media_id, *source_id;
+ GError *error = NULL;
+ GList *failed_keys = NULL;
+
+ source_id = grl_media_get_source (sms->media);
+ media_id = grl_media_get_id (sms->media);
+
+ /* We need the source id */
+ if (!source_id) {
+ g_warning ("Failed to update metadata: source-id not available");
+ error = g_error_new (GRL_ERROR,
+ GRL_ERROR_SET_METADATA_FAILED,
+ "source-id not available, cannot update metadata.");
+ failed_keys = g_list_copy (sms->keys);
+ } else {
+ /* Special case for root categories */
+ if (!media_id) {
+ media_id = "";
+ }
+
+ failed_keys = write_keys (GRL_METADATA_STORE_SOURCE (source)->priv->db,
+ source_id, media_id, sms, &error);
+ }
+
+ sms->callback (sms->source, sms->media, failed_keys, sms->user_data, error);
+
+ if (error) {
+ g_error_free (error);
+ }
+ g_list_free (failed_keys);
+}
diff --git a/src/metadata-store/grl-metadata-store.h b/src/metadata-store/grl-metadata-store.h
new file mode 100644
index 0000000..47df494
--- /dev/null
+++ b/src/metadata-store/grl-metadata-store.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2010 Igalia S.L.
+ *
+ * Contact: Iago Toral Quiroga <itoral@igalia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef _GRL_METADATA_STORE_SOURCE_H_
+#define _GRL_METADATA_STORE_SOURCE_H_
+
+#include <grilo.h>
+
+#define GRL_METADATA_STORE_SOURCE_TYPE \
+ (grl_metadata_store_source_get_type ())
+
+#define GRL_METADATA_STORE_SOURCE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ GRL_METADATA_STORE_SOURCE_TYPE, \
+ GrlMetadataStoreSource))
+
+#define GRL_IS_METADATA_STORE_SOURCE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+ GRL_METADATA_STORE_SOURCE_TYPE))
+
+#define GRL_METADATA_STORE_SOURCE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass), \
+ GRL_METADATA_STORE_SOURCE_TYPE, \
+ GrlMetadataStoreSourceClass))
+
+#define GRL_IS_METADATA_STORE_SOURCE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass), \
+ GRL_METADATA_STORE_SOURCE_TYPE))
+
+#define GRL_METADATA_STORE_SOURCE_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ GRL_METADATA_STORE_SOURCE_TYPE, \
+ GrlMetadataStoreSourceClass))
+
+typedef struct _GrlMetadataStorePrivate GrlMetadataStorePrivate;
+typedef struct _GrlMetadataStoreSource GrlMetadataStoreSource;
+
+struct _GrlMetadataStoreSource {
+
+ GrlMetadataSource parent;
+
+ /*< private >*/
+ GrlMetadataStorePrivate *priv;
+};
+
+typedef struct _GrlMetadataStoreSourceClass GrlMetadataStoreSourceClass;
+
+struct _GrlMetadataStoreSourceClass {
+
+ GrlMetadataSourceClass parent_class;
+
+};
+
+GType grl_metadata_store_source_get_type (void);
+
+#endif /* _GRL_METADATA_STORE_SOURCE_H_ */
diff --git a/src/podcasts/grl-podcasts.c b/src/podcasts/grl-podcasts.c
index bec5145..12ee7ee 100644
--- a/src/podcasts/grl-podcasts.c
+++ b/src/podcasts/grl-podcasts.c
@@ -210,7 +210,7 @@ typedef struct {
guint parse_count;
guint parse_index;
guint parse_valid_index;
- GrlContentMedia *last_media;
+ GrlMedia *last_media;
} OperationSpecParse;
static GrlPodcastsSource *grl_podcasts_source_new (void);
@@ -236,7 +236,8 @@ static void grl_podcasts_source_remove (GrlMediaSource *source,
static gboolean
grl_podcasts_plugin_init (GrlPluginRegistry *registry,
- const GrlPluginInfo *plugin)
+ const GrlPluginInfo *plugin,
+ GList *configs)
{
g_debug ("podcasts_plugin_init\n");
@@ -502,8 +503,8 @@ get_site_from_url (const gchar *url)
return g_strndup (url, p - url);
}
-static GrlContentMedia *
-build_media (GrlContentMedia *content,
+static GrlMedia *
+build_media (GrlMedia *content,
gboolean is_podcast,
const gchar *id,
const gchar *title,
@@ -514,7 +515,7 @@ build_media (GrlContentMedia *content,
guint duration,
guint childcount)
{
- GrlContentMedia *media = NULL;
+ GrlMedia *media = NULL;
gchar *site;
if (content) {
@@ -523,52 +524,52 @@ build_media (GrlContentMedia *content,
if (is_podcast) {
if (!media) {
- media = GRL_CONTENT_MEDIA (grl_content_box_new ());
+ media = GRL_MEDIA (grl_media_box_new ());
}
- grl_content_media_set_id (media, id);
+ grl_media_set_id (media, id);
if (desc)
- grl_content_media_set_description (media, desc);
- grl_content_box_set_childcount (GRL_CONTENT_BOX (media), childcount);
+ grl_media_set_description (media, desc);
+ grl_media_box_set_childcount (GRL_MEDIA_BOX (media), childcount);
} else {
if (!media) {
if (mime_is_audio (mime)) {
- media = grl_content_audio_new ();
+ media = grl_media_audio_new ();
} else if (mime_is_video (mime)) {
- media = grl_content_video_new ();
+ media = grl_media_video_new ();
} else {
- media = grl_content_media_new ();
+ media = grl_media_new ();
}
}
- grl_content_media_set_id (media, url);
+ grl_media_set_id (media, url);
if (date)
- grl_content_media_set_date (media, date);
+ grl_media_set_date (media, date);
if (desc)
- grl_content_media_set_description (media, desc);
+ grl_media_set_description (media, desc);
if (mime)
- grl_content_media_set_mime (media, mime);
+ grl_media_set_mime (media, mime);
if (duration > 0) {
- grl_content_media_set_duration (media, duration);
+ grl_media_set_duration (media, duration);
}
}
- grl_content_media_set_title (media, title);
- grl_content_media_set_url (media, url);
+ grl_media_set_title (media, title);
+ grl_media_set_url (media, url);
site = get_site_from_url (url);
if (site) {
- grl_content_media_set_site (media, site);
+ grl_media_set_site (media, site);
g_free (site);
}
return media;
}
-static GrlContentMedia *
+static GrlMedia *
build_media_from_entry (Entry *entry)
{
- GrlContentMedia *media;
+ GrlMedia *media;
gint duration;
duration = duration_to_seconds (entry->duration);
@@ -579,12 +580,12 @@ build_media_from_entry (Entry *entry)
return media;
}
-static GrlContentMedia *
-build_media_from_stmt (GrlContentMedia *content,
+static GrlMedia *
+build_media_from_stmt (GrlMedia *content,
sqlite3_stmt *sql_stmt,
gboolean is_podcast)
{
- GrlContentMedia *media;
+ GrlMedia *media;
gchar *id;
gchar *title;
gchar *url;
@@ -624,7 +625,7 @@ produce_podcast_contents_from_db (OperationSpec *os)
sqlite3_stmt *sql_stmt = NULL;
GList *iter, *medias = NULL;
guint count = 0;
- GrlContentMedia *media;
+ GrlMedia *media;
gint r;
GError *error = NULL;
@@ -673,7 +674,7 @@ produce_podcast_contents_from_db (OperationSpec *os)
medias = g_list_reverse (medias);
iter = medias;
while (iter) {
- media = GRL_CONTENT_MEDIA (iter->data);
+ media = GRL_MEDIA (iter->data);
os->callback (os->source,
os->operation_id,
media,
@@ -760,19 +761,20 @@ remove_stream (sqlite3 *db, const gchar *url, GError **error)
}
static void
-store_podcast (sqlite3 *db, GrlContentMedia *podcast, GError **error)
+store_podcast (sqlite3 *db, GrlMedia *podcast, GError **error)
{
gint r;
sqlite3_stmt *sql_stmt = NULL;
const gchar *title;
const gchar *url;
const gchar *desc;
+ gchar *id;
g_debug ("store_podcast");
- title = grl_content_media_get_title (podcast);
- url = grl_content_media_get_url (podcast);
- desc = grl_content_media_get_description (podcast);
+ title = grl_media_get_title (podcast);
+ url = grl_media_get_url (podcast);
+ desc = grl_media_get_description (podcast);
g_debug ("%s", GRL_SQL_STORE_PODCAST);
r = sqlite3_prepare_v2 (db,
@@ -807,6 +809,10 @@ store_podcast (sqlite3 *db, GrlContentMedia *podcast, GError **error)
}
sqlite3_finalize (sql_stmt);
+
+ id = g_strdup_printf ("%llu", sqlite3_last_insert_rowid (db));
+ grl_media_set_id (podcast, id);
+ g_free (id);
}
static void
@@ -909,7 +915,7 @@ parse_entry_idle (gpointer user_data)
OperationSpecParse *osp = (OperationSpecParse *) user_data;
xmlNodeSetPtr nodes;
guint remaining;
- GrlContentMedia *media;
+ GrlMedia *media;
nodes = osp->xpathObj->nodesetval;
@@ -1083,40 +1089,52 @@ read_feed_cb (gchar *xmldata, gpointer user_data)
}
}
-static void
-produce_podcast_contents (OperationSpec *os)
+static sqlite3_stmt *
+get_podcast_info (sqlite3 *db, const gchar *podcast_id)
{
gint r;
sqlite3_stmt *sql_stmt = NULL;
- sqlite3 *db;
- GError *error = NULL;
gchar *sql;
- gchar *url;
- g_debug ("produce_podcast_contents");
+ g_debug ("get_podcast_info");
- /* First we get some information about the podcast */
- db = GRL_PODCASTS_SOURCE (os->source)->priv->db;
- sql = g_strdup_printf (GRL_SQL_GET_PODCAST_BY_ID, os->media_id);
+ sql = g_strdup_printf (GRL_SQL_GET_PODCAST_BY_ID, podcast_id);
g_debug ("%s", sql);
r = sqlite3_prepare_v2 (db, sql, strlen (sql), &sql_stmt, NULL);
g_free (sql);
if (r != SQLITE_OK) {
g_warning ("Failed to retrieve podcast '%s': %s",
- os->media_id, sqlite3_errmsg (db));
- error = g_error_new (GRL_ERROR,
- os->error_code,
- "Failed to retrieve podcast information");
- os->callback (os->source, os->operation_id, NULL, 0, os->user_data, error);
- g_error_free (error);
- g_free (os);
- return;
+ podcast_id, sqlite3_errmsg (db));
+ return NULL;
}
while ((r = sqlite3_step (sql_stmt)) == SQLITE_BUSY);
if (r == SQLITE_ROW) {
+ return sql_stmt;
+ } else {
+ g_warning ("Failed to retrieve podcast information: %s",
+ sqlite3_errmsg (db));
+ sqlite3_finalize (sql_stmt);
+ return NULL;
+ }
+}
+
+static void
+produce_podcast_contents (OperationSpec *os)
+{
+ sqlite3_stmt *sql_stmt = NULL;
+ sqlite3 *db;
+ GError *error;
+ gchar *url;
+
+ g_debug ("produce_podcast_contents");
+
+ /* First we get some information about the podcast */
+ db = GRL_PODCASTS_SOURCE (os->source)->priv->db;
+ sql_stmt = get_podcast_info (db, os->media_id);
+ if (sql_stmt) {
gchar *lr_str;
GTimeVal lr;
GTimeVal now;
@@ -1138,9 +1156,8 @@ produce_podcast_contents (OperationSpec *os)
produce_podcast_contents_from_db (os);
g_free (os);
}
+ sqlite3_finalize (sql_stmt);
} else {
- g_warning ("Failed to retrieve podcast information: %s",
- sqlite3_errmsg (db));
error = g_error_new (GRL_ERROR,
os->error_code,
"Failed to retrieve podcast information");
@@ -1149,7 +1166,6 @@ produce_podcast_contents (OperationSpec *os)
g_free (os);
}
- sqlite3_finalize (sql_stmt);
}
static void
@@ -1158,7 +1174,7 @@ produce_podcasts (OperationSpec *os)
gint r;
sqlite3_stmt *sql_stmt = NULL;
sqlite3 *db;
- GrlContentMedia *media;
+ GrlMedia *media;
GError *error = NULL;
GList *medias = NULL;
guint count = 0;
@@ -1218,7 +1234,7 @@ produce_podcasts (OperationSpec *os)
medias = g_list_reverse (medias);
iter = medias;
while (iter) {
- media = GRL_CONTENT_MEDIA (iter->data);
+ media = GRL_MEDIA (iter->data);
os->callback (os->source,
os->operation_id,
media,
@@ -1251,7 +1267,7 @@ stream_metadata (GrlMediaSourceMetadataSpec *ms)
db = GRL_PODCASTS_SOURCE (ms->source)->priv->db;
- id = grl_content_media_get_id (ms->media);
+ id = grl_media_get_id (ms->media);
sql = g_strdup_printf (GRL_SQL_GET_PODCAST_STREAM, id);
g_debug ("%s", sql);
r = sqlite3_prepare_v2 (db, sql, strlen (sql), &sql_stmt, NULL);
@@ -1287,45 +1303,29 @@ stream_metadata (GrlMediaSourceMetadataSpec *ms)
static void
podcast_metadata (GrlMediaSourceMetadataSpec *ms)
{
- gint r;
sqlite3_stmt *sql_stmt = NULL;
sqlite3 *db;
GError *error = NULL;
- gchar *sql;
const gchar *id;
g_debug ("podcast_metadata");
db = GRL_PODCASTS_SOURCE (ms->source)->priv->db;
- id = grl_content_media_get_id (ms->media);
+ id = grl_media_get_id (ms->media);
if (!id) {
/* Root category: special case */
- grl_content_media_set_title (ms->media, "");
+ grl_media_set_title (ms->media, "");
ms->callback (ms->source, ms->media, ms->user_data, NULL);
return;
}
- sql = g_strdup_printf (GRL_SQL_GET_PODCAST_BY_ID, id);
- g_debug ("%s", sql);
- r = sqlite3_prepare_v2 (db, sql, strlen (sql), &sql_stmt, NULL);
- g_free (sql);
+ sql_stmt = get_podcast_info (db, id);
- if (r != SQLITE_OK) {
- g_warning ("Failed to get podcast: %s", sqlite3_errmsg (db));
- error = g_error_new (GRL_ERROR,
- GRL_ERROR_METADATA_FAILED,
- "Failed to get podcast metadata");
- ms->callback (ms->source, ms->media, ms->user_data, error);
- g_error_free (error);
- return;
- }
-
- while ((r = sqlite3_step (sql_stmt)) == SQLITE_BUSY);
-
- if (r == SQLITE_ROW) {
+ if (sql_stmt) {
build_media_from_stmt (ms->media, sql_stmt, TRUE);
ms->callback (ms->source, ms->media, ms->user_data, NULL);
+ sqlite3_finalize (sql_stmt);
} else {
g_warning ("Failed to get podcast: %s", sqlite3_errmsg (db));
error = g_error_new (GRL_ERROR,
@@ -1334,8 +1334,6 @@ podcast_metadata (GrlMediaSourceMetadataSpec *ms)
ms->callback (ms->source, ms->media, ms->user_data, error);
g_error_free (error);
}
-
- sqlite3_finalize (sql_stmt);
}
static gboolean
@@ -1385,7 +1383,7 @@ grl_podcasts_source_browse (GrlMediaSource *source,
os = g_new0 (OperationSpec, 1);
os->source = bs->source;
os->operation_id = bs->browse_id;
- os->media_id = grl_content_media_get_id (bs->container);
+ os->media_id = grl_media_get_id (bs->container);
os->count = bs->count;
os->skip = bs->skip;
os->callback = bs->callback;
@@ -1490,7 +1488,7 @@ grl_podcasts_source_metadata (GrlMediaSource *source,
g_error_free (error);
}
- media_id = grl_content_media_get_id (ms->media);
+ media_id = grl_media_get_id (ms->media);
if (!media_id || media_id_is_podcast (media_id)) {
podcast_metadata (ms);
} else {
@@ -1503,7 +1501,7 @@ grl_podcasts_source_store (GrlMediaSource *source, GrlMediaSourceStoreSpec *ss)
{
g_debug ("grl_podcasts_source_store");
GError *error = NULL;
- if (GRL_IS_CONTENT_BOX (ss->media)) {
+ if (GRL_IS_MEDIA_BOX (ss->media)) {
error = g_error_new (GRL_ERROR,
GRL_ERROR_STORE_FAILED,
"Cannot create containers. Only feeds are accepted.");
diff --git a/src/shoutcast/grl-shoutcast.c b/src/shoutcast/grl-shoutcast.c
index 041799e..ea1ddc5 100644
--- a/src/shoutcast/grl-shoutcast.c
+++ b/src/shoutcast/grl-shoutcast.c
@@ -65,7 +65,7 @@
#define SITE "http://www.igalia.com"
typedef struct {
- GrlContentMedia *media;
+ GrlMedia *media;
GrlMediaSource *source;
GrlMediaSourceMetadataCb metadata_cb;
GrlMediaSourceResultCb result_cb;
@@ -85,7 +85,8 @@ typedef struct {
static GrlShoutcastSource *grl_shoutcast_source_new (void);
gboolean grl_shoutcast_plugin_init (GrlPluginRegistry *registry,
- const GrlPluginInfo *plugin);
+ const GrlPluginInfo *plugin,
+ GList *configs);
static const GList *grl_shoutcast_source_supported_keys (GrlMetadataSource *source);
@@ -105,7 +106,8 @@ static void grl_shoutcast_source_cancel (GrlMediaSource *source,
gboolean
grl_shoutcast_plugin_init (GrlPluginRegistry *registry,
- const GrlPluginInfo *plugin)
+ const GrlPluginInfo *plugin,
+ GList *configs)
{
g_debug ("shoutcast_plugin_init\n");
@@ -185,35 +187,35 @@ xml_count_nodes (xmlNodePtr node)
return count;
}
-static GrlContentMedia *
+static GrlMedia *
build_media_from_genre (OperationData *op_data)
{
- GrlContentMedia *media;
+ GrlMedia *media;
gchar *genre_name;
if (op_data->media) {
media = op_data->media;
} else {
- media = grl_content_box_new ();
+ media = grl_media_box_new ();
}
genre_name = (gchar *) xmlGetProp (op_data->xml_entries,
(const xmlChar *) "name");
- grl_content_media_set_id (media, genre_name);
- grl_content_media_set_title (media, genre_name);
- grl_content_set_string (GRL_CONTENT (media),
- GRL_METADATA_KEY_GENRE,
- genre_name);
+ grl_media_set_id (media, genre_name);
+ grl_media_set_title (media, genre_name);
+ grl_data_set_string (GRL_DATA (media),
+ GRL_METADATA_KEY_GENRE,
+ genre_name);
g_free (genre_name);
return media;
}
-static GrlContentMedia *
+static GrlMedia *
build_media_from_station (OperationData *op_data)
{
- GrlContentMedia *media;
+ GrlMedia *media;
gchar *media_id;
gchar *media_url;
gchar *station_bitrate;
@@ -238,16 +240,16 @@ build_media_from_station (OperationData *op_data)
if (op_data->media) {
media = op_data->media;
} else {
- media = grl_content_audio_new ();
+ media = grl_media_audio_new ();
}
- grl_content_media_set_id (media, media_id);
- grl_content_media_set_title (media, station_name);
- grl_content_media_set_mime (media, station_mime);
- grl_content_audio_set_genre (GRL_CONTENT_AUDIO (media), station_genre);
- grl_content_media_set_url (media, media_url);
- grl_content_audio_set_bitrate (GRL_CONTENT_AUDIO (media),
- atoi (station_bitrate));
+ grl_media_set_id (media, media_id);
+ grl_media_set_title (media, station_name);
+ grl_media_set_mime (media, station_mime);
+ grl_media_audio_set_genre (GRL_MEDIA_AUDIO (media), station_genre);
+ grl_media_set_url (media, media_url);
+ grl_media_audio_set_bitrate (GRL_MEDIA_AUDIO (media),
+ atoi (station_bitrate));
g_free (station_name);
g_free (station_mime);
@@ -261,7 +263,7 @@ build_media_from_station (OperationData *op_data)
}
static gboolean
-send_media (OperationData *op_data, GrlContentMedia *media)
+send_media (OperationData *op_data, GrlMedia *media)
{
if (!op_data->cancelled) {
op_data->result_cb (op_data->source,
@@ -364,7 +366,7 @@ xml_parse_result (const gchar *str, OperationData *op_data)
error = g_error_new (GRL_ERROR,
op_data->error_code,
"Can not find media '%s'",
- grl_content_media_get_id (op_data->media));
+ grl_media_get_id (op_data->media));
}
if (xpath_res) {
xmlXPathFreeObject (xpath_res);
@@ -522,11 +524,11 @@ grl_shoutcast_source_metadata (GrlMediaSource *source,
repeat the Pop browsing and get the result with station id 1321. If it
doesn't exist (think in results obtained from a search), we do nothing */
- media_id = grl_content_media_get_id (ms->media);
+ media_id = grl_media_get_id (ms->media);
/* Check if we need to report about root category */
if (!media_id) {
- grl_content_media_set_title (ms->media, "SHOUTcast");
+ grl_media_set_title (ms->media, "SHOUTcast");
} else {
data = g_new0 (OperationData, 1);
data->source = source;
@@ -587,7 +589,7 @@ grl_shoutcast_source_browse (GrlMediaSource *source,
data->user_data = bs->user_data;
data->error_code = GRL_ERROR_BROWSE_FAILED;
- container_id = grl_content_media_get_id (bs->container);
+ container_id = grl_media_get_id (bs->container);
/* If it's root category send list of genres; else send list of radios */
if (!container_id) {
diff --git a/src/upnp/grl-upnp.c b/src/upnp/grl-upnp.c
index 815ec13..af2166b 100644
--- a/src/upnp/grl-upnp.c
+++ b/src/upnp/grl-upnp.c
@@ -102,7 +102,8 @@ static gchar *build_source_id (const gchar *udn);
static GrlUpnpSource *grl_upnp_source_new (const gchar *id, const gchar *name);
gboolean grl_upnp_plugin_init (GrlPluginRegistry *registry,
- const GrlPluginInfo *plugin);
+ const GrlPluginInfo *plugin,
+ GList *configs);
static void grl_upnp_source_finalize (GObject *plugin);
@@ -134,7 +135,9 @@ static GHashTable *filter_key_mapping = NULL;
/* =================== UPnP Plugin =============== */
gboolean
-grl_upnp_plugin_init (GrlPluginRegistry *registry, const GrlPluginInfo *plugin)
+grl_upnp_plugin_init (GrlPluginRegistry *registry,
+ const GrlPluginInfo *plugin,
+ GList *configs)
{
GError *error = NULL;
GUPnPContext *context;
@@ -757,43 +760,43 @@ get_value_for_key (GrlKeyID key_id,
}
static void
-set_metadata_value (GrlContentMedia *media,
+set_metadata_value (GrlMedia *media,
GrlKeyID key_id,
const gchar *value)
{
switch (key_id) {
case GRL_METADATA_KEY_TITLE:
- grl_content_media_set_title (media, value);
+ grl_media_set_title (media, value);
break;
case GRL_METADATA_KEY_ARTIST:
- grl_content_audio_set_artist (media, value);
+ grl_media_audio_set_artist (media, value);
break;
case GRL_METADATA_KEY_ALBUM:
- grl_content_audio_set_album (media, value);
+ grl_media_audio_set_album (media, value);
break;
case GRL_METADATA_KEY_GENRE:
- grl_content_audio_set_genre (media, value);
+ grl_media_audio_set_genre (media, value);
break;
case GRL_METADATA_KEY_URL:
- grl_content_media_set_url (media, value);
+ grl_media_set_url (media, value);
break;
case GRL_METADATA_KEY_MIME:
- grl_content_media_set_mime (media, value);
+ grl_media_set_mime (media, value);
break;
case GRL_METADATA_KEY_DATE:
- grl_content_media_set_date (media, value);
+ grl_media_set_date (media, value);
break;
case GRL_METADATA_KEY_DURATION:
{
gint duration = didl_h_mm_ss_to_int (value);
if (duration >= 0) {
- grl_content_media_set_duration (media, duration);
+ grl_media_set_duration (media, duration);
}
}
break;
case GRL_METADATA_KEY_CHILDCOUNT:
- if (value && GRL_IS_CONTENT_BOX (media)) {
- grl_content_box_set_childcount (GRL_CONTENT_BOX (media), atoi (value));
+ if (value && GRL_IS_MEDIA_BOX (media)) {
+ grl_media_box_set_childcount (GRL_MEDIA_BOX (media), atoi (value));
}
break;
default:
@@ -801,8 +804,8 @@ set_metadata_value (GrlContentMedia *media,
}
}
-static GrlContentMedia *
-build_media_from_didl (GrlContentMedia *content,
+static GrlMedia *
+build_media_from_didl (GrlMedia *content,
#ifdef GUPNPAV_OLD_VERSION
xmlNode *didl_node,
#else
@@ -818,7 +821,7 @@ build_media_from_didl (GrlContentMedia *content,
const gchar *class;
#endif
- GrlContentMedia *media = NULL;
+ GrlMedia *media = NULL;
GList *didl_props;
GList *iter;
@@ -834,28 +837,28 @@ build_media_from_didl (GrlContentMedia *content,
if (GUPNP_IS_DIDL_LITE_CONTAINER (didl_node)) {
#endif
- media = grl_content_box_new ();
+ media = grl_media_box_new ();
} else {
if (!media) {
class = gupnp_didl_lite_object_get_upnp_class (didl_node);
if (class) {
if (g_str_has_prefix (class, "object.item.audioItem")) {
- media = grl_content_audio_new ();
+ media = grl_media_audio_new ();
} else if (g_str_has_prefix (class, "object.item.videoItem")) {
- media = grl_content_video_new ();
+ media = grl_media_video_new ();
} else if (g_str_has_prefix (class, "object.item.imageItem")) {
- media = grl_content_image_new ();
+ media = grl_media_image_new ();
} else {
- media = grl_content_media_new ();
+ media = grl_media_new ();
}
} else {
- media = grl_content_media_new ();
+ media = grl_media_new ();
}
}
}
id = gupnp_didl_lite_object_get_id (didl_node);
- grl_content_media_set_id (media, id);
+ grl_media_set_id (media, id);
didl_props = didl_get_supported_resources (didl_node);
@@ -887,7 +890,7 @@ gupnp_browse_result_cb (GUPnPDIDLLiteParser *parser,
#endif
gpointer user_data)
{
- GrlContentMedia *media;
+ GrlMedia *media;
struct OperationSpec *os = (struct OperationSpec *) user_data;
if (gupnp_didl_lite_object_get_id (didl)) {
media = build_media_from_didl (NULL, didl, os->keys);
@@ -1100,7 +1103,7 @@ grl_upnp_source_browse (GrlMediaSource *source, GrlMediaSourceBrowseSpec *bs)
os->callback = bs->callback;
os->user_data = bs->user_data;
- container_id = (gchar *) grl_content_media_get_id (bs->container);
+ container_id = (gchar *) grl_media_get_id (bs->container);
if (!container_id) {
container_id = "0";
}
@@ -1198,7 +1201,7 @@ grl_upnp_source_metadata (GrlMediaSource *source,
g_debug ("filter: '%s'", upnp_filter);
- id = (gchar *) grl_content_media_get_id (ms->media);
+ id = (gchar *) grl_media_get_id (ms->media);
if (!id) {
id = "0";
}
diff --git a/src/youtube/TODO b/src/youtube/TODO
index e69de29..409835c 100644
--- a/src/youtube/TODO
+++ b/src/youtube/TODO
@@ -0,0 +1,6 @@
+- Consider using libgdata.
+- Fix get_metadata() for standard feeds.
+- Consider implementing store() -> video upload.
+- Consider implementing configuration (personal account)
+ -> Could add new category for browsing (my videos)
+ -> would enable store() and remove() operations.
diff --git a/src/youtube/grl-youtube.c b/src/youtube/grl-youtube.c
index 7521aa4..b88f6a6 100644
--- a/src/youtube/grl-youtube.c
+++ b/src/youtube/grl-youtube.c
@@ -189,7 +189,8 @@ typedef enum {
static GrlYoutubeSource *grl_youtube_source_new (void);
gboolean grl_youtube_plugin_init (GrlPluginRegistry *registry,
- const GrlPluginInfo *plugin);
+ const GrlPluginInfo *plugin,
+ GList *configs);
static const GList *grl_youtube_source_supported_keys (GrlMetadataSource *source);
@@ -241,7 +242,8 @@ CategoryInfo *categories_dir = NULL;
gboolean
grl_youtube_plugin_init (GrlPluginRegistry *registry,
- const GrlPluginInfo *plugin)
+ const GrlPluginInfo *plugin,
+ GList *config)
{
g_debug ("youtube_plugin_init\n");
@@ -437,17 +439,17 @@ read_url (const gchar *url)
}
}
-static GrlContentMedia *
-build_media_from_entry (GrlContentMedia *content,
+static GrlMedia *
+build_media_from_entry (GrlMedia *content,
const Entry *entry,
const GList *keys)
{
- GrlContentMedia *media;
+ GrlMedia *media;
gchar *url;
GList *iter;
if (!content) {
- media = grl_content_video_new ();
+ media = grl_media_video_new ();
} else {
media = content;
}
@@ -457,40 +459,40 @@ build_media_from_entry (GrlContentMedia *content,
GrlKeyID key_id = POINTER_TO_GRLKEYID (iter->data);
switch (key_id) {
case GRL_METADATA_KEY_ID:
- grl_content_media_set_id (media, entry->id);
+ grl_media_set_id (media, entry->id);
break;
case GRL_METADATA_KEY_TITLE:
- grl_content_media_set_title (media, entry->title);
+ grl_media_set_title (media, entry->title);
break;
case GRL_METADATA_KEY_AUTHOR:
- grl_content_media_set_author (media, entry->author);
+ grl_media_set_author (media, entry->author);
break;
case GRL_METADATA_KEY_DESCRIPTION:
- grl_content_media_set_description (media, entry->description);
+ grl_media_set_description (media, entry->description);
break;
case GRL_METADATA_KEY_THUMBNAIL:
- grl_content_media_set_thumbnail (media, entry->thumbnail);
+ grl_media_set_thumbnail (media, entry->thumbnail);
break;
case GRL_METADATA_KEY_DATE:
- grl_content_media_set_date (media, entry->published);
+ grl_media_set_date (media, entry->published);
break;
case GRL_METADATA_KEY_DURATION:
- grl_content_media_set_duration (media, atoi (entry->duration));
+ grl_media_set_duration (media, atoi (entry->duration));
break;
case GRL_METADATA_KEY_MIME:
- grl_content_media_set_mime (media, YOUTUBE_VIDEO_MIME);
+ grl_media_set_mime (media, YOUTUBE_VIDEO_MIME);
break;
case GRL_METADATA_KEY_SITE:
- grl_content_media_set_site (media, YOUTUBE_SITE_URL);
+ grl_media_set_site (media, YOUTUBE_SITE_URL);
break;
case GRL_METADATA_KEY_RATING:
- grl_content_media_set_rating (media, entry->rating, "5.00");
+ grl_media_set_rating (media, entry->rating, "5.00");
break;
case GRL_METADATA_KEY_URL:
if (!entry->restricted) {
url = get_video_url (entry->id);
if (url) {
- grl_content_media_set_url (media, url);
+ grl_media_set_url (media, url);
}
g_free (url);
}
@@ -624,7 +626,7 @@ parse_entries_idle (gpointer user_data)
Entry *entry = g_new0 (Entry, 1);
parse_entry (pei->doc, pei->node, entry);
if (0) print_entry (entry);
- GrlContentMedia *media =
+ GrlMedia *media =
build_media_from_entry (NULL, entry, pei->os->keys);
free_entry (entry);
@@ -776,7 +778,7 @@ parse_feed (OperationSpec *os, const gchar *str, GError **error)
return;
}
-static GrlContentMedia *
+static GrlMedia *
parse_metadata_entry (GrlMediaSourceMetadataSpec *os,
xmlDocPtr doc,
xmlNodePtr node,
@@ -784,7 +786,7 @@ parse_metadata_entry (GrlMediaSourceMetadataSpec *os,
{
xmlNs *ns;
guint total_results = 0;
- GrlContentMedia *media = NULL;
+ GrlMedia *media = NULL;
/* First checkout search information looking for totalResults */
while (node && !total_results) {
@@ -804,23 +806,28 @@ parse_metadata_entry (GrlMediaSourceMetadataSpec *os,
node = node->next;
}
- /* Should have exactly 1 result */
- if (total_results != 1) {
+ if (total_results <= 0) {
*error = g_error_new (GRL_ERROR,
GRL_ERROR_MEDIA_NOT_FOUND,
"Could not find requested media");
return NULL;
}
- /* Now go for the entry data */
while (node && xmlStrcmp (node->name, (const xmlChar *) "entry")) {
node = node->next;
}
if (node) {
+ const gchar *target_id = grl_media_get_id (os->media);
Entry *entry = g_new0 (Entry, 1);
parse_entry (doc, node, entry);
if (0) print_entry (entry);
- build_media_from_entry (os->media, entry, os->keys);
+ if (!strcmp (entry->id, target_id)) {
+ build_media_from_entry (os->media, entry, os->keys);
+ } else {
+ /* FIXME: The query using the video id at target text resulted in various
+ matches and the one we were looking for was not the first one */
+ g_warning ("Metadata query did not match expected target");
+ }
free_entry (entry);
}
@@ -1010,7 +1017,7 @@ get_container_url (const gchar *container_id)
}
static void
-set_category_childcount (GrlContentBox *content,
+set_category_childcount (GrlMediaBox *content,
CategoryInfo *dir,
guint index)
{
@@ -1045,48 +1052,48 @@ set_category_childcount (GrlContentBox *content,
}
if (set_childcount) {
- grl_content_box_set_childcount (content, childcount);
+ grl_media_box_set_childcount (content, childcount);
}
}
-static GrlContentMedia *
-produce_container_from_directory (GrlContentMedia *media,
+static GrlMedia *
+produce_container_from_directory (GrlMedia *media,
CategoryInfo *dir,
guint index,
gboolean set_childcount)
{
- GrlContentMedia *content;
+ GrlMedia *content;
if (!media) {
/* Create mode */
- content = grl_content_box_new ();
+ content = grl_media_box_new ();
} else {
/* Update mode */
content = media;
}
if (!dir) {
- grl_content_media_set_id (content, NULL);
- grl_content_media_set_title (content, YOUTUBE_ROOT_NAME);
+ grl_media_set_id (content, NULL);
+ grl_media_set_title (content, YOUTUBE_ROOT_NAME);
} else {
- grl_content_media_set_id (content, dir[index].id);
- grl_content_media_set_title (content, dir[index].name);
+ grl_media_set_id (content, dir[index].id);
+ grl_media_set_title (content, dir[index].name);
}
- grl_content_media_set_site (content, YOUTUBE_SITE_URL);
+ grl_media_set_site (content, YOUTUBE_SITE_URL);
if (set_childcount) {
- set_category_childcount (GRL_CONTENT_BOX (content), dir, index);
+ set_category_childcount (GRL_MEDIA_BOX (content), dir, index);
}
return content;
}
-static GrlContentMedia *
-produce_container_from_directory_by_id (GrlContentMedia *media,
+static GrlMedia *
+produce_container_from_directory_by_id (GrlMedia *media,
CategoryInfo *dir,
const gchar *id,
gboolean set_childcount)
{
- GrlContentMedia *content;
+ GrlMedia *content;
guint index = 0;
while (dir[index].id && strcmp (dir[index].id, id)) index++;
@@ -1123,7 +1130,7 @@ classify_media_id (const gchar *media_id)
static gboolean
produce_from_directory_idle (gpointer user_data)
{
- GrlContentMedia *content;
+ GrlMedia *content;
ProduceFromDirectoryIdle *pfdi = (ProduceFromDirectoryIdle *) user_data;
if (!pfdi->os->cancelled) {
@@ -1342,7 +1349,7 @@ grl_youtube_source_browse (GrlMediaSource *source,
g_debug ("grl_youtube_source_browse");
- container_id = grl_content_media_get_id (bs->container);
+ container_id = grl_media_get_id (bs->container);
os = g_new0 (OperationSpec, 1);
os->source = bs->source;
@@ -1410,14 +1417,14 @@ grl_youtube_source_metadata (GrlMediaSource *source,
{
gchar *url;
GError *error = NULL;
- GrlContentMedia *media = NULL;
+ GrlMedia *media = NULL;
YoutubeMediaType media_type;
gboolean set_childcount;
const gchar *id;
g_debug ("grl_youtube_source_metadata");
- id = grl_content_media_get_id (ms->media);
+ id = grl_media_get_id (ms->media);
media_type = classify_media_id (id);
/* Do not compute childcount for expensive categories
diff --git a/test/main.c b/test/main.c
index d86a723..32de62c 100644
--- a/test/main.c
+++ b/test/main.c
@@ -51,10 +51,21 @@ print_supported_ops (GrlMetadataSource *source)
if (caps & GRL_OP_QUERY) {
g_debug (" + Query");
}
+ if (caps & GRL_OP_STORE_PARENT) {
+ g_debug (" + Store (parent)");
+ } else if (caps & GRL_OP_STORE) {
+ g_debug (" + Store");
+ }
+ if (caps & GRL_OP_REMOVE) {
+ g_debug (" + Remove");
+ }
+ if (caps & GRL_OP_SET_METADATA) {
+ g_debug (" + Set Metadata");
+ }
}
static void
-print_metadata (gpointer key, GrlContent *content)
+print_metadata (gpointer key, GrlData *content)
{
GrlKeyID key_id = POINTER_TO_GRLKEYID(key);
@@ -66,7 +77,7 @@ print_metadata (gpointer key, GrlContent *content)
const GrlMetadataKey *mkey =
grl_plugin_registry_lookup_metadata_key (registry, key_id);
- const GValue *value = grl_content_get (content, key_id);
+ const GValue *value = grl_data_get (content, key_id);
if (value && G_VALUE_HOLDS_STRING (value)) {
g_debug ("\t%s: %s", GRL_METADATA_KEY_GET_NAME (mkey),
g_value_get_string (value));
@@ -76,28 +87,28 @@ print_metadata (gpointer key, GrlContent *content)
}
}
-static GrlContentMedia *
+static GrlMedia *
media_from_id (const gchar *id)
{
- GrlContentMedia *media;
- media = grl_content_media_new ();
- grl_content_media_set_id (media, id);
+ GrlMedia *media;
+ media = grl_media_new ();
+ grl_media_set_id (media, id);
return media;
}
-static GrlContentMedia *
+static GrlMedia *
box_from_id (const gchar *id)
{
- GrlContentMedia *media;
- media = grl_content_box_new ();
- grl_content_media_set_id (media, id);
+ GrlMedia *media;
+ media = grl_media_box_new ();
+ grl_media_set_id (media, id);
return media;
}
static void
browse_cb (GrlMediaSource *source,
guint browse_id,
- GrlContentMedia *media,
+ GrlMedia *media,
guint remaining,
gpointer user_data,
const GError *error)
@@ -118,10 +129,10 @@ browse_cb (GrlMediaSource *source,
}
g_debug ("\tContainer: %s",
- GRL_IS_CONTENT_BOX(media) ? "yes" : "no");
+ GRL_IS_MEDIA_BOX(media) ? "yes" : "no");
- keys = grl_content_get_keys (GRL_CONTENT (media));
- g_list_foreach (keys, (GFunc) print_metadata, GRL_CONTENT (media));
+ keys = grl_data_get_keys (GRL_DATA (media));
+ g_list_foreach (keys, (GFunc) print_metadata, GRL_DATA (media));
g_list_free (keys);
g_object_unref (media);
@@ -132,7 +143,7 @@ browse_cb (GrlMediaSource *source,
static void
metadata_cb (GrlMediaSource *source,
- GrlContentMedia *media,
+ GrlMedia *media,
gpointer user_data,
const GError *error)
{
@@ -146,13 +157,13 @@ metadata_cb (GrlMediaSource *source,
}
g_debug (" Got metadata for object '%s'",
- grl_content_media_get_id (GRL_CONTENT_MEDIA (media)));
+ grl_media_get_id (GRL_MEDIA (media)));
g_debug ("\tContainer: %s",
- GRL_IS_CONTENT_BOX(media) ? "yes" : "no");
+ GRL_IS_MEDIA_BOX(media) ? "yes" : "no");
- keys = grl_content_get_keys (GRL_CONTENT (media));
- g_list_foreach (keys, (GFunc) print_metadata, GRL_CONTENT (media));
+ keys = grl_data_get_keys (GRL_DATA (media));
+ g_list_foreach (keys, (GFunc) print_metadata, GRL_DATA (media));
g_list_free (keys);
g_object_unref (media);
@@ -161,13 +172,26 @@ metadata_cb (GrlMediaSource *source,
static void
resolve_cb (GrlMetadataSource *source,
- GrlContentMedia *media,
+ GrlMedia *media,
gpointer user_data,
const GError *error)
{
metadata_cb (NULL, media, user_data, error);
}
+static void
+set_cb (GrlMetadataSource *source,
+ GrlMedia *media,
+ GList *failed_keys,
+ gpointer user_data,
+ const GError *error)
+{
+ if (error) {
+ g_critical ("%s: %d keys not written",
+ error->message, g_list_length (failed_keys));
+ }
+}
+
gint
main (void)
{
@@ -182,7 +206,8 @@ main (void)
"grl-shoutcast:*,"
"grl-apple-trailers:*,"
"grl-lastfm-albumart:*,"
- "grl-flickr:*");
+ "grl-flickr:*,"
+ "grl-metadata-store:*");
keys = grl_metadata_key_list_new (GRL_METADATA_KEY_ID,
GRL_METADATA_KEY_TITLE,
@@ -197,6 +222,10 @@ main (void)
GRL_METADATA_KEY_DURATION,
GRL_METADATA_KEY_CHILDCOUNT,
GRL_METADATA_KEY_MIME,
+ GRL_METADATA_KEY_PLAY_COUNT,
+ GRL_METADATA_KEY_LAST_PLAYED,
+ GRL_METADATA_KEY_LAST_POSITION,
+ GRL_METADATA_KEY_RATING,
NULL);
g_debug ("start");
@@ -220,6 +249,12 @@ main (void)
"../src/lastfm-albumart/.libs/libgrllastfm-albumart.so");
grl_plugin_registry_load (registry,
"../src/flickr/.libs/libgrlflickr.so");
+ grl_plugin_registry_load (registry,
+ "../src/metadata-store/.libs/libgrlmetadatastore.so");
+ grl_plugin_registry_load (registry,
+ "../src/bookmarks/.libs/libgrlbookmarks.so");
+ grl_plugin_registry_load (registry,
+ "../src/podcasts/.libs/libgrlpodcasts.so");
g_debug ("Obtaining sources");
@@ -255,33 +290,48 @@ main (void)
(GrlMetadataSource *) grl_plugin_registry_lookup_source (registry,
"grl-lastfm-albumart");
+ GrlMetadataSource *metadata_store =
+ (GrlMetadataSource *) grl_plugin_registry_lookup_source (registry,
+ "grl-metadata-store");
+
+ GrlMediaSource *bookmarks =
+ (GrlMediaSource *) grl_plugin_registry_lookup_source (registry,
+ "grl-bookmarks");
+
+ GrlMediaSource *podcasts =
+ (GrlMediaSource *) grl_plugin_registry_lookup_source (registry,
+ "grl-podcasts");
+
g_assert (youtube);
g_assert (fs);
- g_assert (flickr);
g_assert (jamendo);
g_assert (shoutcast);
g_assert (apple_trailers);
- g_assert (fake);
g_assert (lastfm);
-
+ g_assert (metadata_store);
+ g_assert (bookmarks);
+ g_assert (podcasts);
g_debug ("Supported operations");
print_supported_ops (GRL_METADATA_SOURCE (youtube));
print_supported_ops (GRL_METADATA_SOURCE (fs));
- print_supported_ops (GRL_METADATA_SOURCE (flickr));
+ if (flickr) print_supported_ops (GRL_METADATA_SOURCE (flickr));
print_supported_ops (GRL_METADATA_SOURCE (jamendo));
print_supported_ops (GRL_METADATA_SOURCE (apple_trailers));
print_supported_ops (GRL_METADATA_SOURCE (shoutcast));
- print_supported_ops (fake);
+ if (fake) print_supported_ops (fake);
+ print_supported_ops (GRL_METADATA_SOURCE (podcasts));
+ print_supported_ops (GRL_METADATA_SOURCE (bookmarks));
print_supported_ops (lastfm);
+ print_supported_ops (metadata_store);
g_debug ("testing");
if (0) grl_media_source_browse (youtube, NULL, keys, 0, 5, GRL_RESOLVE_IDLE_RELAY , browse_cb, NULL);
if (0) grl_media_source_browse (youtube, NULL, keys, 0, 5, GRL_RESOLVE_IDLE_RELAY , browse_cb, NULL);
if (0) grl_media_source_browse (youtube, media_from_id ("standard-feeds/most-viewed"), keys, 0, 10, GRL_RESOLVE_FAST_ONLY , browse_cb, NULL);
- if (0) grl_media_source_browse (youtube, media_from_id ("categories/Sports"), keys, 0, 173, GRL_RESOLVE_FAST_ONLY, browse_cb, NULL);
- if (0) grl_media_source_search (youtube, "igalia", keys, 6, 10, GRL_RESOLVE_FAST_ONLY, browse_cb, NULL);
+ if (0) grl_media_source_browse (youtube, media_from_id ("categories/Sports"), keys, 0, 5, GRL_RESOLVE_FAST_ONLY, browse_cb, NULL);
+ if (0) grl_media_source_search (youtube, "igalia", keys, 0, 3, GRL_RESOLVE_FULL | GRL_RESOLVE_FAST_ONLY, browse_cb, NULL);
if (0) grl_media_source_search (youtube, "igalia", keys, 1, 10, GRL_RESOLVE_FULL | GRL_RESOLVE_IDLE_RELAY | GRL_RESOLVE_FAST_ONLY, browse_cb, NULL);
if (0) grl_media_source_metadata (youtube, NULL, keys, 0, metadata_cb, NULL);
if (0) grl_media_source_metadata (youtube, NULL, keys, GRL_RESOLVE_IDLE_RELAY | GRL_RESOLVE_FAST_ONLY | GRL_RESOLVE_FULL, metadata_cb, NULL);
@@ -314,17 +364,35 @@ main (void)
if (0) grl_media_source_metadata (shoutcast, box_from_id("2424hs"), keys, 0, metadata_cb, NULL);
if (0) grl_media_source_metadata (shoutcast, media_from_id("American/556687"), keys, 0, metadata_cb, NULL);
if (0) grl_media_source_metadata (shoutcast, media_from_id("American/556682"), keys, 0, metadata_cb, NULL);
- if (1) grl_media_source_browse (apple_trailers, NULL, keys, 0, 5, GRL_RESOLVE_IDLE_RELAY , browse_cb, NULL);
+ if (0) grl_media_source_browse (apple_trailers, NULL, keys, 0, 5, GRL_RESOLVE_IDLE_RELAY , browse_cb, NULL);
if (0) {
- GrlContentMedia *media = media_from_id ("test");
- grl_content_set_string (GRL_CONTENT (media),
- GRL_METADATA_KEY_ARTIST,
- "roxette");
- grl_content_set_string (GRL_CONTENT (media),
- GRL_METADATA_KEY_ALBUM,
- "pop hits");
+ GrlMedia *media = media_from_id ("test");
+ grl_data_set_string (GRL_DATA (media),
+ GRL_METADATA_KEY_ARTIST,
+ "roxette");
+ grl_data_set_string (GRL_DATA (media),
+ GRL_METADATA_KEY_ALBUM,
+ "pop hits");
grl_metadata_source_resolve (lastfm, keys, media, GRL_RESOLVE_IDLE_RELAY, resolve_cb, NULL);
}
+ if (1) {
+ GrlMedia *media = media_from_id ("test-id");
+ grl_media_set_source (media, "some-source-id");
+ grl_media_set_play_count (media, 68);
+ grl_media_set_rating (media, "4.5", "5");
+ grl_media_set_last_position (media, 60);
+ grl_media_set_last_played (media, "19/11/2009");
+ GList *keys_to_write = grl_metadata_key_list_new (GRL_METADATA_KEY_PLAY_COUNT,
+ GRL_METADATA_KEY_RATING,
+ GRL_METADATA_KEY_LAST_POSITION,
+ GRL_METADATA_KEY_ALBUM,
+ GRL_METADATA_KEY_LAST_PLAYED,
+ GRL_METADATA_KEY_TITLE,
+ GRL_METADATA_KEY_GENRE,
+ NULL);
+ grl_metadata_source_set_metadata (metadata_store, media, keys_to_write,
+ GRL_WRITE_FULL, set_cb, NULL);
+ }
g_debug ("Running main loop");