[PATCH 07/14] tracker: add browsing support
- From: llandwerlin gmail com
- To: grilo-list gnome org
- Subject: [PATCH 07/14] tracker: add browsing support
- Date: Mon, 17 Jan 2011 10:18:04 +0000
From: Lionel Landwerlin <lionel g landwerlin linux intel com>
Support flat & directory browsing
Signed-off-by: Lionel Landwerlin <lionel g landwerlin linux intel com>
---
src/tracker/grl-tracker.c | 287 ++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 269 insertions(+), 18 deletions(-)
diff --git a/src/tracker/grl-tracker.c b/src/tracker/grl-tracker.c
index c028f20..eed2e05 100644
--- a/src/tracker/grl-tracker.c
+++ b/src/tracker/grl-tracker.c
@@ -4,6 +4,7 @@
* Contact: Iago Toral Quiroga <itoral igalia com>
*
* Authors: Juan A. Suarez Romero <jasuarez igalia com>
+ * Lionel Landwerlin <lionel g landwerlin linux intel com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
@@ -46,6 +47,7 @@ GRL_LOG_DOMAIN_STATIC(tracker_log_domain);
#define RDF_TYPE_AUDIO "nmm#MusicPiece"
#define RDF_TYPE_IMAGE "nmm#Photo"
#define RDF_TYPE_VIDEO "nmm#Video"
+#define RDF_TYPE_FOLDER "nfo#Folder"
#define RDF_TYPE_BOX "grilo#Box"
/* ---- Plugin information --- */
@@ -69,6 +71,41 @@ enum {
/* --- Other --- */
+#define TRACKER_BROWSE_FLAT_REQUEST " \
+ SELECT %s \
+ WHERE { \
+ { ?urn a nmm:Video } UNION \
+ { ?urn a nmm:Photo } UNION \
+ { ?urn a nmm:MusicPiece } . \
+ ?urn tracker:available ?tr . \
+ } \
+ ORDER BY DESC(nfo:fileLastModified(?urn)) \
+ OFFSET %i LIMIT %i"
+
+#define TRACKER_BROWSE_DIRECTORY_ROOT_REQUEST " \
+ SELECT %s nie:isPartOf(?urn) AS ?parent \
+ WHERE { \
+ ?urn a nfo:Folder . \
+ ?urn tracker:available ?tr . \
+ OPTIONAL { ?urn nie:isPartOf ?parent } \
+ FILTER (! bound(?parent)) \
+ } \
+ ORDER BY ASC(nfo:fileName(?urn)) \
+ OFFSET %i LIMIT %i"
+
+#define TRACKER_BROWSE_DIRECTORY_CONT_REQUEST " \
+ SELECT %s \
+ WHERE { \
+ { ?urn a nfo:Folder } UNION \
+ { ?urn a nmm:Video } UNION \
+ { ?urn a nmm:Photo } UNION \
+ { ?urn a nmm:MusicPiece } . \
+ ?urn tracker:available ?tr . \
+ ?urn nie:isPartOf <%s> \
+ } \
+ ORDER BY ASC(nfo:fileName(?urn)) \
+ OFFSET %i LIMIT %i"
+
#define TRACKER_SEARCH_REQUEST " \
SELECT %s \
WHERE { \
@@ -94,6 +131,12 @@ typedef enum {
MEDIA_PROP_FLOAT,
} tracker_grl_type_t;
+typedef enum {
+ TRACKER_BROWSING_MODE_FLAT,
+ TRACKER_BROWSING_MODE_DIRECTORY,
+ TRACKER_BROWSING_MODE_INVALID,
+} tracker_browsing_mode_t;
+
typedef struct {
GrlKeyID grl_key;
tracker_grl_type_t grl_key_type;
@@ -115,6 +158,13 @@ struct OperationSpec {
struct _GrlTrackerSourcePriv {
TrackerSparqlConnection *tracker_connection;
+
+ tracker_browsing_mode_t browsing_mode;
+};
+
+enum {
+ PROP_0,
+ PROP_BROWSING_MODE,
};
#define GRL_TRACKER_SOURCE_GET_PRIVATE(object) \
@@ -122,12 +172,25 @@ struct _GrlTrackerSourcePriv {
GRL_TRACKER_SOURCE_TYPE, \
GrlTrackerSourcePriv))
-static GrlTrackerSource *grl_tracker_source_new (void);
gboolean grl_tracker_plugin_init (GrlPluginRegistry *registry,
const GrlPluginInfo *plugin,
GList *configs);
+static GrlTrackerSource *grl_tracker_source_new (void);
+
+static void grl_tracker_source_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+static void grl_tracker_source_set_property (GObject *object,
+ guint propid,
+ const GValue *value,
+ GParamSpec *pspec);
+
+static void grl_tracker_source_finalize (GObject *plugin);
+
static GrlSupportedOps grl_tracker_source_supported_operations (GrlMetadataSource *metadata_source);
static const GList *grl_tracker_source_supported_keys (GrlMetadataSource *source);
@@ -142,8 +205,15 @@ static void grl_tracker_source_search (GrlMediaSource *source,
static void grl_tracker_source_metadata (GrlMediaSource *source,
GrlMediaSourceMetadataSpec *ms);
+static void grl_tracker_source_browse (GrlMediaSource *source,
+ GrlMediaSourceBrowseSpec *bs);
+
static void setup_key_mappings (void);
+static const gchar *tracker_browsing_mode_to_str (tracker_browsing_mode_t mode);
+
+static tracker_browsing_mode_t tracker_browsing_mode_from_str (const gchar *str);
+
/* ===================== Globals ================= */
static GHashTable *grl_to_sparql_mapping = NULL;
@@ -156,11 +226,31 @@ grl_tracker_plugin_init (GrlPluginRegistry *registry,
const GrlPluginInfo *plugin,
GList *configs)
{
+ GrlConfig *config;
+ gint config_count;
+
GRL_LOG_DOMAIN_INIT (tracker_log_domain, "tracker");
GRL_DEBUG ("tracker_plugin_init");
GrlTrackerSource *source = grl_tracker_source_new ();
+
+ if (!configs) {
+ GRL_WARNING ("Configuration not provided! Using default configuration.");
+ } else {
+ config_count = g_list_length (configs);
+ if (config_count > 1) {
+ GRL_WARNING ("Provided %i configs, but will only use one", config_count);
+ }
+
+ config = GRL_CONFIG (configs->data);
+
+ g_object_set (G_OBJECT (source),
+ "browsing-mode",
+ grl_config_get_string (config, "flat-browsing-view"),
+ NULL);
+ }
+
grl_plugin_registry_register_source (registry,
plugin,
GRL_MEDIA_PLUGIN (source),
@@ -202,33 +292,33 @@ grl_tracker_source_new (void)
G_DEFINE_TYPE (GrlTrackerSource, grl_tracker_source, GRL_TYPE_MEDIA_SOURCE);
static void
-grl_tracker_source_finalize (GObject *object)
-{
- GrlTrackerSource *self;
-
- self = GRL_TRACKER_SOURCE (object);
- if (self->priv->tracker_connection) {
- g_object_unref (self->priv->tracker_connection);
- }
-
- G_OBJECT_CLASS (grl_tracker_source_parent_class)->finalize (object);
-}
-
-static void
grl_tracker_source_class_init (GrlTrackerSourceClass * klass)
{
GrlMediaSourceClass *source_class = GRL_MEDIA_SOURCE_CLASS (klass);
GrlMetadataSourceClass *metadata_class = GRL_METADATA_SOURCE_CLASS (klass);
GObjectClass *g_class = G_OBJECT_CLASS (klass);
+ source_class->browse = grl_tracker_source_browse;
+ source_class->metadata = grl_tracker_source_metadata;
source_class->query = grl_tracker_source_query;
source_class->search = grl_tracker_source_search;
- source_class->metadata = grl_tracker_source_metadata;
metadata_class->supported_keys = grl_tracker_source_supported_keys;
metadata_class->supported_operations = grl_tracker_source_supported_operations;
- g_class->finalize = grl_tracker_source_finalize;
+ g_class->finalize = grl_tracker_source_finalize;
+ g_class->get_property = grl_tracker_source_get_property;
+ g_class->set_property = grl_tracker_source_set_property;
+
+ g_object_class_install_property (g_class,
+ PROP_BROWSING_MODE,
+ g_param_spec_string ("browsing-mode",
+ "browsing-mode",
+ "Method used to browse a tracker source (flat,directory)",
+ "directory",
+ G_PARAM_READABLE
+ | G_PARAM_WRITABLE
+ | G_PARAM_STATIC_NAME));
g_type_class_add_private (klass, sizeof (GrlTrackerSourcePriv));
@@ -239,10 +329,98 @@ static void
grl_tracker_source_init (GrlTrackerSource *source)
{
source->priv = GRL_TRACKER_SOURCE_GET_PRIVATE (source);
+
+ source->priv->browsing_mode = TRACKER_BROWSING_MODE_DIRECTORY;
+}
+
+static void
+grl_tracker_source_finalize (GObject *object)
+{
+ GrlTrackerSource *self;
+
+ self = GRL_TRACKER_SOURCE (object);
+ if (self->priv->tracker_connection) {
+ g_object_unref (self->priv->tracker_connection);
+ }
+
+ G_OBJECT_CLASS (grl_tracker_source_parent_class)->finalize (object);
+}
+
+static void
+grl_tracker_source_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GrlTrackerSourcePriv *priv = GRL_TRACKER_SOURCE_GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case PROP_BROWSING_MODE:
+ g_value_set_string (value,
+ g_strdup (tracker_browsing_mode_to_str (priv->browsing_mode)));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+grl_tracker_source_set_property (GObject *object,
+ guint propid,
+ const GValue *value,
+ GParamSpec *pspec)
+
+{
+ GrlTrackerSourcePriv *priv = GRL_TRACKER_SOURCE_GET_PRIVATE (object);
+
+ switch (propid) {
+ case PROP_BROWSING_MODE:
+ {
+ tracker_browsing_mode_t mode =
+ tracker_browsing_mode_from_str (g_value_get_string (value));
+ if (mode != TRACKER_BROWSING_MODE_INVALID)
+ priv->browsing_mode = mode;
+ }
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
+ }
}
/* ======================= Utilities ==================== */
+static const gchar *
+tracker_browsing_mode_to_str (tracker_browsing_mode_t mode)
+{
+ switch (mode) {
+ case TRACKER_BROWSING_MODE_FLAT:
+ return "flat";
+
+ case TRACKER_BROWSING_MODE_DIRECTORY:
+ return "directory";
+
+ default:
+ return "invalid";
+ }
+
+ return "invalid";
+}
+
+static tracker_browsing_mode_t
+tracker_browsing_mode_from_str (const gchar *str)
+{
+ if (str == NULL)
+ return TRACKER_BROWSING_MODE_INVALID;
+ if (!strcmp (str, "flat"))
+ return TRACKER_BROWSING_MODE_FLAT;
+ if (!strcmp (str, "directory"))
+ return TRACKER_BROWSING_MODE_DIRECTORY;
+ return TRACKER_BROWSING_MODE_INVALID;
+}
+
static gchar *
build_flavored_key (gchar *key, const gchar *flavor)
{
@@ -326,7 +504,7 @@ setup_key_mappings (void)
"audio");
insert_key_mapping (GRL_METADATA_KEY_FRAMERATE,
- MEDIA_PROP_INT,
+ MEDIA_PROP_FLOAT,
"nfo:frameRate(?urn)",
"video");
@@ -442,8 +620,12 @@ build_grilo_media (const gchar *rdf_type)
media = grl_media_box_new ();
} else if (g_str_has_suffix (rdf_single_type[i], RDF_TYPE_ALBUM)) {
media = grl_media_box_new ();
+ } else if (g_str_has_suffix (rdf_single_type[i], RDF_TYPE_FOLDER)) {
+ media = grl_media_box_new ();
} else if (g_str_has_suffix (rdf_single_type[i], RDF_TYPE_BOX)) {
media = grl_media_box_new ();
+ } else {
+ media = grl_media_new ();
}
i--;
}
@@ -466,6 +648,9 @@ fill_grilo_media_from_sparql (GrlMedia *media,
const gchar *str_val;
} val;
+ if (assoc == NULL)
+ return;
+
GRL_DEBUG ("\tSetting media prop (col=%i/var=%s//prop=%s/type=%i) %s",
column,
sparql_key,
@@ -623,7 +808,7 @@ grl_tracker_source_supported_operations (GrlMetadataSource *metadata_source)
GrlTrackerSource *source;
source = GRL_TRACKER_SOURCE (metadata_source);
- caps = GRL_OP_QUERY | GRL_OP_SEARCH | GRL_OP_METADATA;
+ caps = GRL_OP_BROWSE | GRL_OP_METADATA | GRL_OP_QUERY | GRL_OP_SEARCH;
return caps;
}
@@ -823,3 +1008,69 @@ grl_tracker_source_metadata (GrlMediaSource *source,
if (sparql_final != NULL)
g_free (sparql_final);
}
+
+static void
+grl_tracker_source_browse (GrlMediaSource *source,
+ GrlMediaSourceBrowseSpec *bs)
+{
+ GrlTrackerSourcePriv *priv = GRL_TRACKER_SOURCE_GET_PRIVATE (source);
+ gchar *sparql_select;
+ gchar *sparql_final;
+ GError *error = NULL;
+ struct OperationSpec *os;
+
+ GRL_DEBUG ("grl_tracker_source_browse");
+
+ if (priv->tracker_connection == NULL) {
+ error = g_error_new (GRL_CORE_ERROR,
+ GRL_CORE_ERROR_SEARCH_FAILED,
+ "No tracker connection");
+ goto send_error;
+ }
+
+ sparql_select = get_select_string (source, bs->keys);
+ if (priv->browsing_mode == TRACKER_BROWSING_MODE_FLAT) {
+ sparql_final = g_strdup_printf (TRACKER_BROWSE_FLAT_REQUEST,
+ sparql_select, bs->skip, bs->count);
+ } else {
+ if (bs->container == NULL ||
+ grl_media_get_id (bs->container) == NULL) {
+ sparql_final = g_strdup_printf (TRACKER_BROWSE_DIRECTORY_ROOT_REQUEST,
+ sparql_select, bs->skip, bs->count);
+ } else {
+ sparql_final = g_strdup_printf (TRACKER_BROWSE_DIRECTORY_CONT_REQUEST,
+ sparql_select,
+ grl_media_get_id (bs->container),
+ bs->skip, bs->count);
+ }
+ }
+
+ GRL_DEBUG ("select: '%s'", sparql_final);
+
+ os = g_slice_new0 (struct OperationSpec);
+ os->source = bs->source;
+ os->priv = priv;
+ os->operation_id = bs->browse_id;
+ os->keys = grl_tracker_source_supported_keys (GRL_METADATA_SOURCE (source));
+ os->skip = bs->skip;
+ os->count = bs->count;
+ os->callback = bs->callback;
+ os->user_data = bs->user_data;
+
+ tracker_sparql_connection_query_async (priv->tracker_connection,
+ sparql_final,
+ NULL,
+ (GAsyncReadyCallback) tracker_query_cb,
+ os);
+
+ if (sparql_select != NULL)
+ g_free (sparql_select);
+ if (sparql_final != NULL)
+ g_free (sparql_final);
+
+ return;
+
+ send_error:
+ bs->callback (bs->source, bs->browse_id, NULL, 0, bs->user_data, error);
+ g_error_free (error);
+}
--
1.7.2.3
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]