[PATCH 1/4] tracker: reorganize files before add metadata support
- From: lionel g landwerlin linux intel com
- To: grilo-list gnome org
- Subject: [PATCH 1/4] tracker: reorganize files before add metadata support
- Date: Thu, 10 Mar 2011 15:18:29 +0000
From: Lionel Landwerlin <lionel g landwerlin linux intel com>
Signed-off-by: Lionel Landwerlin <lionel g landwerlin linux intel com>
---
src/media/tracker/Makefile.am | 21 +-
src/media/tracker/grl-tracker-api.c | 840 --------------------------
src/media/tracker/grl-tracker-api.h | 56 --
src/media/tracker/grl-tracker-cache.c | 188 ------
src/media/tracker/grl-tracker-cache.h | 45 --
src/media/tracker/grl-tracker-media-api.c | 841 +++++++++++++++++++++++++++
src/media/tracker/grl-tracker-media-api.h | 56 ++
src/media/tracker/grl-tracker-media-cache.c | 188 ++++++
src/media/tracker/grl-tracker-media-cache.h | 45 ++
src/media/tracker/grl-tracker-media-notif.c | 641 ++++++++++++++++++++
src/media/tracker/grl-tracker-media-notif.h | 54 ++
src/media/tracker/grl-tracker-media-priv.h | 86 +++
src/media/tracker/grl-tracker-media.c | 417 +++++++++++++
src/media/tracker/grl-tracker-media.h | 88 +++
src/media/tracker/grl-tracker-notif.c | 641 --------------------
src/media/tracker/grl-tracker-notif.h | 54 --
src/media/tracker/grl-tracker-priv.h | 86 ---
src/media/tracker/grl-tracker-utils.c | 17 +-
src/media/tracker/grl-tracker-utils.h | 16 +-
src/media/tracker/grl-tracker.c | 416 -------------
src/media/tracker/grl-tracker.h | 88 ---
21 files changed, 2443 insertions(+), 2441 deletions(-)
delete mode 100644 src/media/tracker/grl-tracker-api.c
delete mode 100644 src/media/tracker/grl-tracker-api.h
delete mode 100644 src/media/tracker/grl-tracker-cache.c
delete mode 100644 src/media/tracker/grl-tracker-cache.h
create mode 100644 src/media/tracker/grl-tracker-media-api.c
create mode 100644 src/media/tracker/grl-tracker-media-api.h
create mode 100644 src/media/tracker/grl-tracker-media-cache.c
create mode 100644 src/media/tracker/grl-tracker-media-cache.h
create mode 100644 src/media/tracker/grl-tracker-media-notif.c
create mode 100644 src/media/tracker/grl-tracker-media-notif.h
create mode 100644 src/media/tracker/grl-tracker-media-priv.h
create mode 100644 src/media/tracker/grl-tracker-media.c
create mode 100644 src/media/tracker/grl-tracker-media.h
delete mode 100644 src/media/tracker/grl-tracker-notif.c
delete mode 100644 src/media/tracker/grl-tracker-notif.h
delete mode 100644 src/media/tracker/grl-tracker-priv.h
delete mode 100644 src/media/tracker/grl-tracker.c
delete mode 100644 src/media/tracker/grl-tracker.h
diff --git a/src/media/tracker/Makefile.am b/src/media/tracker/Makefile.am
index 537aaa4..accacfe 100644
--- a/src/media/tracker/Makefile.am
+++ b/src/media/tracker/Makefile.am
@@ -19,16 +19,17 @@ libgrltracker_la_LDFLAGS = \
-module \
-avoid-version
-libgrltracker_la_SOURCES = \
- grl-tracker.c \
- grl-tracker.h \
- grl-tracker-api.c \
- grl-tracker-api.h \
- grl-tracker-cache.c \
- grl-tracker-cache.h \
- grl-tracker-notif.c \
- grl-tracker-notif.h \
- grl-tracker-utils.c \
+libgrltracker_la_SOURCES = \
+ grl-tracker-media.c \
+ grl-tracker-media.h \
+ grl-tracker-media-api.c \
+ grl-tracker-media-api.h \
+ grl-tracker-media-cache.c \
+ grl-tracker-media-cache.h \
+ grl-tracker-media-notif.c \
+ grl-tracker-media-notif.h \
+ \
+ grl-tracker-utils.c \
grl-tracker-utils.h
libdir = $(GRL_PLUGINS_DIR)
diff --git a/src/media/tracker/grl-tracker-api.c b/src/media/tracker/grl-tracker-api.c
deleted file mode 100644
index a85f564..0000000
--- a/src/media/tracker/grl-tracker-api.c
+++ /dev/null
@@ -1,840 +0,0 @@
-/*
- * Copyright (C) 2011 Intel Corporation.
- *
- * Contact: Iago Toral Quiroga <itoral igalia com>
- *
- * Authors: 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
- * 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
- *
- */
-
-#include <gio/gio.h>
-#include <tracker-sparql.h>
-
-#include "grl-tracker-api.h"
-#include "grl-tracker-cache.h"
-#include "grl-tracker-priv.h"
-#include "grl-tracker-utils.h"
-
-/* --------- Logging -------- */
-
-#define GRL_LOG_DOMAIN_DEFAULT tracker_request_log_domain
-
-GRL_LOG_DOMAIN_STATIC(tracker_request_log_domain);
-GRL_LOG_DOMAIN_STATIC(tracker_result_log_domain);
-
-/* Inputs/requests */
-#define GRL_IDEBUG(args...) \
- GRL_LOG (tracker_request_log_domain, \
- GRL_LOG_LEVEL_DEBUG, args)
-
-/* Outputs/results */
-#define GRL_ODEBUG(args...) \
- GRL_LOG (tracker_result_log_domain, \
- GRL_LOG_LEVEL_DEBUG, args)
-
-/* ------- Definitions ------- */
-
-#define TRACKER_QUERY_REQUEST \
- "SELECT rdf:type(?urn) %s " \
- "WHERE { %s . %s } " \
- "ORDER BY DESC(nfo:fileLastModified(?urn)) " \
- "OFFSET %i " \
- "LIMIT %i"
-
-#define TRACKER_SEARCH_REQUEST \
- "SELECT rdf:type(?urn) %s " \
- "WHERE " \
- "{ " \
- "?urn a nfo:Media . " \
- "?urn tracker:available ?tr . " \
- "?urn fts:match '*%s*' . " \
- "%s " \
- "} " \
- "ORDER BY DESC(nfo:fileLastModified(?urn)) " \
- "OFFSET %i " \
- "LIMIT %i"
-
-#define TRACKER_SEARCH_ALL_REQUEST \
- "SELECT rdf:type(?urn) %s " \
- "WHERE " \
- "{ " \
- "?urn a nfo:Media . " \
- "?urn tracker:available ?tr . " \
- "%s " \
- "} " \
- "ORDER BY DESC(nfo:fileLastModified(?urn)) " \
- "OFFSET %i " \
- "LIMIT %i"
-
-#define TRACKER_BROWSE_CATEGORY_REQUEST \
- "SELECT rdf:type(?urn) %s " \
- "WHERE " \
- "{ " \
- "?urn a %s . " \
- "?urn tracker:available ?tr . " \
- "%s " \
- "} " \
- "ORDER BY DESC(nfo:fileLastModified(?urn)) " \
- "OFFSET %i " \
- "LIMIT %i"
-
-#define TRACKER_BROWSE_FILESYSTEM_ROOT_REQUEST \
- "SELECT DISTINCT rdf:type(?urn) %s " \
- "WHERE " \
- "{ " \
- "{ ?urn a nfo:Folder } UNION " \
- "{ ?urn a nfo:Audio } UNION " \
- "{ ?urn a nfo:Document } UNION " \
- "{ ?urn a nmm:Photo } UNION " \
- "{ ?urn a nmm:Video } . " \
- "%s " \
- "FILTER (!bound(nfo:belongsToContainer(?urn))) " \
- "} " \
- "ORDER BY DESC(nfo:fileLastModified(?urn)) " \
- "OFFSET %i " \
- "LIMIT %i"
-
-#define TRACKER_BROWSE_FILESYSTEM_REQUEST \
- "SELECT DISTINCT rdf:type(?urn) %s " \
- "WHERE " \
- "{ " \
- "{ ?urn a nfo:Folder } UNION " \
- "{ ?urn a nfo:Audio } UNION " \
- "{ ?urn a nfo:Document } UNION " \
- "{ ?urn a nmm:Photo } UNION " \
- "{ ?urn a nmm:Video } . " \
- "%s " \
- "FILTER(tracker:id(nfo:belongsToContainer(?urn)) = %s) " \
- "} " \
- "ORDER BY DESC(nfo:fileLastModified(?urn)) " \
- "OFFSET %i " \
- "LIMIT %i"
-
-#define TRACKER_METADATA_REQUEST \
- "SELECT %s " \
- "WHERE " \
- "{ " \
- "?urn a nie:DataObject . " \
- "FILTER (tracker:id(?urn) = %s) " \
- "}"
-
-/**/
-
-struct OperationSpec {
- GrlMediaSource *source;
- GrlTrackerSourcePriv *priv;
- guint operation_id;
- GCancellable *cancel_op;
- const GList *keys;
- guint skip;
- guint count;
- guint current;
- GrlMediaSourceResultCb callback;
- gpointer user_data;
- TrackerSparqlCursor *cursor;
-};
-
-/**/
-
-static GrlKeyID grl_metadata_key_tracker_category;
-
-/**/
-
-static struct OperationSpec *
-tracker_operation_initiate (GrlMediaSource *source,
- GrlTrackerSourcePriv *priv,
- guint operation_id)
-{
- struct OperationSpec *os = g_slice_new0 (struct OperationSpec);
-
- os->source = source;
- os->priv = priv;
- os->operation_id = operation_id;
- os->cancel_op = g_cancellable_new ();
-
- g_hash_table_insert (priv->operations, GSIZE_TO_POINTER (operation_id), os);
-
- return os;
-}
-
-static void
-tracker_operation_terminate (struct OperationSpec *os)
-{
- if (os == NULL)
- return;
-
- g_hash_table_remove (os->priv->operations,
- GSIZE_TO_POINTER (os->operation_id));
-
- g_object_unref (G_OBJECT (os->cursor));
- g_object_unref (G_OBJECT (os->cancel_op));
- g_slice_free (struct OperationSpec, os);
-}
-
-static void
-fill_grilo_media_from_sparql (GrlTrackerSource *source,
- GrlMedia *media,
- TrackerSparqlCursor *cursor,
- gint column)
-{
- const gchar *sparql_key = tracker_sparql_cursor_get_variable_name (cursor,
- column);
- tracker_grl_sparql_t *assoc =
- grl_tracker_get_mapping_from_sparql (sparql_key);
- union {
- gint int_val;
- gdouble double_val;
- const gchar *str_val;
- } val;
-
- if (assoc == NULL)
- return;
-
- GRL_ODEBUG ("\tSetting media prop (col=%i/var=%s/prop=%s) %s",
- column,
- sparql_key,
- g_param_spec_get_name (G_PARAM_SPEC (assoc->grl_key)),
- tracker_sparql_cursor_get_string (cursor, column, NULL));
-
- if (tracker_sparql_cursor_is_bound (cursor, column) == FALSE) {
- GRL_ODEBUG ("\t\tDropping, no data");
- return;
- }
-
- if (grl_data_key_is_known (GRL_DATA (media), assoc->grl_key)) {
- GRL_ODEBUG ("\t\tDropping, already here");
- return;
- }
-
- switch (G_PARAM_SPEC (assoc->grl_key)->value_type) {
- case G_TYPE_STRING:
- /* Cache the source associated to this result. */
- if (assoc->grl_key == GRL_METADATA_KEY_ID) {
- grl_tracker_cache_add_item (grl_tracker_item_cache,
- tracker_sparql_cursor_get_integer (cursor, column),
- source);
- }
- val.str_val = tracker_sparql_cursor_get_string (cursor, column, NULL);
- if (val.str_val != NULL)
- grl_data_set_string (GRL_DATA (media), assoc->grl_key, val.str_val);
- break;
-
- case G_TYPE_INT:
- val.int_val = tracker_sparql_cursor_get_integer (cursor, column);
- grl_data_set_int (GRL_DATA (media), assoc->grl_key, val.int_val);
- break;
-
- case G_TYPE_FLOAT:
- val.double_val = tracker_sparql_cursor_get_double (cursor, column);
- grl_data_set_float (GRL_DATA (media), assoc->grl_key, (gfloat) val.double_val);
- break;
-
- default:
- GRL_ODEBUG ("\t\tUnexpected data type");
- break;
- }
-}
-
-static void
-tracker_query_result_cb (GObject *source_object,
- GAsyncResult *result,
- struct OperationSpec *operation)
-{
- gint col;
- const gchar *sparql_type;
- GError *tracker_error = NULL, *error = NULL;
- GrlMedia *media;
-
- GRL_ODEBUG ("%s", __FUNCTION__);
-
- if (g_cancellable_is_cancelled (operation->cancel_op)) {
- GRL_ODEBUG ("\tOperation %u cancelled", operation->operation_id);
- operation->callback (operation->source,
- operation->operation_id,
- NULL, 0,
- operation->user_data, NULL);
- tracker_operation_terminate (operation);
-
- return;
- }
-
- if (!tracker_sparql_cursor_next_finish (operation->cursor,
- result,
- &tracker_error)) {
- if (tracker_error != NULL) {
- GRL_ODEBUG ("\terror in parsing query id=%u : %s",
- operation->operation_id, tracker_error->message);
-
- error = g_error_new (GRL_CORE_ERROR,
- GRL_CORE_ERROR_BROWSE_FAILED,
- "Failed to start browse/query action : %s",
- tracker_error->message);
-
- operation->callback (operation->source,
- operation->operation_id,
- NULL, 0,
- operation->user_data, error);
-
- g_error_free (error);
- g_error_free (tracker_error);
- } else {
- GRL_ODEBUG ("\tend of parsing id=%u :)", operation->operation_id);
-
- /* Only emit this last one if more result than expected */
- if (operation->count > 1)
- operation->callback (operation->source,
- operation->operation_id,
- NULL, 0,
- operation->user_data, NULL);
- }
-
- tracker_operation_terminate (operation);
- return;
- }
-
- sparql_type = tracker_sparql_cursor_get_string (operation->cursor, 0, NULL);
-
- GRL_ODEBUG ("\tParsing line %i of type %s", operation->current, sparql_type);
-
- media = grl_tracker_build_grilo_media (sparql_type);
-
- if (media != NULL) {
- for (col = 1 ;
- col < tracker_sparql_cursor_get_n_columns (operation->cursor) ;
- col++) {
- fill_grilo_media_from_sparql (GRL_TRACKER_SOURCE (operation->source),
- media, operation->cursor, col);
- }
-
- operation->callback (operation->source,
- operation->operation_id,
- media,
- --operation->count,
- operation->user_data,
- NULL);
- }
-
- /* Schedule the next line to parse */
- operation->current++;
- if (operation->count < 1)
- tracker_operation_terminate (operation);
- else
- tracker_sparql_cursor_next_async (operation->cursor, operation->cancel_op,
- (GAsyncReadyCallback) tracker_query_result_cb,
- (gpointer) operation);
-}
-
-static void
-tracker_query_cb (GObject *source_object,
- GAsyncResult *result,
- struct OperationSpec *operation)
-{
- GError *tracker_error = NULL, *error = NULL;
-
- GRL_ODEBUG ("%s", __FUNCTION__);
-
- operation->cursor =
- tracker_sparql_connection_query_finish (operation->priv->tracker_connection,
- result, &tracker_error);
-
- if (tracker_error) {
- GRL_WARNING ("Could not execute sparql query id=%u: %s",
- operation->operation_id, tracker_error->message);
-
- error = g_error_new (GRL_CORE_ERROR,
- GRL_CORE_ERROR_BROWSE_FAILED,
- "Failed to start browse/query action : %s",
- tracker_error->message);
-
- operation->callback (operation->source, operation->operation_id, NULL, 0,
- operation->user_data, error);
-
- g_error_free (tracker_error);
- g_error_free (error);
- g_slice_free (struct OperationSpec, operation);
-
- return;
- }
-
- /* Start parsing results */
- operation->current = 0;
- tracker_sparql_cursor_next_async (operation->cursor, NULL,
- (GAsyncReadyCallback) tracker_query_result_cb,
- (gpointer) operation);
-}
-
-static void
-tracker_metadata_cb (GObject *source_object,
- GAsyncResult *result,
- GrlMediaSourceMetadataSpec *ms)
-{
- GrlTrackerSourcePriv *priv = GRL_TRACKER_SOURCE_GET_PRIVATE (ms->source);
- gint col;
- GError *tracker_error = NULL, *error = NULL;
- TrackerSparqlCursor *cursor;
-
- GRL_ODEBUG ("%s", __FUNCTION__);
-
- cursor = tracker_sparql_connection_query_finish (priv->tracker_connection,
- result, &tracker_error);
-
- if (tracker_error) {
- GRL_WARNING ("Could not execute sparql query id=%u : %s",
- ms->metadata_id, tracker_error->message);
-
- error = g_error_new (GRL_CORE_ERROR,
- GRL_CORE_ERROR_BROWSE_FAILED,
- "Failed to start metadata action : %s",
- tracker_error->message);
-
- ms->callback (ms->source, NULL, ms->user_data, error);
-
- g_error_free (tracker_error);
- g_error_free (error);
-
- goto end_operation;
- }
-
-
- tracker_sparql_cursor_next (cursor, NULL, NULL);
-
- /* Translate Sparql result into Grilo result */
- for (col = 0 ; col < tracker_sparql_cursor_get_n_columns (cursor) ; col++) {
- fill_grilo_media_from_sparql (GRL_TRACKER_SOURCE (ms->source),
- ms->media, cursor, col);
- }
-
- ms->callback (ms->source, ms->media, ms->user_data, NULL);
-
- end_operation:
- if (cursor)
- g_object_unref (G_OBJECT (cursor));
-}
-
-/**/
-
-const GList *
-grl_tracker_source_supported_keys (GrlMetadataSource *source)
-{
- return
- grl_plugin_registry_get_metadata_keys (grl_plugin_registry_get_default ());
-}
-
-/**
- * Query is a SPARQL query.
- *
- * Columns must be named with the Grilo key name that the column
- * represent. Unnamed or unknown columns will be ignored.
- *
- * First column must be the media type, and it does not need to be named. It
- * must match with any value supported in rdf:type() property, or
- * grilo#Box. Types understood are:
- *
- * <itemizedlist>
- * <listitem>
- * <para>
- * <literal>nmm#MusicPiece</literal>
- * </para>
- * </listitem>
- * <listitem>
- * <para>
- * <literal>nmm#Video</literal>
- * </para>
- * </listitem>
- * <listitem>
- * <para>
- * <literal>nmm#Photo</literal>
- * </para>
- * </listitem>
- * <listitem>
- * <para>
- * <literal>nmm#Artist</literal>
- * </para>
- * </listitem>
- * <listitem>
- * <para>
- * <literal>nmm#MusicAlbum</literal>
- * </para>
- * </listitem>
- * <listitem>
- * <para>
- * <literal>grilo#Box</literal>
- * </para>
- * </listitem>
- * </itemizedlist>
- *
- * An example for searching all songs:
- *
- * <informalexample>
- * <programlisting>
- * SELECT rdf:type(?song)
- * ?song AS id
- * nie:title(?song) AS title
- * nie:url(?song) AS url
- * WHERE { ?song a nmm:MusicPiece }
- * </programlisting>
- * </informalexample>
- *
- * Alternatively, we can use a partial SPARQL query: just specify the sentence
- * in the WHERE part. In this case, "?urn" is the ontology concept to be used in
- * the clause.
- *
- * An example of such partial query:
- *
- * <informalexample>
- * <programlisting>
- * ?urn a nfo:Media
- * </programlisting>
- * </informalexample>
- *
- * In this case, all data required to build a full SPARQL query will be get from
- * the query spec.
- */
-void
-grl_tracker_source_query (GrlMediaSource *source,
- GrlMediaSourceQuerySpec *qs)
-{
- GError *error = NULL;
- GrlTrackerSourcePriv *priv = GRL_TRACKER_SOURCE_GET_PRIVATE (source);
- gchar *constraint;
- gchar *sparql_final;
- gchar *sparql_select;
- struct OperationSpec *os;
-
- GRL_IDEBUG ("%s: id=%u", __FUNCTION__, qs->query_id);
-
- if (!qs->query || qs->query[0] == '\0') {
- error = g_error_new_literal (GRL_CORE_ERROR,
- GRL_CORE_ERROR_QUERY_FAILED,
- "Empty query");
- goto send_error;
- }
-
- /* Check if it is a full sparql query */
- if (g_ascii_strncasecmp (qs->query, "select ", 7) != 0) {
- constraint = grl_tracker_source_get_device_constraint (priv);
- sparql_select = grl_tracker_source_get_select_string (source, qs->keys);
- sparql_final = g_strdup_printf (TRACKER_QUERY_REQUEST,
- sparql_select,
- qs->query,
- constraint,
- qs->skip,
- qs->count);
- g_free (constraint);
- g_free (qs->query);
- g_free (sparql_select);
- qs->query = sparql_final;
- grl_tracker_source_query (source, qs);
- return;
- }
-
- GRL_IDEBUG ("\tselect : '%s'", qs->query);
-
- os = tracker_operation_initiate (source, priv, qs->query_id);
- os->keys = qs->keys;
- os->skip = qs->skip;
- os->count = qs->count;
- os->callback = qs->callback;
- os->user_data = qs->user_data;
-
- tracker_sparql_connection_query_async (priv->tracker_connection,
- qs->query,
- os->cancel_op,
- (GAsyncReadyCallback) tracker_query_cb,
- os);
-
- return;
-
- send_error:
- qs->callback (qs->source, qs->query_id, NULL, 0, qs->user_data, error);
- g_error_free (error);
-}
-
-void
-grl_tracker_source_metadata (GrlMediaSource *source,
- GrlMediaSourceMetadataSpec *ms)
-{
- GrlTrackerSourcePriv *priv = GRL_TRACKER_SOURCE_GET_PRIVATE (source);
- gchar *constraint = NULL, *sparql_select, *sparql_final;
-
- GRL_IDEBUG ("%s: id=%i", __FUNCTION__, ms->metadata_id);
-
- if (grl_media_get_id (ms->media) == NULL) {
- if (grl_tracker_per_device_source) {
- constraint = grl_tracker_source_get_device_constraint (priv);
- sparql_select = grl_tracker_source_get_select_string (source, ms->keys);
- sparql_final = g_strdup_printf (TRACKER_BROWSE_FILESYSTEM_ROOT_REQUEST,
- sparql_select, constraint, 0, 1);
- } else {
- ms->callback (ms->source, ms->media, ms->user_data, NULL);
- return;
- }
- } else {
- sparql_select = grl_tracker_source_get_select_string (source, ms->keys);
- sparql_final = g_strdup_printf (TRACKER_METADATA_REQUEST, sparql_select,
- grl_media_get_id (ms->media));
- }
-
- GRL_IDEBUG ("\tselect: '%s'", sparql_final);
-
- tracker_sparql_connection_query_async (priv->tracker_connection,
- sparql_final,
- NULL,
- (GAsyncReadyCallback) tracker_metadata_cb,
- ms);
-
- if (constraint != NULL)
- g_free (constraint);
- if (sparql_select != NULL)
- g_free (sparql_select);
- if (sparql_final != NULL)
- g_free (sparql_final);
-}
-
-void
-grl_tracker_source_search (GrlMediaSource *source, GrlMediaSourceSearchSpec *ss)
-{
- GrlTrackerSourcePriv *priv = GRL_TRACKER_SOURCE_GET_PRIVATE (source);
- gchar *constraint;
- gchar *sparql_select;
- gchar *sparql_final;
- struct OperationSpec *os;
-
- GRL_IDEBUG ("%s: id=%u", __FUNCTION__, ss->search_id);
-
- constraint = grl_tracker_source_get_device_constraint (priv);
- sparql_select = grl_tracker_source_get_select_string (source, ss->keys);
- if (!ss->text || ss->text[0] == '\0') {
- /* Search all */
- sparql_final = g_strdup_printf (TRACKER_SEARCH_ALL_REQUEST, sparql_select,
- constraint, ss->skip, ss->count);
- } else {
- sparql_final = g_strdup_printf (TRACKER_SEARCH_REQUEST, sparql_select,
- ss->text, constraint, ss->skip, ss->count);
- }
-
- GRL_IDEBUG ("\tselect: '%s'", sparql_final);
-
- os = tracker_operation_initiate (source, priv, ss->search_id);
- os->keys = ss->keys;
- os->skip = ss->skip;
- os->count = ss->count;
- os->callback = ss->callback;
- os->user_data = ss->user_data;
-
- tracker_sparql_connection_query_async (priv->tracker_connection,
- sparql_final,
- os->cancel_op,
- (GAsyncReadyCallback) tracker_query_cb,
- os);
-
- g_free (constraint);
- g_free (sparql_select);
- g_free (sparql_final);
-}
-
-static void
-grl_tracker_source_browse_category (GrlMediaSource *source,
- GrlMediaSourceBrowseSpec *bs)
-{
- GrlTrackerSourcePriv *priv = GRL_TRACKER_SOURCE_GET_PRIVATE (source);
- gchar *constraint;
- gchar *sparql_select;
- gchar *sparql_final;
- struct OperationSpec *os;
- GrlMedia *media;
- const gchar *category;
-
- GRL_IDEBUG ("%s: id=%u", __FUNCTION__, bs->browse_id);
-
- if (bs->container == NULL ||
- !grl_data_key_is_known (GRL_DATA (bs->container),
- grl_metadata_key_tracker_category)) {
- /* Hardcoded categories */
- media = grl_media_box_new ();
- grl_media_set_title (media, "Documents");
- grl_data_set_string (GRL_DATA (media),
- grl_metadata_key_tracker_category,
- "nfo:Document");
- bs->callback (bs->source, bs->browse_id, media, 3, bs->user_data, NULL);
-
- media = grl_media_box_new ();
- grl_media_set_title (media, "Music");
- grl_data_set_string (GRL_DATA (media),
- grl_metadata_key_tracker_category,
- "nmm:MusicPiece");
- bs->callback (bs->source, bs->browse_id, media, 2, bs->user_data, NULL);
-
- media = grl_media_box_new ();
- grl_media_set_title (media, "Photos");
- grl_data_set_string (GRL_DATA (media),
- grl_metadata_key_tracker_category,
- "nmm:Photo");
- bs->callback (bs->source, bs->browse_id, media, 1, bs->user_data, NULL);
-
- media = grl_media_box_new ();
- grl_media_set_title (media, "Videos");
- grl_data_set_string (GRL_DATA (media),
- grl_metadata_key_tracker_category,
- "nmm:Video");
- bs->callback (bs->source, bs->browse_id, media, 0, bs->user_data, NULL);
- return;
- }
-
- category = grl_data_get_string (GRL_DATA (bs->container),
- grl_metadata_key_tracker_category);
-
- constraint = grl_tracker_source_get_device_constraint (priv);
- sparql_select = grl_tracker_source_get_select_string (bs->source, bs->keys);
- sparql_final = g_strdup_printf (TRACKER_BROWSE_CATEGORY_REQUEST,
- sparql_select,
- category,
- constraint,
- bs->skip, bs->count);
-
- GRL_IDEBUG ("\tselect: '%s'", sparql_final);
-
- os = tracker_operation_initiate (source, priv, bs->browse_id);
- os->keys = bs->keys;
- 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,
- os->cancel_op,
- (GAsyncReadyCallback) tracker_query_cb,
- os);
-
- g_free (constraint);
- g_free (sparql_select);
- g_free (sparql_final);
-}
-
-static void
-grl_tracker_source_browse_filesystem (GrlMediaSource *source,
- GrlMediaSourceBrowseSpec *bs)
-{
- GrlTrackerSourcePriv *priv = GRL_TRACKER_SOURCE_GET_PRIVATE (source);
- gchar *constraint;
- gchar *sparql_select;
- gchar *sparql_final;
- struct OperationSpec *os;
-
- GRL_IDEBUG ("%s: id=%u", __FUNCTION__, bs->browse_id);
-
- sparql_select = grl_tracker_source_get_select_string (bs->source, bs->keys);
- constraint = grl_tracker_source_get_device_constraint (priv);
-
- if (bs->container == NULL ||
- !grl_media_get_id (bs->container)) {
- sparql_final = g_strdup_printf (TRACKER_BROWSE_FILESYSTEM_ROOT_REQUEST,
- sparql_select,
- constraint,
- bs->skip, bs->count);
-
- } else {
- sparql_final = g_strdup_printf (TRACKER_BROWSE_FILESYSTEM_REQUEST,
- sparql_select,
- constraint,
- grl_media_get_id (bs->container),
- bs->skip, bs->count);
- }
-
- GRL_IDEBUG ("\tselect: '%s'", sparql_final);
-
- os = tracker_operation_initiate (source, priv, bs->browse_id);
- os->keys = bs->keys;
- 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,
- os->cancel_op,
- (GAsyncReadyCallback) tracker_query_cb,
- os);
-
- g_free (constraint);
- g_free (sparql_select);
- g_free (sparql_final);
-}
-
-void
-grl_tracker_source_browse (GrlMediaSource *source,
- GrlMediaSourceBrowseSpec *bs)
-{
- if (grl_tracker_browse_filesystem)
- grl_tracker_source_browse_filesystem (source, bs);
- else
- grl_tracker_source_browse_category (source, bs);
-}
-
-void
-grl_tracker_source_cancel (GrlMediaSource *source, guint operation_id)
-{
- GrlTrackerSourcePriv *priv = GRL_TRACKER_SOURCE_GET_PRIVATE (source);
- struct OperationSpec *os;
-
- GRL_IDEBUG ("%s: id=%u", __FUNCTION__, operation_id);
-
- os = g_hash_table_lookup (priv->operations, GSIZE_TO_POINTER (operation_id));
-
- if (os != NULL)
- g_cancellable_cancel (os->cancel_op);
-}
-
-gboolean
-grl_tracker_source_change_start (GrlMediaSource *source, GError **error)
-{
- GrlTrackerSourcePriv *priv = GRL_TRACKER_SOURCE_GET_PRIVATE (source);
-
- priv->notify_changes = TRUE;
-
- return TRUE;
-}
-
-gboolean
-grl_tracker_source_change_stop (GrlMediaSource *source, GError **error)
-{
- GrlTrackerSourcePriv *priv = GRL_TRACKER_SOURCE_GET_PRIVATE (source);
-
- priv->notify_changes = FALSE;
-
- return TRUE;
-}
-
-void
-grl_tracker_init_requests (void)
-{
- grl_metadata_key_tracker_category =
- grl_plugin_registry_register_metadata_key (grl_plugin_registry_get_default (),
- g_param_spec_string ("tracker-category",
- "Tracker category",
- "Category a media belongs to",
- NULL,
- G_PARAM_STATIC_STRINGS |
- G_PARAM_READWRITE),
- NULL);
-
-
- GRL_LOG_DOMAIN_INIT (tracker_request_log_domain, "tracker-request");
- GRL_LOG_DOMAIN_INIT (tracker_result_log_domain, "tracker-result");
-}
diff --git a/src/media/tracker/grl-tracker-api.h b/src/media/tracker/grl-tracker-api.h
deleted file mode 100644
index 4e2b52b..0000000
--- a/src/media/tracker/grl-tracker-api.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2011 Intel Corporation.
- *
- * Contact: Iago Toral Quiroga <itoral igalia com>
- *
- * Authors: 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
- * 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_TRACKER_API_H_
-#define _GRL_TRACKER_API_H_
-
-#include "grl-tracker.h"
-
-/**/
-
-void grl_tracker_init_requests (void);
-
-const GList *grl_tracker_source_supported_keys (GrlMetadataSource *source);
-
-void grl_tracker_source_query (GrlMediaSource *source,
- GrlMediaSourceQuerySpec *qs);
-
-void grl_tracker_source_metadata (GrlMediaSource *source,
- GrlMediaSourceMetadataSpec *ms);
-
-void grl_tracker_source_search (GrlMediaSource *source,
- GrlMediaSourceSearchSpec *ss);
-
-void grl_tracker_source_browse (GrlMediaSource *source,
- GrlMediaSourceBrowseSpec *bs);
-
-void grl_tracker_source_cancel (GrlMediaSource *source, guint operation_id);
-
-gboolean grl_tracker_source_change_start (GrlMediaSource *source,
- GError **error);
-
-gboolean grl_tracker_source_change_stop (GrlMediaSource *source,
- GError **error);
-
-#endif /* _GRL_TRACKER_API_H_ */
diff --git a/src/media/tracker/grl-tracker-cache.c b/src/media/tracker/grl-tracker-cache.c
deleted file mode 100644
index e5801e7..0000000
--- a/src/media/tracker/grl-tracker-cache.c
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Copyright (C) 2011 Intel Corporation.
- *
- * Contact: Iago Toral Quiroga <itoral igalia com>
- *
- * Authors: 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
- * 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
- *
- */
-
-#include <glib.h>
-
-#include "grl-tracker-cache.h"
-
-typedef struct {
- GrlTrackerSource *source;
-
- GHashTable *id_table;
-} GrlTrackerCacheSource;
-
-struct _GrlTrackerCache {
- gsize size_limit;
- gsize size_current;
-
- GHashTable *id_table;
- GHashTable *source_table;
- GList *id_list;
-};
-
-static GrlTrackerCacheSource *
-grl_tracker_cache_source_new (GrlTrackerSource *source)
-{
- GrlTrackerCacheSource *csource = g_slice_new0 (GrlTrackerCacheSource);
-
- csource->source = source;
- csource->id_table = g_hash_table_new (g_direct_hash, g_direct_equal);
-
- return csource;
-}
-
-static void
-grl_tracker_cache_source_free (GrlTrackerCacheSource *csource)
-{
- g_hash_table_destroy (csource->id_table);
-
- g_slice_free (GrlTrackerCacheSource, csource);
-}
-
-/**/
-
-GrlTrackerCache *
-grl_tracker_cache_new (gsize size)
-{
- GrlTrackerCache *cache;
-
- g_return_val_if_fail (size > 0, NULL);
-
- cache = g_slice_new0 (GrlTrackerCache);
-
- if (!cache)
- return NULL;
-
- cache->size_limit = size;
- cache->id_table = g_hash_table_new (g_direct_hash, g_direct_equal);
- cache->source_table = g_hash_table_new (g_direct_hash, g_direct_equal);
-
- return cache;
-}
-
-void
-grl_tracker_cache_free (GrlTrackerCache *cache)
-{
- GHashTableIter iter;
- gpointer key, value;
-
- g_return_if_fail (cache != NULL);
-
- g_hash_table_iter_init (&iter, cache->source_table);
- while (g_hash_table_iter_next (&iter, &key, &value)) {
- grl_tracker_cache_del_source (cache, key);
- }
-
- if (cache->id_list) {
- g_warning ("Memleak detected");
- g_list_free (cache->id_list);
- }
- g_hash_table_destroy (cache->id_table);
- g_hash_table_destroy (cache->source_table);
-
- g_slice_free (GrlTrackerCache, cache);
-}
-
-void
-grl_tracker_cache_add_item (GrlTrackerCache *cache,
- guint id,
- GrlTrackerSource *source)
-{
- GList *lid;
- GrlTrackerCacheSource *csource;
-
- g_return_if_fail (cache != NULL);
-
- if (g_hash_table_lookup (cache->id_table, GSIZE_TO_POINTER (id)) != NULL)
- return; /* TODO: is it worth to have an LRU ? */
-
- csource = g_hash_table_lookup (cache->source_table, source);
-
- if (!csource) {
- csource = grl_tracker_cache_source_new (source);
- g_hash_table_insert (cache->source_table, source, csource);
- }
-
- if (cache->size_current >= cache->size_limit) {
- lid = g_list_last (cache->id_list); /* TODO: optimize that ! */
- g_hash_table_remove (cache->id_table, lid->data);
- cache->id_list = g_list_remove_link (cache->id_list, lid);
-
- lid->data = GSIZE_TO_POINTER (id);
- lid->next = cache->id_list;
- cache->id_list->prev = lid;
- cache->id_list = lid;
- } else {
- cache->id_list = g_list_prepend (cache->id_list, GSIZE_TO_POINTER (id));
- cache->size_current++;
- }
-
- g_hash_table_insert (cache->id_table, GSIZE_TO_POINTER (id), csource);
- g_hash_table_insert (csource->id_table, GSIZE_TO_POINTER (id),
- cache->id_list);
-}
-
-void
-grl_tracker_cache_del_source (GrlTrackerCache *cache,
- GrlTrackerSource *source)
-{
- GrlTrackerCacheSource *csource;
- GHashTableIter iter;
- gpointer key, value;
-
- g_return_if_fail (cache != NULL);
- g_return_if_fail (source != NULL);
-
- csource = g_hash_table_lookup (cache->source_table, source);
-
- if (!csource)
- return;
-
- g_hash_table_iter_init (&iter, csource->id_table);
-
- while (g_hash_table_iter_next (&iter, &key, &value)) {
- g_hash_table_remove (cache->id_table, key);
- cache->id_list = g_list_delete_link (cache->id_list, value);
- }
-
- g_hash_table_remove (cache->source_table, source);
- grl_tracker_cache_source_free (csource);
-}
-
-GrlTrackerSource *
-grl_tracker_cache_get_source (GrlTrackerCache *cache, guint id)
-{
- GrlTrackerCacheSource *csource;
-
- g_return_val_if_fail (cache != NULL, NULL);
-
- csource = (GrlTrackerCacheSource *) g_hash_table_lookup (cache->id_table,
- GSIZE_TO_POINTER (id));
-
- if (csource) {
- return csource->source;
- }
-
- return NULL;
-}
diff --git a/src/media/tracker/grl-tracker-cache.h b/src/media/tracker/grl-tracker-cache.h
deleted file mode 100644
index ad07865..0000000
--- a/src/media/tracker/grl-tracker-cache.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2011 Intel Corporation.
- *
- * Contact: Iago Toral Quiroga <itoral igalia com>
- *
- * Authors: 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
- * 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_TRACKER_CACHE_H_
-#define _GRL_TRACKER_CACHE_H_
-
-#include "grl-tracker.h"
-
-typedef struct _GrlTrackerCache GrlTrackerCache;
-
-GrlTrackerCache *grl_tracker_cache_new (gsize size);
-
-void grl_tracker_cache_free (GrlTrackerCache *cache);
-
-void grl_tracker_cache_add_item (GrlTrackerCache *cache,
- guint id,
- GrlTrackerSource *source);
-void grl_tracker_cache_del_source (GrlTrackerCache *cache,
- GrlTrackerSource *source);
-
-GrlTrackerSource *grl_tracker_cache_get_source (GrlTrackerCache *cache,
- guint id);
-
-#endif /* _GRL_TRACKER_CACHE_H_ */
diff --git a/src/media/tracker/grl-tracker-media-api.c b/src/media/tracker/grl-tracker-media-api.c
new file mode 100644
index 0000000..7b803ec
--- /dev/null
+++ b/src/media/tracker/grl-tracker-media-api.c
@@ -0,0 +1,841 @@
+/*
+ * Copyright (C) 2011 Intel Corporation.
+ *
+ * Contact: Iago Toral Quiroga <itoral igalia com>
+ *
+ * Authors: 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
+ * 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
+ *
+ */
+
+#include <gio/gio.h>
+#include <tracker-sparql.h>
+
+#include "grl-tracker-media-api.h"
+#include "grl-tracker-media-cache.h"
+#include "grl-tracker-media-priv.h"
+#include "grl-tracker-utils.h"
+
+/* --------- Logging -------- */
+
+#define GRL_LOG_DOMAIN_DEFAULT tracker_request_log_domain
+
+GRL_LOG_DOMAIN_STATIC(tracker_request_log_domain);
+GRL_LOG_DOMAIN_STATIC(tracker_result_log_domain);
+
+/* Inputs/requests */
+#define GRL_IDEBUG(args...) \
+ GRL_LOG (tracker_request_log_domain, \
+ GRL_LOG_LEVEL_DEBUG, args)
+
+/* Outputs/results */
+#define GRL_ODEBUG(args...) \
+ GRL_LOG (tracker_result_log_domain, \
+ GRL_LOG_LEVEL_DEBUG, args)
+
+/* ------- Definitions ------- */
+
+#define TRACKER_QUERY_REQUEST \
+ "SELECT rdf:type(?urn) %s " \
+ "WHERE { %s . %s } " \
+ "ORDER BY DESC(nfo:fileLastModified(?urn)) " \
+ "OFFSET %i " \
+ "LIMIT %i"
+
+#define TRACKER_SEARCH_REQUEST \
+ "SELECT rdf:type(?urn) %s " \
+ "WHERE " \
+ "{ " \
+ "?urn a nfo:Media . " \
+ "?urn tracker:available ?tr . " \
+ "?urn fts:match '*%s*' . " \
+ "%s " \
+ "} " \
+ "ORDER BY DESC(nfo:fileLastModified(?urn)) " \
+ "OFFSET %i " \
+ "LIMIT %i"
+
+#define TRACKER_SEARCH_ALL_REQUEST \
+ "SELECT rdf:type(?urn) %s " \
+ "WHERE " \
+ "{ " \
+ "?urn a nfo:Media . " \
+ "?urn tracker:available ?tr . " \
+ "%s " \
+ "} " \
+ "ORDER BY DESC(nfo:fileLastModified(?urn)) " \
+ "OFFSET %i " \
+ "LIMIT %i"
+
+#define TRACKER_BROWSE_CATEGORY_REQUEST \
+ "SELECT rdf:type(?urn) %s " \
+ "WHERE " \
+ "{ " \
+ "?urn a %s . " \
+ "?urn tracker:available ?tr . " \
+ "%s " \
+ "} " \
+ "ORDER BY DESC(nfo:fileLastModified(?urn)) " \
+ "OFFSET %i " \
+ "LIMIT %i"
+
+#define TRACKER_BROWSE_FILESYSTEM_ROOT_REQUEST \
+ "SELECT DISTINCT rdf:type(?urn) %s " \
+ "WHERE " \
+ "{ " \
+ "{ ?urn a nfo:Folder } UNION " \
+ "{ ?urn a nfo:Audio } UNION " \
+ "{ ?urn a nfo:Document } UNION " \
+ "{ ?urn a nmm:Photo } UNION " \
+ "{ ?urn a nmm:Video } . " \
+ "%s " \
+ "FILTER (!bound(nfo:belongsToContainer(?urn))) " \
+ "} " \
+ "ORDER BY DESC(nfo:fileLastModified(?urn)) " \
+ "OFFSET %i " \
+ "LIMIT %i"
+
+#define TRACKER_BROWSE_FILESYSTEM_REQUEST \
+ "SELECT DISTINCT rdf:type(?urn) %s " \
+ "WHERE " \
+ "{ " \
+ "{ ?urn a nfo:Folder } UNION " \
+ "{ ?urn a nfo:Audio } UNION " \
+ "{ ?urn a nfo:Document } UNION " \
+ "{ ?urn a nmm:Photo } UNION " \
+ "{ ?urn a nmm:Video } . " \
+ "%s " \
+ "FILTER(tracker:id(nfo:belongsToContainer(?urn)) = %s) " \
+ "} " \
+ "ORDER BY DESC(nfo:fileLastModified(?urn)) " \
+ "OFFSET %i " \
+ "LIMIT %i"
+
+#define TRACKER_METADATA_REQUEST \
+ "SELECT %s " \
+ "WHERE " \
+ "{ " \
+ "?urn a nie:DataObject . " \
+ "FILTER (tracker:id(?urn) = %s) " \
+ "}"
+
+/**/
+
+struct OperationSpec {
+ GrlMediaSource *source;
+ GrlTrackerMediaPriv *priv;
+ guint operation_id;
+ GCancellable *cancel_op;
+ const GList *keys;
+ guint skip;
+ guint count;
+ guint current;
+ GrlMediaSourceResultCb callback;
+ gpointer user_data;
+ TrackerSparqlCursor *cursor;
+};
+
+/**/
+
+static GrlKeyID grl_metadata_key_tracker_category;
+
+/**/
+
+static struct OperationSpec *
+tracker_operation_initiate (GrlMediaSource *source,
+ GrlTrackerMediaPriv *priv,
+ guint operation_id)
+{
+ struct OperationSpec *os = g_slice_new0 (struct OperationSpec);
+
+ os->source = source;
+ os->priv = priv;
+ os->operation_id = operation_id;
+ os->cancel_op = g_cancellable_new ();
+
+ g_hash_table_insert (priv->operations, GSIZE_TO_POINTER (operation_id), os);
+
+ return os;
+}
+
+static void
+tracker_operation_terminate (struct OperationSpec *os)
+{
+ if (os == NULL)
+ return;
+
+ g_hash_table_remove (os->priv->operations,
+ GSIZE_TO_POINTER (os->operation_id));
+
+ g_object_unref (G_OBJECT (os->cursor));
+ g_object_unref (G_OBJECT (os->cancel_op));
+ g_slice_free (struct OperationSpec, os);
+}
+
+static void
+fill_grilo_media_from_sparql (GrlTrackerMedia *source,
+ GrlMedia *media,
+ TrackerSparqlCursor *cursor,
+ gint column)
+{
+ const gchar *sparql_key = tracker_sparql_cursor_get_variable_name (cursor,
+ column);
+ tracker_grl_sparql_t *assoc =
+ grl_tracker_get_mapping_from_sparql (sparql_key);
+ union {
+ gint int_val;
+ gdouble double_val;
+ const gchar *str_val;
+ } val;
+
+ if (assoc == NULL)
+ return;
+
+ GRL_ODEBUG ("\tSetting media prop (col=%i/var=%s/prop=%s) %s",
+ column,
+ sparql_key,
+ g_param_spec_get_name (G_PARAM_SPEC (assoc->grl_key)),
+ tracker_sparql_cursor_get_string (cursor, column, NULL));
+
+ if (tracker_sparql_cursor_is_bound (cursor, column) == FALSE) {
+ GRL_ODEBUG ("\t\tDropping, no data");
+ return;
+ }
+
+ if (grl_data_key_is_known (GRL_DATA (media), assoc->grl_key)) {
+ GRL_ODEBUG ("\t\tDropping, already here");
+ return;
+ }
+
+ switch (G_PARAM_SPEC (assoc->grl_key)->value_type) {
+ case G_TYPE_STRING:
+ /* Cache the source associated to this result. */
+ if (assoc->grl_key == GRL_METADATA_KEY_ID) {
+ grl_tracker_media_cache_add_item (grl_tracker_item_cache,
+ tracker_sparql_cursor_get_integer (cursor,
+ column),
+ source);
+ }
+ val.str_val = tracker_sparql_cursor_get_string (cursor, column, NULL);
+ if (val.str_val != NULL)
+ grl_data_set_string (GRL_DATA (media), assoc->grl_key, val.str_val);
+ break;
+
+ case G_TYPE_INT:
+ val.int_val = tracker_sparql_cursor_get_integer (cursor, column);
+ grl_data_set_int (GRL_DATA (media), assoc->grl_key, val.int_val);
+ break;
+
+ case G_TYPE_FLOAT:
+ val.double_val = tracker_sparql_cursor_get_double (cursor, column);
+ grl_data_set_float (GRL_DATA (media), assoc->grl_key, (gfloat) val.double_val);
+ break;
+
+ default:
+ GRL_ODEBUG ("\t\tUnexpected data type");
+ break;
+ }
+}
+
+static void
+tracker_query_result_cb (GObject *source_object,
+ GAsyncResult *result,
+ struct OperationSpec *operation)
+{
+ gint col;
+ const gchar *sparql_type;
+ GError *tracker_error = NULL, *error = NULL;
+ GrlMedia *media;
+
+ GRL_ODEBUG ("%s", __FUNCTION__);
+
+ if (g_cancellable_is_cancelled (operation->cancel_op)) {
+ GRL_ODEBUG ("\tOperation %u cancelled", operation->operation_id);
+ operation->callback (operation->source,
+ operation->operation_id,
+ NULL, 0,
+ operation->user_data, NULL);
+ tracker_operation_terminate (operation);
+
+ return;
+ }
+
+ if (!tracker_sparql_cursor_next_finish (operation->cursor,
+ result,
+ &tracker_error)) {
+ if (tracker_error != NULL) {
+ GRL_ODEBUG ("\terror in parsing query id=%u : %s",
+ operation->operation_id, tracker_error->message);
+
+ error = g_error_new (GRL_CORE_ERROR,
+ GRL_CORE_ERROR_BROWSE_FAILED,
+ "Failed to start browse/query action : %s",
+ tracker_error->message);
+
+ operation->callback (operation->source,
+ operation->operation_id,
+ NULL, 0,
+ operation->user_data, error);
+
+ g_error_free (error);
+ g_error_free (tracker_error);
+ } else {
+ GRL_ODEBUG ("\tend of parsing id=%u :)", operation->operation_id);
+
+ /* Only emit this last one if more result than expected */
+ if (operation->count > 1)
+ operation->callback (operation->source,
+ operation->operation_id,
+ NULL, 0,
+ operation->user_data, NULL);
+ }
+
+ tracker_operation_terminate (operation);
+ return;
+ }
+
+ sparql_type = tracker_sparql_cursor_get_string (operation->cursor, 0, NULL);
+
+ GRL_ODEBUG ("\tParsing line %i of type %s", operation->current, sparql_type);
+
+ media = grl_tracker_build_grilo_media (sparql_type);
+
+ if (media != NULL) {
+ for (col = 1 ;
+ col < tracker_sparql_cursor_get_n_columns (operation->cursor) ;
+ col++) {
+ fill_grilo_media_from_sparql (GRL_TRACKER_MEDIA (operation->source),
+ media, operation->cursor, col);
+ }
+
+ operation->callback (operation->source,
+ operation->operation_id,
+ media,
+ --operation->count,
+ operation->user_data,
+ NULL);
+ }
+
+ /* Schedule the next line to parse */
+ operation->current++;
+ if (operation->count < 1)
+ tracker_operation_terminate (operation);
+ else
+ tracker_sparql_cursor_next_async (operation->cursor, operation->cancel_op,
+ (GAsyncReadyCallback) tracker_query_result_cb,
+ (gpointer) operation);
+}
+
+static void
+tracker_query_cb (GObject *source_object,
+ GAsyncResult *result,
+ struct OperationSpec *operation)
+{
+ GError *tracker_error = NULL, *error = NULL;
+
+ GRL_ODEBUG ("%s", __FUNCTION__);
+
+ operation->cursor =
+ tracker_sparql_connection_query_finish (operation->priv->tracker_connection,
+ result, &tracker_error);
+
+ if (tracker_error) {
+ GRL_WARNING ("Could not execute sparql query id=%u: %s",
+ operation->operation_id, tracker_error->message);
+
+ error = g_error_new (GRL_CORE_ERROR,
+ GRL_CORE_ERROR_BROWSE_FAILED,
+ "Failed to start browse/query action : %s",
+ tracker_error->message);
+
+ operation->callback (operation->source, operation->operation_id, NULL, 0,
+ operation->user_data, error);
+
+ g_error_free (tracker_error);
+ g_error_free (error);
+ g_slice_free (struct OperationSpec, operation);
+
+ return;
+ }
+
+ /* Start parsing results */
+ operation->current = 0;
+ tracker_sparql_cursor_next_async (operation->cursor, NULL,
+ (GAsyncReadyCallback) tracker_query_result_cb,
+ (gpointer) operation);
+}
+
+static void
+tracker_metadata_cb (GObject *source_object,
+ GAsyncResult *result,
+ GrlMediaSourceMetadataSpec *ms)
+{
+ GrlTrackerMediaPriv *priv = GRL_TRACKER_MEDIA_GET_PRIVATE (ms->source);
+ gint col;
+ GError *tracker_error = NULL, *error = NULL;
+ TrackerSparqlCursor *cursor;
+
+ GRL_ODEBUG ("%s", __FUNCTION__);
+
+ cursor = tracker_sparql_connection_query_finish (priv->tracker_connection,
+ result, &tracker_error);
+
+ if (tracker_error) {
+ GRL_WARNING ("Could not execute sparql query id=%u : %s",
+ ms->metadata_id, tracker_error->message);
+
+ error = g_error_new (GRL_CORE_ERROR,
+ GRL_CORE_ERROR_BROWSE_FAILED,
+ "Failed to start metadata action : %s",
+ tracker_error->message);
+
+ ms->callback (ms->source, NULL, ms->user_data, error);
+
+ g_error_free (tracker_error);
+ g_error_free (error);
+
+ goto end_operation;
+ }
+
+
+ tracker_sparql_cursor_next (cursor, NULL, NULL);
+
+ /* Translate Sparql result into Grilo result */
+ for (col = 0 ; col < tracker_sparql_cursor_get_n_columns (cursor) ; col++) {
+ fill_grilo_media_from_sparql (GRL_TRACKER_MEDIA (ms->source),
+ ms->media, cursor, col);
+ }
+
+ ms->callback (ms->source, ms->media, ms->user_data, NULL);
+
+ end_operation:
+ if (cursor)
+ g_object_unref (G_OBJECT (cursor));
+}
+
+/**/
+
+const GList *
+grl_tracker_media_supported_keys (GrlMetadataSource *source)
+{
+ return
+ grl_plugin_registry_get_metadata_keys (grl_plugin_registry_get_default ());
+}
+
+/**
+ * Query is a SPARQL query.
+ *
+ * Columns must be named with the Grilo key name that the column
+ * represent. Unnamed or unknown columns will be ignored.
+ *
+ * First column must be the media type, and it does not need to be named. It
+ * must match with any value supported in rdf:type() property, or
+ * grilo#Box. Types understood are:
+ *
+ * <itemizedlist>
+ * <listitem>
+ * <para>
+ * <literal>nmm#MusicPiece</literal>
+ * </para>
+ * </listitem>
+ * <listitem>
+ * <para>
+ * <literal>nmm#Video</literal>
+ * </para>
+ * </listitem>
+ * <listitem>
+ * <para>
+ * <literal>nmm#Photo</literal>
+ * </para>
+ * </listitem>
+ * <listitem>
+ * <para>
+ * <literal>nmm#Artist</literal>
+ * </para>
+ * </listitem>
+ * <listitem>
+ * <para>
+ * <literal>nmm#MusicAlbum</literal>
+ * </para>
+ * </listitem>
+ * <listitem>
+ * <para>
+ * <literal>grilo#Box</literal>
+ * </para>
+ * </listitem>
+ * </itemizedlist>
+ *
+ * An example for searching all songs:
+ *
+ * <informalexample>
+ * <programlisting>
+ * SELECT rdf:type(?song)
+ * ?song AS id
+ * nie:title(?song) AS title
+ * nie:url(?song) AS url
+ * WHERE { ?song a nmm:MusicPiece }
+ * </programlisting>
+ * </informalexample>
+ *
+ * Alternatively, we can use a partial SPARQL query: just specify the sentence
+ * in the WHERE part. In this case, "?urn" is the ontology concept to be used in
+ * the clause.
+ *
+ * An example of such partial query:
+ *
+ * <informalexample>
+ * <programlisting>
+ * ?urn a nfo:Media
+ * </programlisting>
+ * </informalexample>
+ *
+ * In this case, all data required to build a full SPARQL query will be get from
+ * the query spec.
+ */
+void
+grl_tracker_media_query (GrlMediaSource *source,
+ GrlMediaSourceQuerySpec *qs)
+{
+ GError *error = NULL;
+ GrlTrackerMediaPriv *priv = GRL_TRACKER_MEDIA_GET_PRIVATE (source);
+ gchar *constraint;
+ gchar *sparql_final;
+ gchar *sparql_select;
+ struct OperationSpec *os;
+
+ GRL_IDEBUG ("%s: id=%u", __FUNCTION__, qs->query_id);
+
+ if (!qs->query || qs->query[0] == '\0') {
+ error = g_error_new_literal (GRL_CORE_ERROR,
+ GRL_CORE_ERROR_QUERY_FAILED,
+ "Empty query");
+ goto send_error;
+ }
+
+ /* Check if it is a full sparql query */
+ if (g_ascii_strncasecmp (qs->query, "select ", 7) != 0) {
+ constraint = grl_tracker_media_get_device_constraint (priv);
+ sparql_select = grl_tracker_media_get_select_string (source, qs->keys);
+ sparql_final = g_strdup_printf (TRACKER_QUERY_REQUEST,
+ sparql_select,
+ qs->query,
+ constraint,
+ qs->skip,
+ qs->count);
+ g_free (constraint);
+ g_free (qs->query);
+ g_free (sparql_select);
+ qs->query = sparql_final;
+ grl_tracker_media_query (source, qs);
+ return;
+ }
+
+ GRL_IDEBUG ("\tselect : '%s'", qs->query);
+
+ os = tracker_operation_initiate (source, priv, qs->query_id);
+ os->keys = qs->keys;
+ os->skip = qs->skip;
+ os->count = qs->count;
+ os->callback = qs->callback;
+ os->user_data = qs->user_data;
+
+ tracker_sparql_connection_query_async (priv->tracker_connection,
+ qs->query,
+ os->cancel_op,
+ (GAsyncReadyCallback) tracker_query_cb,
+ os);
+
+ return;
+
+ send_error:
+ qs->callback (qs->source, qs->query_id, NULL, 0, qs->user_data, error);
+ g_error_free (error);
+}
+
+void
+grl_tracker_media_metadata (GrlMediaSource *source,
+ GrlMediaSourceMetadataSpec *ms)
+{
+ GrlTrackerMediaPriv *priv = GRL_TRACKER_MEDIA_GET_PRIVATE (source);
+ gchar *constraint = NULL, *sparql_select, *sparql_final;
+
+ GRL_IDEBUG ("%s: id=%i", __FUNCTION__, ms->metadata_id);
+
+ if (grl_media_get_id (ms->media) == NULL) {
+ if (grl_tracker_per_device_source) {
+ constraint = grl_tracker_media_get_device_constraint (priv);
+ sparql_select = grl_tracker_media_get_select_string (source, ms->keys);
+ sparql_final = g_strdup_printf (TRACKER_BROWSE_FILESYSTEM_ROOT_REQUEST,
+ sparql_select, constraint, 0, 1);
+ } else {
+ ms->callback (ms->source, ms->media, ms->user_data, NULL);
+ return;
+ }
+ } else {
+ sparql_select = grl_tracker_media_get_select_string (source, ms->keys);
+ sparql_final = g_strdup_printf (TRACKER_METADATA_REQUEST, sparql_select,
+ grl_media_get_id (ms->media));
+ }
+
+ GRL_IDEBUG ("\tselect: '%s'", sparql_final);
+
+ tracker_sparql_connection_query_async (priv->tracker_connection,
+ sparql_final,
+ NULL,
+ (GAsyncReadyCallback) tracker_metadata_cb,
+ ms);
+
+ if (constraint != NULL)
+ g_free (constraint);
+ if (sparql_select != NULL)
+ g_free (sparql_select);
+ if (sparql_final != NULL)
+ g_free (sparql_final);
+}
+
+void
+grl_tracker_media_search (GrlMediaSource *source, GrlMediaSourceSearchSpec *ss)
+{
+ GrlTrackerMediaPriv *priv = GRL_TRACKER_MEDIA_GET_PRIVATE (source);
+ gchar *constraint;
+ gchar *sparql_select;
+ gchar *sparql_final;
+ struct OperationSpec *os;
+
+ GRL_IDEBUG ("%s: id=%u", __FUNCTION__, ss->search_id);
+
+ constraint = grl_tracker_media_get_device_constraint (priv);
+ sparql_select = grl_tracker_media_get_select_string (source, ss->keys);
+ if (!ss->text || ss->text[0] == '\0') {
+ /* Search all */
+ sparql_final = g_strdup_printf (TRACKER_SEARCH_ALL_REQUEST, sparql_select,
+ constraint, ss->skip, ss->count);
+ } else {
+ sparql_final = g_strdup_printf (TRACKER_SEARCH_REQUEST, sparql_select,
+ ss->text, constraint, ss->skip, ss->count);
+ }
+
+ GRL_IDEBUG ("\tselect: '%s'", sparql_final);
+
+ os = tracker_operation_initiate (source, priv, ss->search_id);
+ os->keys = ss->keys;
+ os->skip = ss->skip;
+ os->count = ss->count;
+ os->callback = ss->callback;
+ os->user_data = ss->user_data;
+
+ tracker_sparql_connection_query_async (priv->tracker_connection,
+ sparql_final,
+ os->cancel_op,
+ (GAsyncReadyCallback) tracker_query_cb,
+ os);
+
+ g_free (constraint);
+ g_free (sparql_select);
+ g_free (sparql_final);
+}
+
+static void
+grl_tracker_media_browse_category (GrlMediaSource *source,
+ GrlMediaSourceBrowseSpec *bs)
+{
+ GrlTrackerMediaPriv *priv = GRL_TRACKER_MEDIA_GET_PRIVATE (source);
+ gchar *constraint;
+ gchar *sparql_select;
+ gchar *sparql_final;
+ struct OperationSpec *os;
+ GrlMedia *media;
+ const gchar *category;
+
+ GRL_IDEBUG ("%s: id=%u", __FUNCTION__, bs->browse_id);
+
+ if (bs->container == NULL ||
+ !grl_data_key_is_known (GRL_DATA (bs->container),
+ grl_metadata_key_tracker_category)) {
+ /* Hardcoded categories */
+ media = grl_media_box_new ();
+ grl_media_set_title (media, "Documents");
+ grl_data_set_string (GRL_DATA (media),
+ grl_metadata_key_tracker_category,
+ "nfo:Document");
+ bs->callback (bs->source, bs->browse_id, media, 3, bs->user_data, NULL);
+
+ media = grl_media_box_new ();
+ grl_media_set_title (media, "Music");
+ grl_data_set_string (GRL_DATA (media),
+ grl_metadata_key_tracker_category,
+ "nmm:MusicPiece");
+ bs->callback (bs->source, bs->browse_id, media, 2, bs->user_data, NULL);
+
+ media = grl_media_box_new ();
+ grl_media_set_title (media, "Photos");
+ grl_data_set_string (GRL_DATA (media),
+ grl_metadata_key_tracker_category,
+ "nmm:Photo");
+ bs->callback (bs->source, bs->browse_id, media, 1, bs->user_data, NULL);
+
+ media = grl_media_box_new ();
+ grl_media_set_title (media, "Videos");
+ grl_data_set_string (GRL_DATA (media),
+ grl_metadata_key_tracker_category,
+ "nmm:Video");
+ bs->callback (bs->source, bs->browse_id, media, 0, bs->user_data, NULL);
+ return;
+ }
+
+ category = grl_data_get_string (GRL_DATA (bs->container),
+ grl_metadata_key_tracker_category);
+
+ constraint = grl_tracker_media_get_device_constraint (priv);
+ sparql_select = grl_tracker_media_get_select_string (bs->source, bs->keys);
+ sparql_final = g_strdup_printf (TRACKER_BROWSE_CATEGORY_REQUEST,
+ sparql_select,
+ category,
+ constraint,
+ bs->skip, bs->count);
+
+ GRL_IDEBUG ("\tselect: '%s'", sparql_final);
+
+ os = tracker_operation_initiate (source, priv, bs->browse_id);
+ os->keys = bs->keys;
+ 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,
+ os->cancel_op,
+ (GAsyncReadyCallback) tracker_query_cb,
+ os);
+
+ g_free (constraint);
+ g_free (sparql_select);
+ g_free (sparql_final);
+}
+
+static void
+grl_tracker_media_browse_filesystem (GrlMediaSource *source,
+ GrlMediaSourceBrowseSpec *bs)
+{
+ GrlTrackerMediaPriv *priv = GRL_TRACKER_MEDIA_GET_PRIVATE (source);
+ gchar *constraint;
+ gchar *sparql_select;
+ gchar *sparql_final;
+ struct OperationSpec *os;
+
+ GRL_IDEBUG ("%s: id=%u", __FUNCTION__, bs->browse_id);
+
+ sparql_select = grl_tracker_media_get_select_string (bs->source, bs->keys);
+ constraint = grl_tracker_media_get_device_constraint (priv);
+
+ if (bs->container == NULL ||
+ !grl_media_get_id (bs->container)) {
+ sparql_final = g_strdup_printf (TRACKER_BROWSE_FILESYSTEM_ROOT_REQUEST,
+ sparql_select,
+ constraint,
+ bs->skip, bs->count);
+
+ } else {
+ sparql_final = g_strdup_printf (TRACKER_BROWSE_FILESYSTEM_REQUEST,
+ sparql_select,
+ constraint,
+ grl_media_get_id (bs->container),
+ bs->skip, bs->count);
+ }
+
+ GRL_IDEBUG ("\tselect: '%s'", sparql_final);
+
+ os = tracker_operation_initiate (source, priv, bs->browse_id);
+ os->keys = bs->keys;
+ 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,
+ os->cancel_op,
+ (GAsyncReadyCallback) tracker_query_cb,
+ os);
+
+ g_free (constraint);
+ g_free (sparql_select);
+ g_free (sparql_final);
+}
+
+void
+grl_tracker_media_browse (GrlMediaSource *source,
+ GrlMediaSourceBrowseSpec *bs)
+{
+ if (grl_tracker_browse_filesystem)
+ grl_tracker_media_browse_filesystem (source, bs);
+ else
+ grl_tracker_media_browse_category (source, bs);
+}
+
+void
+grl_tracker_media_cancel (GrlMediaSource *source, guint operation_id)
+{
+ GrlTrackerMediaPriv *priv = GRL_TRACKER_MEDIA_GET_PRIVATE (source);
+ struct OperationSpec *os;
+
+ GRL_IDEBUG ("%s: id=%u", __FUNCTION__, operation_id);
+
+ os = g_hash_table_lookup (priv->operations, GSIZE_TO_POINTER (operation_id));
+
+ if (os != NULL)
+ g_cancellable_cancel (os->cancel_op);
+}
+
+gboolean
+grl_tracker_media_change_start (GrlMediaSource *source, GError **error)
+{
+ GrlTrackerMediaPriv *priv = GRL_TRACKER_MEDIA_GET_PRIVATE (source);
+
+ priv->notify_changes = TRUE;
+
+ return TRUE;
+}
+
+gboolean
+grl_tracker_media_change_stop (GrlMediaSource *source, GError **error)
+{
+ GrlTrackerMediaPriv *priv = GRL_TRACKER_MEDIA_GET_PRIVATE (source);
+
+ priv->notify_changes = FALSE;
+
+ return TRUE;
+}
+
+void
+grl_tracker_media_init_requests (void)
+{
+ grl_metadata_key_tracker_category =
+ grl_plugin_registry_register_metadata_key (grl_plugin_registry_get_default (),
+ g_param_spec_string ("tracker-category",
+ "Tracker category",
+ "Category a media belongs to",
+ NULL,
+ G_PARAM_STATIC_STRINGS |
+ G_PARAM_READWRITE),
+ NULL);
+
+
+ GRL_LOG_DOMAIN_INIT (tracker_request_log_domain, "tracker-request");
+ GRL_LOG_DOMAIN_INIT (tracker_result_log_domain, "tracker-result");
+}
diff --git a/src/media/tracker/grl-tracker-media-api.h b/src/media/tracker/grl-tracker-media-api.h
new file mode 100644
index 0000000..30589e0
--- /dev/null
+++ b/src/media/tracker/grl-tracker-media-api.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2011 Intel Corporation.
+ *
+ * Contact: Iago Toral Quiroga <itoral igalia com>
+ *
+ * Authors: 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
+ * 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_TRACKER_MEDIA_API_H_
+#define _GRL_TRACKER_MEDIA_API_H_
+
+#include "grl-tracker-media.h"
+
+/**/
+
+void grl_tracker_media_init_requests (void);
+
+const GList *grl_tracker_media_supported_keys (GrlMetadataSource *source);
+
+void grl_tracker_media_query (GrlMediaSource *source,
+ GrlMediaSourceQuerySpec *qs);
+
+void grl_tracker_media_metadata (GrlMediaSource *source,
+ GrlMediaSourceMetadataSpec *ms);
+
+void grl_tracker_media_search (GrlMediaSource *source,
+ GrlMediaSourceSearchSpec *ss);
+
+void grl_tracker_media_browse (GrlMediaSource *source,
+ GrlMediaSourceBrowseSpec *bs);
+
+void grl_tracker_media_cancel (GrlMediaSource *source, guint operation_id);
+
+gboolean grl_tracker_media_change_start (GrlMediaSource *source,
+ GError **error);
+
+gboolean grl_tracker_media_change_stop (GrlMediaSource *source,
+ GError **error);
+
+#endif /* _GRL_TRACKER_MEDIA_API_H_ */
diff --git a/src/media/tracker/grl-tracker-media-cache.c b/src/media/tracker/grl-tracker-media-cache.c
new file mode 100644
index 0000000..057c3ca
--- /dev/null
+++ b/src/media/tracker/grl-tracker-media-cache.c
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2011 Intel Corporation.
+ *
+ * Contact: Iago Toral Quiroga <itoral igalia com>
+ *
+ * Authors: 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
+ * 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
+ *
+ */
+
+#include <glib.h>
+
+#include "grl-tracker-media-cache.h"
+
+typedef struct {
+ GrlTrackerMedia *source;
+
+ GHashTable *id_table;
+} GrlTrackerCacheSource;
+
+struct _GrlTrackerCache {
+ gsize size_limit;
+ gsize size_current;
+
+ GHashTable *id_table;
+ GHashTable *source_table;
+ GList *id_list;
+};
+
+static GrlTrackerCacheSource *
+grl_tracker_cache_media_new (GrlTrackerMedia *source)
+{
+ GrlTrackerCacheSource *csource = g_slice_new0 (GrlTrackerCacheSource);
+
+ csource->source = source;
+ csource->id_table = g_hash_table_new (g_direct_hash, g_direct_equal);
+
+ return csource;
+}
+
+static void
+grl_tracker_cache_media_free (GrlTrackerCacheSource *csource)
+{
+ g_hash_table_destroy (csource->id_table);
+
+ g_slice_free (GrlTrackerCacheSource, csource);
+}
+
+/**/
+
+GrlTrackerCache *
+grl_tracker_media_cache_new (gsize size)
+{
+ GrlTrackerCache *cache;
+
+ g_return_val_if_fail (size > 0, NULL);
+
+ cache = g_slice_new0 (GrlTrackerCache);
+
+ if (!cache)
+ return NULL;
+
+ cache->size_limit = size;
+ cache->id_table = g_hash_table_new (g_direct_hash, g_direct_equal);
+ cache->source_table = g_hash_table_new (g_direct_hash, g_direct_equal);
+
+ return cache;
+}
+
+void
+grl_tracker_media_cache_free (GrlTrackerCache *cache)
+{
+ GHashTableIter iter;
+ gpointer key, value;
+
+ g_return_if_fail (cache != NULL);
+
+ g_hash_table_iter_init (&iter, cache->source_table);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ grl_tracker_media_cache_del_source (cache, key);
+ }
+
+ if (cache->id_list) {
+ g_warning ("Memleak detected");
+ g_list_free (cache->id_list);
+ }
+ g_hash_table_destroy (cache->id_table);
+ g_hash_table_destroy (cache->source_table);
+
+ g_slice_free (GrlTrackerCache, cache);
+}
+
+void
+grl_tracker_media_cache_add_item (GrlTrackerCache *cache,
+ guint id,
+ GrlTrackerMedia *source)
+{
+ GList *lid;
+ GrlTrackerCacheSource *csource;
+
+ g_return_if_fail (cache != NULL);
+
+ if (g_hash_table_lookup (cache->id_table, GSIZE_TO_POINTER (id)) != NULL)
+ return; /* TODO: is it worth to have an LRU ? */
+
+ csource = g_hash_table_lookup (cache->source_table, source);
+
+ if (!csource) {
+ csource = grl_tracker_cache_media_new (source);
+ g_hash_table_insert (cache->source_table, source, csource);
+ }
+
+ if (cache->size_current >= cache->size_limit) {
+ lid = g_list_last (cache->id_list); /* TODO: optimize that ! */
+ g_hash_table_remove (cache->id_table, lid->data);
+ cache->id_list = g_list_remove_link (cache->id_list, lid);
+
+ lid->data = GSIZE_TO_POINTER (id);
+ lid->next = cache->id_list;
+ cache->id_list->prev = lid;
+ cache->id_list = lid;
+ } else {
+ cache->id_list = g_list_prepend (cache->id_list, GSIZE_TO_POINTER (id));
+ cache->size_current++;
+ }
+
+ g_hash_table_insert (cache->id_table, GSIZE_TO_POINTER (id), csource);
+ g_hash_table_insert (csource->id_table, GSIZE_TO_POINTER (id),
+ cache->id_list);
+}
+
+void
+grl_tracker_media_cache_del_source (GrlTrackerCache *cache,
+ GrlTrackerMedia *source)
+{
+ GrlTrackerCacheSource *csource;
+ GHashTableIter iter;
+ gpointer key, value;
+
+ g_return_if_fail (cache != NULL);
+ g_return_if_fail (source != NULL);
+
+ csource = g_hash_table_lookup (cache->source_table, source);
+
+ if (!csource)
+ return;
+
+ g_hash_table_iter_init (&iter, csource->id_table);
+
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ g_hash_table_remove (cache->id_table, key);
+ cache->id_list = g_list_delete_link (cache->id_list, value);
+ }
+
+ g_hash_table_remove (cache->source_table, source);
+ grl_tracker_cache_media_free (csource);
+}
+
+GrlTrackerMedia *
+grl_tracker_media_cache_get_source (GrlTrackerCache *cache, guint id)
+{
+ GrlTrackerCacheSource *csource;
+
+ g_return_val_if_fail (cache != NULL, NULL);
+
+ csource = (GrlTrackerCacheSource *) g_hash_table_lookup (cache->id_table,
+ GSIZE_TO_POINTER (id));
+
+ if (csource) {
+ return csource->source;
+ }
+
+ return NULL;
+}
diff --git a/src/media/tracker/grl-tracker-media-cache.h b/src/media/tracker/grl-tracker-media-cache.h
new file mode 100644
index 0000000..1b5329e
--- /dev/null
+++ b/src/media/tracker/grl-tracker-media-cache.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2011 Intel Corporation.
+ *
+ * Contact: Iago Toral Quiroga <itoral igalia com>
+ *
+ * Authors: 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
+ * 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_TRACKER_MEDIA_CACHE_H_
+#define _GRL_TRACKER_MEDIA_CACHE_H_
+
+#include "grl-tracker-media.h"
+
+typedef struct _GrlTrackerCache GrlTrackerCache;
+
+GrlTrackerCache *grl_tracker_media_cache_new (gsize size);
+
+void grl_tracker_media_cache_free (GrlTrackerCache *cache);
+
+void grl_tracker_media_cache_add_item (GrlTrackerCache *cache,
+ guint id,
+ GrlTrackerMedia *source);
+void grl_tracker_media_cache_del_source (GrlTrackerCache *cache,
+ GrlTrackerMedia *source);
+
+GrlTrackerMedia *grl_tracker_media_cache_get_source (GrlTrackerCache *cache,
+ guint id);
+
+#endif /* _GRL_TRACKER_MEDIA_CACHE_H_ */
diff --git a/src/media/tracker/grl-tracker-media-notif.c b/src/media/tracker/grl-tracker-media-notif.c
new file mode 100644
index 0000000..409d977
--- /dev/null
+++ b/src/media/tracker/grl-tracker-media-notif.c
@@ -0,0 +1,641 @@
+/*
+ * Copyright (C) 2011 Intel Corporation.
+ *
+ * Contact: Iago Toral Quiroga <itoral igalia com>
+ *
+ * Authors: 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
+ * 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
+ *
+ */
+
+#include <tracker-sparql.h>
+
+#include "grl-tracker-media-notif.h"
+#include "grl-tracker-media-priv.h"
+#include "grl-tracker-utils.h"
+
+/* --------- Logging -------- */
+
+#define GRL_LOG_DOMAIN_DEFAULT tracker_notif_log_domain
+GRL_LOG_DOMAIN_STATIC(tracker_notif_log_domain);
+
+/* ------- Definitions ------- */
+
+#define TRACKER_MEDIA_ITEM_START \
+ "SELECT rdf:type(?urn) tracker:id(?urn) nie:dataSource(?urn) " \
+ "WHERE { ?urn a nfo:FileDataObject . " \
+ "FILTER (tracker:id(?urn) IN ("
+
+#define TRACKER_MEDIA_ITEM_END ")) }"
+
+/**/
+
+typedef struct {
+ /* tables of items for which we know the source */
+ GHashTable *inserted_items;
+ GHashTable *deleted_items;
+ GHashTable *updated_items;
+
+ /* table of items for which we don't know the source */
+ GHashTable *orphan_items;
+
+ /* List of new/old sources */
+ GList *new_sources;
+ GList *old_sources;
+
+ /* Convenient stuff (for tracker/own callbacks...) */
+ TrackerSparqlCursor *cursor;
+ gboolean in_use;
+ GrlMediaSourceChangeType change_type;
+} tracker_evt_update_t;
+
+/**/
+
+static guint tracker_dbus_signal_id = 0;
+
+/**/
+static tracker_evt_update_t *
+tracker_evt_update_new (void)
+{
+ tracker_evt_update_t *evt = g_slice_new0 (tracker_evt_update_t);
+
+ evt->inserted_items = g_hash_table_new (g_direct_hash, g_direct_equal);
+ evt->deleted_items = g_hash_table_new (g_direct_hash, g_direct_equal);
+ evt->updated_items = g_hash_table_new (g_direct_hash, g_direct_equal);
+
+ evt->orphan_items = g_hash_table_new (g_direct_hash, g_direct_equal);
+
+ return evt;
+}
+
+static void
+tracker_evt_update_free (tracker_evt_update_t *evt)
+{
+ if (!evt)
+ return;
+
+ g_hash_table_destroy (evt->inserted_items);
+ g_hash_table_destroy (evt->deleted_items);
+ g_hash_table_destroy (evt->updated_items);
+
+ g_hash_table_destroy (evt->orphan_items);
+
+ g_list_free (evt->new_sources);
+ g_list_free (evt->old_sources);
+
+ if (evt->cursor != NULL)
+ g_object_unref (evt->cursor);
+
+ g_slice_free (tracker_evt_update_t, evt);
+}
+
+static void
+tracker_evt_update_media_add (tracker_evt_update_t *evt,
+ const gchar *id,
+ const gchar *source_name)
+{
+ GrlTrackerMedia *source;
+ GrlTrackerMediaPriv *priv;
+
+ source = g_hash_table_lookup (grl_tracker_modified_sources, id);
+ if (!source) {
+ source = g_object_new (GRL_TRACKER_MEDIA_TYPE,
+ "source-id", id,
+ "source-name", source_name,
+ "source-desc", GRL_TRACKER_MEDIA_DESC,
+ "tracker-connection", grl_tracker_connection,
+ NULL);
+ g_hash_table_insert (grl_tracker_modified_sources,
+ (gpointer) grl_metadata_source_get_id (GRL_METADATA_SOURCE (source)),
+ source);
+ }
+
+ priv = GRL_TRACKER_MEDIA_GET_PRIVATE (source);
+ priv->state = GRL_TRACKER_MEDIA_STATE_INSERTING;
+ priv->notification_ref++;
+
+ evt->new_sources = g_list_append (evt->new_sources, source);
+
+ GRL_DEBUG ("Preadd source p=%p name=%s id=%s count=%u",
+ source, source_name, id, priv->notification_ref);
+}
+
+static void
+tracker_evt_update_media_del (tracker_evt_update_t *evt,
+ GrlTrackerMedia *source)
+{
+ GrlTrackerMediaPriv *priv = GRL_TRACKER_MEDIA_GET_PRIVATE (source);
+
+ priv->notification_ref++;
+ priv->state = GRL_TRACKER_MEDIA_STATE_DELETING;
+
+ evt->old_sources = g_list_append (evt->old_sources, source);
+
+ GRL_DEBUG ("Predel source p=%p name=%s id=%s count=%u", source,
+ grl_metadata_source_get_name (GRL_METADATA_SOURCE (source)),
+ grl_metadata_source_get_id (GRL_METADATA_SOURCE (source)),
+ priv->notification_ref);
+}
+
+static void
+tracker_evt_postupdate_sources (tracker_evt_update_t *evt)
+{
+ GList *source;
+
+ GRL_DEBUG ("%s: evt=%p", __FUNCTION__, evt);
+
+ source = evt->old_sources;
+ while (source != NULL) {
+ grl_tracker_del_source (GRL_TRACKER_MEDIA (source->data));
+ source = source->next;
+ }
+
+ source = evt->new_sources;
+ while (source != NULL) {
+ grl_tracker_add_source (GRL_TRACKER_MEDIA (source->data));
+ source = source->next;
+ }
+
+ tracker_evt_update_free (evt);
+}
+
+static void
+tracker_evt_update_orphan_item_cb (GObject *object,
+ GAsyncResult *result,
+ tracker_evt_update_t *evt)
+{
+ guint id;
+ const gchar *type, *datasource;
+ GrlTrackerMedia *source = NULL;
+ GError *error = NULL;
+
+ GRL_DEBUG ("%s: evt=%p", __FUNCTION__, evt);
+
+ if (!tracker_sparql_cursor_next_finish (evt->cursor, result, &error)) {
+ if (error != NULL) {
+ GRL_DEBUG ("\terror in parsing : %s", error->message);
+ g_error_free (error);
+ } else {
+ GRL_DEBUG ("\tend of parsing...");
+ }
+
+ if (grl_tracker_per_device_source) {
+ /* Once all items have been processed, add new sources and we're
+ done. */
+ tracker_evt_postupdate_sources (evt);
+ }
+
+ return;
+ }
+
+ type = tracker_sparql_cursor_get_string (evt->cursor, 0, NULL);
+ id = tracker_sparql_cursor_get_integer (evt->cursor, 1);
+ datasource = tracker_sparql_cursor_get_string (evt->cursor, 2, NULL);
+
+ GRL_DEBUG ("\tOrphan item: id=%u datasource=%s", id, datasource);
+
+ if (datasource)
+ source = grl_tracker_media_find (datasource);
+
+ if (source && GRL_IS_TRACKER_MEDIA (source)) {
+ GrlMedia *media;
+
+ GRL_DEBUG (" \tAdding to cache id=%u", id);
+ grl_tracker_media_cache_add_item (grl_tracker_item_cache, id, source);
+
+ if (grl_tracker_media_can_notify (source)) {
+ media = grl_tracker_build_grilo_media (type);
+ if (media) {
+ gchar *str_id = g_strdup_printf ("%i", id);
+ gint change_type =
+ GPOINTER_TO_INT (g_hash_table_lookup (evt->orphan_items,
+ GSIZE_TO_POINTER (id)));
+
+ grl_media_set_id (media, str_id);
+ g_free (str_id);
+
+ GRL_DEBUG ("\tNotify id=%u source=%s p=%p", id,
+ grl_metadata_source_get_name (GRL_METADATA_SOURCE (source)),
+ source);
+ grl_media_source_notify_change (GRL_MEDIA_SOURCE (source), media,
+ change_type, FALSE);
+
+ g_object_unref (media);
+ }
+ }
+ }
+
+ tracker_sparql_cursor_next_async (evt->cursor, NULL,
+ (GAsyncReadyCallback) tracker_evt_update_orphan_item_cb,
+ (gpointer) evt);
+}
+
+static void
+tracker_evt_update_orphans_cb (GObject *object,
+ GAsyncResult *result,
+ tracker_evt_update_t *evt)
+{
+ GError *error = NULL;
+
+ GRL_DEBUG ("%s: evt=%p", __FUNCTION__, evt);
+
+ if (evt->cursor != NULL)
+ g_object_unref (evt->cursor);
+ evt->cursor = tracker_sparql_connection_query_finish (grl_tracker_connection,
+ result, &error);
+
+ if (error != NULL) {
+ GRL_WARNING ("Could not execute sparql query: %s", error->message);
+
+ g_error_free (error);
+ tracker_evt_postupdate_sources (evt);
+ return;
+ }
+
+ tracker_sparql_cursor_next_async (evt->cursor, NULL,
+ (GAsyncReadyCallback) tracker_evt_update_orphan_item_cb,
+ (gpointer) evt);
+}
+
+static void
+tracker_evt_update_orphans (tracker_evt_update_t *evt)
+{
+ guint id;
+ gchar *str_id;
+ GString *request_str;
+ GList *subject, *subjects;
+ GrlMedia *media;
+ GList *source, *sources;
+
+ GRL_DEBUG ("%s: evt=%p", __FUNCTION__, evt);
+
+ if (g_hash_table_size (evt->orphan_items) < 1) {
+ tracker_evt_postupdate_sources (evt);
+ return;
+ }
+
+ sources = grl_plugin_registry_get_sources (grl_plugin_registry_get_default (),
+ FALSE);
+
+ request_str = g_string_new (TRACKER_MEDIA_ITEM_START);
+ subjects = g_hash_table_get_keys (evt->orphan_items);
+
+ subject = subjects;
+ while (subject != NULL) {
+ id = GPOINTER_TO_INT (subject->data);
+ if (GPOINTER_TO_INT (g_hash_table_lookup (evt->orphan_items,
+ subject->data)) != GRL_CONTENT_REMOVED) {
+ g_string_append_printf (request_str, "%u", id);
+ break;
+ } else {
+ /* Notify all sources that a been removed */
+ media = grl_media_new ();
+ str_id = g_strdup_printf ("%u", id);
+ grl_media_set_id (media, str_id);
+ g_free (str_id);
+
+ source = sources;
+ while (source != NULL) {
+ if (GRL_IS_TRACKER_MEDIA (source->data)) {
+ GRL_DEBUG ("\tNotify id=%u source=%s p=%p", id,
+ grl_metadata_source_get_name (GRL_METADATA_SOURCE (source->data)),
+ source->data);
+ if (grl_tracker_media_can_notify (GRL_TRACKER_MEDIA (source->data)))
+ grl_media_source_notify_change (GRL_MEDIA_SOURCE (source->data),
+ media, GRL_CONTENT_REMOVED, FALSE);
+ }
+ source = source->next;
+ }
+ g_object_unref (media);
+ }
+ subject = subject->next;
+ }
+
+ if (subject != NULL) {
+ subject = subject->next;
+ while (subject != NULL) {
+ id = GPOINTER_TO_INT (subject->data);
+ if (GPOINTER_TO_INT (g_hash_table_lookup (evt->orphan_items,
+ subject->data)) != GRL_CONTENT_REMOVED) {
+ g_string_append_printf (request_str, ", %u", id);
+ } else {
+ /* Notify all sources that a been removed */
+ media = grl_media_new ();
+ str_id = g_strdup_printf ("%u", id);
+ grl_media_set_id (media, str_id);
+ g_free (str_id);
+
+ source = sources;
+ while (source != NULL) {
+ if (GRL_IS_TRACKER_MEDIA (source->data)) {
+ GRL_DEBUG ("\tNotify id=%u source=%s p=%p", id,
+ grl_metadata_source_get_name (GRL_METADATA_SOURCE (source->data)),
+ source->data);
+ if (grl_tracker_media_can_notify (GRL_TRACKER_MEDIA (source->data)))
+ grl_media_source_notify_change (GRL_MEDIA_SOURCE (source->data),
+ media, GRL_CONTENT_REMOVED, FALSE);
+ }
+ source = source->next;
+ }
+ g_object_unref (media);
+ }
+ subject = subject->next;
+ }
+ g_list_free (subjects);
+
+ g_string_append (request_str, TRACKER_MEDIA_ITEM_END);
+
+ GRL_DEBUG ("\trequest : '%s'", request_str->str);
+
+ tracker_sparql_connection_query_async (grl_tracker_connection,
+ request_str->str,
+ NULL,
+ (GAsyncReadyCallback) tracker_evt_update_orphans_cb,
+ evt);
+ } else {
+ tracker_evt_postupdate_sources (evt);
+ }
+
+ g_string_free (request_str, TRUE);
+}
+
+static void
+tracker_evt_update_items_cb (gpointer key,
+ gpointer value,
+ tracker_evt_update_t *evt)
+{
+ guint id = GPOINTER_TO_INT (key);
+ gchar *str_id;
+ GrlTrackerMedia *source = (GrlTrackerMedia *) value;
+ GrlMedia *media;
+
+ GRL_DEBUG ("%s: evt=%p", __FUNCTION__, evt);
+
+ if (!source) {
+ g_assert ("\tnot in cache ???");
+ return;
+ }
+
+ if (!grl_tracker_media_can_notify (source)) {
+ GRL_DEBUG ("\tno notification for source %s...",
+ grl_metadata_source_get_name (GRL_METADATA_SOURCE (source)));
+ return;
+ }
+
+ media = grl_media_new ();
+ str_id = g_strdup_printf ("%i", id);
+ grl_media_set_id (media, str_id);
+ g_free (str_id);
+
+ GRL_DEBUG ("\tNotify id=%u source=%s", id,
+ grl_metadata_source_get_name (GRL_METADATA_SOURCE (source)));
+ grl_media_source_notify_change (GRL_MEDIA_SOURCE (source), media,
+ evt->change_type, FALSE);
+
+ g_object_unref (media);
+}
+
+static void
+tracker_evt_update_items (tracker_evt_update_t *evt)
+{
+ evt->change_type = GRL_CONTENT_REMOVED;
+ g_hash_table_foreach (evt->deleted_items,
+ (GHFunc) tracker_evt_update_items_cb, evt);
+ evt->change_type = GRL_CONTENT_ADDED;
+ g_hash_table_foreach (evt->inserted_items,
+ (GHFunc) tracker_evt_update_items_cb, evt);
+ evt->change_type = GRL_CONTENT_CHANGED;
+ g_hash_table_foreach (evt->updated_items,
+ (GHFunc) tracker_evt_update_items_cb, evt);
+}
+
+static void
+tracker_evt_preupdate_sources_item_cb (GObject *object,
+ GAsyncResult *result,
+ tracker_evt_update_t *evt)
+{
+ const gchar *type, *datasource, *uri, *datasource_name;
+ gboolean source_available;
+ GrlTrackerMedia *source;
+ GError *error = NULL;
+
+ GRL_DEBUG ("%s: evt=%p", __FUNCTION__, evt);
+
+ if (!tracker_sparql_cursor_next_finish (evt->cursor, result, &error)) {
+ if (error != NULL) {
+ GRL_DEBUG ("\terror in parsing : %s", error->message);
+ g_error_free (error);
+ } else {
+ GRL_DEBUG ("\tend of parsing... start notifying sources");
+ }
+
+ /* Once all sources have been preupdated, start items
+ updates. */
+ tracker_evt_update_items (evt);
+ tracker_evt_update_orphans (evt);
+
+ return;
+ }
+
+ type = tracker_sparql_cursor_get_string (evt->cursor, 0, NULL);
+ datasource = tracker_sparql_cursor_get_string (evt->cursor, 1, NULL);
+ datasource_name = tracker_sparql_cursor_get_string (evt->cursor, 2, NULL);
+ uri = tracker_sparql_cursor_get_string (evt->cursor, 3, NULL);
+ source_available = tracker_sparql_cursor_get_boolean (evt->cursor, 4);
+
+ source = grl_tracker_media_find (datasource);
+
+ GRL_DEBUG ("\tdatasource=%s uri=%s available=%i source=%p",
+ datasource, uri, source_available, source);
+
+ if (source_available) {
+ if (source == NULL) {
+ gchar *source_name = grl_tracker_get_media_name (type, uri, datasource,
+ datasource_name);
+ /* Defer source creation until we have processed all sources */
+ tracker_evt_update_media_add (evt, datasource, source_name);
+ g_free (source_name);
+ } else {
+ GRL_DEBUG ("\tChanges on source %p / %s", source, datasource);
+ }
+ } else if (!source_available && source != NULL) {
+ tracker_evt_update_media_del (evt, GRL_TRACKER_MEDIA (source));
+ }
+
+ tracker_sparql_cursor_next_async (evt->cursor, NULL,
+ (GAsyncReadyCallback) tracker_evt_preupdate_sources_item_cb,
+ (gpointer) evt);
+}
+
+static void
+tracker_evt_preupdate_sources_cb (GObject *object,
+ GAsyncResult *result,
+ tracker_evt_update_t *evt)
+{
+ GError *error = NULL;
+
+ GRL_DEBUG ("%s: evt=%p", __FUNCTION__, evt);
+
+ if (evt->cursor != NULL)
+ g_object_unref (evt->cursor);
+ evt->cursor = tracker_sparql_connection_query_finish (grl_tracker_connection,
+ result, &error);
+
+ if (error != NULL) {
+ GRL_WARNING ("\tCannot handle datasource request : %s", error->message);
+
+ g_error_free (error);
+ tracker_evt_update_free (evt);
+ return;
+ }
+
+ tracker_sparql_cursor_next_async (evt->cursor, NULL,
+ (GAsyncReadyCallback) tracker_evt_preupdate_sources_item_cb,
+ (gpointer) evt);
+}
+
+static void
+tracker_evt_preupdate_sources (tracker_evt_update_t *evt)
+{
+ tracker_sparql_connection_query_async (grl_tracker_connection,
+ TRACKER_DATASOURCES_REQUEST,
+ NULL,
+ (GAsyncReadyCallback) tracker_evt_preupdate_sources_cb,
+ evt);
+}
+
+static void
+tracker_dbus_signal_cb (GDBusConnection *connection,
+ const gchar *sender_name,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *signal_name,
+ GVariant *parameters,
+ gpointer user_data)
+
+{
+ gchar *class_name;
+ gint graph = 0, subject = 0, predicate = 0, object = 0;
+ GVariantIter *iter1, *iter2;
+ tracker_evt_update_t *evt = tracker_evt_update_new ();
+
+ g_variant_get (parameters, "(&sa(iiii)a(iiii))", &class_name, &iter1, &iter2);
+
+ GRL_DEBUG ("\tTracker update event for class=%s ins=%lu del=%lu evt=%p",
+ class_name,
+ (unsigned long) g_variant_iter_n_children (iter1),
+ (unsigned long) g_variant_iter_n_children (iter2),
+ evt);
+
+ /* Avoid processing item from uninteresting classes */
+ if (g_str_has_suffix (class_name, RDF_TYPE_MUSIC) ||
+ g_str_has_suffix (class_name, RDF_TYPE_AUDIO) ||
+ g_str_has_suffix (class_name, RDF_TYPE_VIDEO) ||
+ g_str_has_suffix (class_name, RDF_TYPE_IMAGE)) {
+
+ /* Process deleted items */
+ while (g_variant_iter_loop (iter1, "(iiii)", &graph,
+ &subject, &predicate, &object)) {
+ gpointer psubject = GSIZE_TO_POINTER (subject);
+ GrlTrackerMedia *source =
+ grl_tracker_media_cache_get_source (grl_tracker_item_cache, subject);
+
+ /* GRL_DEBUG ("\tdelete=> subject=%i", subject); */
+
+ if (source) {
+ g_hash_table_insert (evt->deleted_items, psubject,
+ g_object_ref (source));
+ } else {
+ g_hash_table_insert (evt->orphan_items, psubject,
+ GSIZE_TO_POINTER (GRL_CONTENT_REMOVED));
+ }
+ }
+
+ /* Process inserted items */
+ while (g_variant_iter_loop (iter2, "(iiii)", &graph,
+ &subject, &predicate, &object)) {
+ gpointer psubject = GSIZE_TO_POINTER (subject);
+ GrlTrackerMedia *source =
+ grl_tracker_media_cache_get_source (grl_tracker_item_cache, subject);
+
+ /* GRL_DEBUG ("\tinsert=> subject=%i", subject); */
+
+ if (source) {
+ /* Removed & inserted items are probably just renamed items... */
+ if (g_hash_table_lookup (evt->deleted_items, psubject)) {
+ g_hash_table_remove (evt->deleted_items, psubject);
+ g_hash_table_insert (evt->updated_items, psubject,
+ g_object_ref (source));
+ } else if (!g_hash_table_lookup (evt->updated_items, psubject)) {
+ g_hash_table_insert (evt->inserted_items, psubject,
+ g_object_ref (source));
+ }
+ } else {
+ gpointer state;
+
+ if (g_hash_table_lookup_extended (evt->orphan_items, psubject,
+ NULL, &state) &&
+ (GPOINTER_TO_INT (state) == GRL_CONTENT_REMOVED)) {
+ g_hash_table_insert (evt->orphan_items, psubject,
+ GSIZE_TO_POINTER (GRL_CONTENT_CHANGED));
+ } else {
+ g_hash_table_insert (evt->orphan_items, psubject,
+ GSIZE_TO_POINTER (GRL_CONTENT_ADDED));
+ }
+ }
+ }
+ }
+
+ g_variant_iter_free (iter1);
+ g_variant_iter_free (iter2);
+
+ GRL_DEBUG ("\tinserted=%i deleted=%i updated=%i orphan=%i",
+ g_hash_table_size (evt->inserted_items),
+ g_hash_table_size (evt->deleted_items),
+ g_hash_table_size (evt->updated_items),
+ g_hash_table_size (evt->orphan_items));
+
+ if (grl_tracker_per_device_source) {
+ tracker_evt_preupdate_sources (evt);
+ } else {
+ tracker_evt_update_items (evt);
+ tracker_evt_update_orphans (evt);
+ }
+}
+
+void
+grl_tracker_media_dbus_start_watch (void)
+{
+ GDBusConnection *connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
+
+ tracker_dbus_signal_id = g_dbus_connection_signal_subscribe (connection,
+ TRACKER_DBUS_SERVICE,
+ TRACKER_DBUS_INTERFACE_RESOURCES,
+ "GraphUpdated",
+ TRACKER_DBUS_OBJECT_RESOURCES,
+ NULL,
+ G_DBUS_SIGNAL_FLAGS_NONE,
+ tracker_dbus_signal_cb,
+ NULL,
+ NULL);
+}
+
+void
+grl_tracker_media_init_notifs (void)
+{
+ GRL_LOG_DOMAIN_INIT (tracker_notif_log_domain, "tracker-notif");
+}
diff --git a/src/media/tracker/grl-tracker-media-notif.h b/src/media/tracker/grl-tracker-media-notif.h
new file mode 100644
index 0000000..67eeba8
--- /dev/null
+++ b/src/media/tracker/grl-tracker-media-notif.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2011 Intel Corporation.
+ *
+ * Contact: Iago Toral Quiroga <itoral igalia com>
+ *
+ * Authors: 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
+ * 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_TRACKER_MEDIA_NOTIF_H_
+#define _GRL_TRACKER_MEDIA_NOTIF_H_
+
+#include "grl-tracker-media.h"
+
+/* ------- Definitions ------- */
+
+#define TRACKER_DATASOURCES_REQUEST \
+ "SELECT " \
+ "(SELECT GROUP_CONCAT(rdf:type(?source), \":\") " \
+ " WHERE { ?urn nie:dataSource ?source }) " \
+ "nie:dataSource(?urn) " \
+ "(SELECT GROUP_CONCAT(nie:title(?source), \":\") " \
+ " WHERE { ?urn nie:dataSource ?source }) " \
+ "(SELECT GROUP_CONCAT(nie:url(tracker:mountPoint(?source)), \":\") " \
+ " WHERE { ?urn nie:dataSource ?source }) " \
+ "tracker:available(?urn) " \
+ "WHERE " \
+ "{ " \
+ "?urn a nfo:FileDataObject . FILTER (bound(nie:dataSource(?urn)))" \
+ "} " \
+ "GROUP BY (nie:dataSource(?urn))"
+
+/**/
+
+void grl_tracker_media_dbus_start_watch (void);
+
+void grl_tracker_media_init_notifs (void);
+
+#endif /* _GRL_TRACKER_MEDIA_NOTIF_H_ */
diff --git a/src/media/tracker/grl-tracker-media-priv.h b/src/media/tracker/grl-tracker-media-priv.h
new file mode 100644
index 0000000..0446de2
--- /dev/null
+++ b/src/media/tracker/grl-tracker-media-priv.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2011 Intel Corporation.
+ *
+ * Contact: Iago Toral Quiroga <itoral igalia com>
+ *
+ * Authors: 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
+ * 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_TRACKER_MEDIA_PRIV_H_
+#define _GRL_TRACKER_MEDIA_PRIV_H_
+
+#include "grl-tracker-media.h"
+#include "grl-tracker-media-cache.h"
+
+#include <tracker-sparql.h>
+
+/* ---- Plugin information --- */
+
+#define GRL_TRACKER_PLUGIN_ID TRACKER_PLUGIN_ID
+
+#define GRL_TRACKER_MEDIA_ID "grl-tracker"
+#define GRL_TRACKER_MEDIA_NAME "Tracker"
+#define GRL_TRACKER_MEDIA_DESC \
+ "A plugin for searching multimedia " \
+ "content using Tracker"
+
+#define GRL_TRACKER_AUTHOR "Igalia S.L."
+#define GRL_TRACKER_LICENSE "LGPL"
+#define GRL_TRACKER_SITE "http://www.igalia.com"
+
+/**/
+
+#define GRL_TRACKER_MEDIA_GET_PRIVATE(object) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((object), \
+ GRL_TRACKER_MEDIA_TYPE, \
+ GrlTrackerMediaPriv))
+
+typedef enum {
+ GRL_TRACKER_MEDIA_STATE_INSERTING,
+ GRL_TRACKER_MEDIA_STATE_RUNNING,
+ GRL_TRACKER_MEDIA_STATE_DELETING,
+ GRL_TRACKER_MEDIA_STATE_DELETED,
+} GrlTrackerMediaState;
+
+struct _GrlTrackerMediaPriv {
+ TrackerSparqlConnection *tracker_connection;
+
+ GHashTable *operations;
+
+ gchar *tracker_datasource;
+ gboolean notify_changes;
+
+ GrlTrackerMediaState state;
+ guint notification_ref;
+};
+
+/**/
+
+extern TrackerSparqlConnection *grl_tracker_connection;
+extern const GrlPluginInfo *grl_tracker_plugin;
+
+/* shared data across */
+extern GrlTrackerCache *grl_tracker_item_cache;
+extern GHashTable *grl_tracker_modified_sources;
+
+/* tracker plugin config */
+extern gboolean grl_tracker_per_device_source;
+extern gboolean grl_tracker_browse_filesystem;
+
+#endif /* _GRL_TRACKER_MEDIA_PRIV_H_ */
diff --git a/src/media/tracker/grl-tracker-media.c b/src/media/tracker/grl-tracker-media.c
new file mode 100644
index 0000000..1ac906f
--- /dev/null
+++ b/src/media/tracker/grl-tracker-media.c
@@ -0,0 +1,417 @@
+/*
+ * Copyright (C) 2011 Igalia S.L.
+ * Copyright (C) 2011 Intel Corporation.
+ *
+ * Contact: Iago Toral Quiroga <itoral igalia com>
+ *
+ * Authors: Juan A. Suarez Romero <jasuarez 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 <string.h>
+#include <tracker-sparql.h>
+
+#include "grl-tracker-media.h"
+#include "grl-tracker-media-priv.h"
+#include "grl-tracker-media-api.h"
+#include "grl-tracker-media-cache.h"
+#include "grl-tracker-media-notif.h"
+#include "grl-tracker-utils.h"
+
+/* --------- Logging -------- */
+
+#define GRL_LOG_DOMAIN_DEFAULT tracker_general_log_domain
+GRL_LOG_DOMAIN_STATIC(tracker_general_log_domain);
+
+/* ------- Definitions ------- */
+
+#define MEDIA_TYPE "grilo-media-type"
+
+#define TRACKER_ITEM_CACHE_SIZE (10000)
+
+/* --- Other --- */
+
+enum {
+ PROP_0,
+ PROP_TRACKER_CONNECTION,
+};
+
+static GrlTrackerMedia *grl_tracker_media_new (TrackerSparqlConnection *connection);
+
+static void grl_tracker_media_set_property (GObject *object,
+ guint propid,
+ const GValue *value,
+ GParamSpec *pspec);
+
+static void grl_tracker_media_constructed (GObject *object);
+
+static void grl_tracker_media_finalize (GObject *object);
+
+gboolean grl_tracker_plugin_init (GrlPluginRegistry *registry,
+ const GrlPluginInfo *plugin,
+ GList *configs);
+
+/* ===================== Globals ================= */
+
+TrackerSparqlConnection *grl_tracker_connection = NULL;
+const GrlPluginInfo *grl_tracker_plugin;
+
+/* shared data across */
+GrlTrackerCache *grl_tracker_item_cache;
+GHashTable *grl_tracker_modified_sources;
+
+/* tracker plugin config */
+gboolean grl_tracker_per_device_source = FALSE;
+gboolean grl_tracker_browse_filesystem = FALSE;
+
+/* =================== Tracker Plugin =============== */
+
+void
+grl_tracker_add_source (GrlTrackerMedia *source)
+{
+ GrlTrackerMediaPriv *priv = GRL_TRACKER_MEDIA_GET_PRIVATE (source);
+
+ GRL_DEBUG ("====================>add source '%s' count=%u",
+ grl_metadata_source_get_name (GRL_METADATA_SOURCE (source)),
+ priv->notification_ref);
+
+ if (priv->notification_ref > 0) {
+ priv->notification_ref--;
+ }
+ if (priv->notification_ref == 0) {
+ g_hash_table_remove (grl_tracker_modified_sources,
+ grl_metadata_source_get_id (GRL_METADATA_SOURCE (source)));
+ priv->state = GRL_TRACKER_MEDIA_STATE_RUNNING;
+ grl_plugin_registry_register_source (grl_plugin_registry_get_default (),
+ grl_tracker_plugin,
+ GRL_MEDIA_PLUGIN (source),
+ NULL);
+ }
+}
+
+void
+grl_tracker_del_source (GrlTrackerMedia *source)
+{
+ GrlTrackerMediaPriv *priv = GRL_TRACKER_MEDIA_GET_PRIVATE (source);
+
+ GRL_DEBUG ("==================>del source '%s' count=%u",
+ grl_metadata_source_get_name (GRL_METADATA_SOURCE (source)),
+ priv->notification_ref);
+ if (priv->notification_ref > 0) {
+ priv->notification_ref--;
+ }
+ if (priv->notification_ref == 0) {
+ g_hash_table_remove (grl_tracker_modified_sources,
+ grl_metadata_source_get_id (GRL_METADATA_SOURCE (source)));
+ grl_tracker_media_cache_del_source (grl_tracker_item_cache, source);
+ priv->state = GRL_TRACKER_MEDIA_STATE_DELETED;
+ grl_plugin_registry_unregister_source (grl_plugin_registry_get_default (),
+ GRL_MEDIA_PLUGIN (source),
+ NULL);
+ }
+}
+
+gboolean
+grl_tracker_media_can_notify (GrlTrackerMedia *source)
+{
+ GrlTrackerMediaPriv *priv = GRL_TRACKER_MEDIA_GET_PRIVATE (source);
+
+ if (priv->state == GRL_TRACKER_MEDIA_STATE_RUNNING)
+ return priv->notify_changes;
+
+ return FALSE;
+}
+
+GrlTrackerMedia *
+grl_tracker_media_find (const gchar *id)
+{
+ GrlMediaPlugin *source;
+
+ source = grl_plugin_registry_lookup_source (grl_plugin_registry_get_default (),
+ id);
+
+ if (source && GRL_IS_TRACKER_MEDIA (source)) {
+ return (GrlTrackerMedia *) source;
+ }
+
+ return
+ (GrlTrackerMedia *) g_hash_table_lookup (grl_tracker_modified_sources,
+ id);
+}
+
+static void
+tracker_get_datasource_cb (GObject *object,
+ GAsyncResult *result,
+ TrackerSparqlCursor *cursor)
+{
+ const gchar *type, *datasource, *datasource_name, *uri;
+ gboolean source_available;
+ GError *error = NULL;
+ GrlTrackerMedia *source;
+
+ GRL_DEBUG ("%s", __FUNCTION__);
+
+ if (!tracker_sparql_cursor_next_finish (cursor, result, &error)) {
+ if (error == NULL) {
+ GRL_DEBUG ("\tEnd of parsing of devices");
+ } else {
+ GRL_WARNING ("\tError while parsing devices: %s", error->message);
+ g_error_free (error);
+ }
+ g_object_unref (G_OBJECT (cursor));
+ return;
+ }
+
+ type = tracker_sparql_cursor_get_string (cursor, 0, NULL);
+ datasource = tracker_sparql_cursor_get_string (cursor, 1, NULL);
+ datasource_name = tracker_sparql_cursor_get_string (cursor, 2, NULL);
+ uri = tracker_sparql_cursor_get_string (cursor, 3, NULL);
+ source_available = tracker_sparql_cursor_get_boolean (cursor, 4);
+
+ source = grl_tracker_media_find (datasource);
+
+ if ((source == NULL) && source_available) {
+ gchar *source_name = grl_tracker_get_media_name (type, uri, datasource,
+ datasource_name);
+ GRL_DEBUG ("\tnew datasource: urn=%s name=%s uri=%s\n",
+ datasource, datasource_name, uri);
+ source = g_object_new (GRL_TRACKER_MEDIA_TYPE,
+ "source-id", datasource,
+ "source-name", source_name,
+ "source-desc", GRL_TRACKER_MEDIA_DESC,
+ "tracker-connection", grl_tracker_connection,
+ NULL);
+ grl_tracker_add_source (source);
+ g_free (source_name);
+ }
+
+ tracker_sparql_cursor_next_async (cursor, NULL,
+ (GAsyncReadyCallback) tracker_get_datasource_cb,
+ cursor);
+}
+
+static void
+tracker_get_datasources_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer data)
+{
+ GError *error = NULL;
+ TrackerSparqlCursor *cursor;
+
+ GRL_DEBUG ("%s", __FUNCTION__);
+
+ cursor = tracker_sparql_connection_query_finish (grl_tracker_connection,
+ result, &error);
+
+ if (error) {
+ GRL_WARNING ("Cannot handle datasource request : %s", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ tracker_sparql_cursor_next_async (cursor, NULL,
+ (GAsyncReadyCallback) tracker_get_datasource_cb,
+ cursor);
+}
+
+static void
+tracker_get_connection_cb (GObject *object,
+ GAsyncResult *res,
+ const GrlPluginInfo *plugin)
+{
+ /* GrlTrackerMedia *source; */
+
+ GRL_DEBUG ("%s", __FUNCTION__);
+
+ grl_tracker_connection = tracker_sparql_connection_get_finish (res, NULL);
+
+ if (grl_tracker_connection != NULL) {
+ grl_tracker_media_dbus_start_watch ();
+
+ if (grl_tracker_per_device_source == TRUE) {
+ /* Let's discover available data sources. */
+ GRL_DEBUG ("\tper device source mode request: '"
+ TRACKER_DATASOURCES_REQUEST "'");
+
+ tracker_sparql_connection_query_async (grl_tracker_connection,
+ TRACKER_DATASOURCES_REQUEST,
+ NULL,
+ (GAsyncReadyCallback) tracker_get_datasources_cb,
+ NULL);
+ } else {
+ /* One source to rule them all. */
+ grl_tracker_add_source (grl_tracker_media_new (grl_tracker_connection));
+ }
+ }
+}
+
+gboolean
+grl_tracker_plugin_init (GrlPluginRegistry *registry,
+ const GrlPluginInfo *plugin,
+ GList *configs)
+{
+ GrlConfig *config;
+ gint config_count;
+
+ GRL_DEBUG ("%s", __FUNCTION__);
+
+ GRL_LOG_DOMAIN_INIT (tracker_general_log_domain, "tracker-general");
+ grl_tracker_media_init_notifs ();
+ grl_tracker_media_init_requests ();
+
+ grl_tracker_plugin = plugin;
+ grl_tracker_item_cache =
+ grl_tracker_media_cache_new (TRACKER_ITEM_CACHE_SIZE);
+ grl_tracker_modified_sources = g_hash_table_new (g_str_hash, g_str_equal);
+
+ if (!configs) {
+ GRL_WARNING ("\tConfiguration not provided! Using default configuration.");
+ } else {
+ config_count = g_list_length (configs);
+ if (config_count > 1) {
+ GRL_WARNING ("\tProvided %i configs, but will only use one", config_count);
+ }
+
+ config = GRL_CONFIG (configs->data);
+
+ grl_tracker_per_device_source =
+ grl_config_get_boolean (config, "per-device-source");
+ grl_tracker_browse_filesystem =
+ grl_config_get_boolean (config, "browse-filesystem");
+ }
+
+ tracker_sparql_connection_get_async (NULL,
+ (GAsyncReadyCallback) tracker_get_connection_cb,
+ (gpointer) plugin);
+ return TRUE;
+}
+
+GRL_PLUGIN_REGISTER (grl_tracker_plugin_init,
+ NULL,
+ GRL_TRACKER_PLUGIN_ID);
+
+/* ================== Tracker GObject ================ */
+
+static GrlTrackerMedia *
+grl_tracker_media_new (TrackerSparqlConnection *connection)
+{
+ GRL_DEBUG ("%s", __FUNCTION__);
+
+ return g_object_new (GRL_TRACKER_MEDIA_TYPE,
+ "source-id", GRL_TRACKER_MEDIA_ID,
+ "source-name", GRL_TRACKER_MEDIA_NAME,
+ "source-desc", GRL_TRACKER_MEDIA_DESC,
+ "tracker-connection", connection,
+ NULL);
+}
+
+G_DEFINE_TYPE (GrlTrackerMedia, grl_tracker_media, GRL_TYPE_MEDIA_SOURCE);
+
+static void
+grl_tracker_media_class_init (GrlTrackerMediaClass * 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->query = grl_tracker_media_query;
+ source_class->metadata = grl_tracker_media_metadata;
+ source_class->search = grl_tracker_media_search;
+ source_class->browse = grl_tracker_media_browse;
+ source_class->cancel = grl_tracker_media_cancel;
+ source_class->notify_change_start = grl_tracker_media_change_start;
+ source_class->notify_change_stop = grl_tracker_media_change_stop;
+
+ metadata_class->supported_keys = grl_tracker_media_supported_keys;
+
+ g_class->finalize = grl_tracker_media_finalize;
+ g_class->set_property = grl_tracker_media_set_property;
+ g_class->constructed = grl_tracker_media_constructed;
+
+ g_object_class_install_property (g_class,
+ PROP_TRACKER_CONNECTION,
+ g_param_spec_object ("tracker-connection",
+ "tracker connection",
+ "A Tracker connection",
+ TRACKER_SPARQL_TYPE_CONNECTION,
+ G_PARAM_WRITABLE
+ | G_PARAM_CONSTRUCT_ONLY
+ | G_PARAM_STATIC_NAME));
+
+ g_type_class_add_private (klass, sizeof (GrlTrackerMediaPriv));
+
+ grl_tracker_setup_key_mappings ();
+}
+
+static void
+grl_tracker_media_init (GrlTrackerMedia *source)
+{
+ GrlTrackerMediaPriv *priv = GRL_TRACKER_MEDIA_GET_PRIVATE (source);
+
+ source->priv = priv;
+
+ priv->operations = g_hash_table_new (g_direct_hash, g_direct_equal);
+}
+
+static void
+grl_tracker_media_constructed (GObject *object)
+{
+ GrlTrackerMediaPriv *priv = GRL_TRACKER_MEDIA_GET_PRIVATE (object);
+
+ if (grl_tracker_per_device_source)
+ g_object_get (object, "source-id", &priv->tracker_datasource, NULL);
+}
+
+static void
+grl_tracker_media_finalize (GObject *object)
+{
+ GrlTrackerMedia *self;
+
+ self = GRL_TRACKER_MEDIA (object);
+ if (self->priv->tracker_connection)
+ g_object_unref (self->priv->tracker_connection);
+
+ G_OBJECT_CLASS (grl_tracker_media_parent_class)->finalize (object);
+}
+
+static void
+grl_tracker_media_set_property (GObject *object,
+ guint propid,
+ const GValue *value,
+ GParamSpec *pspec)
+
+{
+ GrlTrackerMediaPriv *priv = GRL_TRACKER_MEDIA_GET_PRIVATE (object);
+
+ switch (propid) {
+ case PROP_TRACKER_CONNECTION:
+ if (priv->tracker_connection != NULL)
+ g_object_unref (G_OBJECT (priv->tracker_connection));
+ priv->tracker_connection = g_object_ref (g_value_get_object (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
+ }
+}
+
diff --git a/src/media/tracker/grl-tracker-media.h b/src/media/tracker/grl-tracker-media.h
new file mode 100644
index 0000000..6b484c2
--- /dev/null
+++ b/src/media/tracker/grl-tracker-media.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2011 Igalia S.L.
+ *
+ * Contact: Iago Toral Quiroga <itoral igalia com>
+ *
+ * Authors: Juan A. Suarez Romero <jasuarez 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_TRACKER_MEDIA_H_
+#define _GRL_TRACKER_MEDIA_H_
+
+#include <grilo.h>
+
+#define GRL_TRACKER_MEDIA_TYPE \
+ (grl_tracker_media_get_type ())
+
+#define GRL_TRACKER_MEDIA(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ GRL_TRACKER_MEDIA_TYPE, \
+ GrlTrackerMedia))
+
+#define GRL_IS_TRACKER_MEDIA(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+ GRL_TRACKER_MEDIA_TYPE))
+
+#define GRL_TRACKER_MEDIA_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass), \
+ GRL_TRACKER_MEDIA_TYPE, \
+ GrlTrackerMediaClass))
+
+#define GRL_IS_TRACKER_MEDIA_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass), \
+ GRL_TRACKER_MEDIA_TYPE))
+
+#define GRL_TRACKER_MEDIA_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ GRL_TRACKER_MEDIA_TYPE, \
+ GrlTrackerMediaClass))
+
+typedef struct _GrlTrackerMedia GrlTrackerMedia;
+typedef struct _GrlTrackerMediaPriv GrlTrackerMediaPriv;
+
+struct _GrlTrackerMedia {
+
+ GrlMediaSource parent;
+
+ /*< private >*/
+ GrlTrackerMediaPriv *priv;
+
+};
+
+typedef struct _GrlTrackerMediaClass GrlTrackerMediaClass;
+
+struct _GrlTrackerMediaClass {
+
+ GrlMediaSourceClass parent_class;
+
+};
+
+GType grl_tracker_media_get_type (void);
+
+gboolean grl_tracker_media_can_notify (GrlTrackerMedia *source);
+
+/**/
+void grl_tracker_add_source (GrlTrackerMedia *source);
+
+void grl_tracker_del_source (GrlTrackerMedia *source);
+
+GrlTrackerMedia *grl_tracker_media_find (const gchar *id);
+
+
+#endif /* _GRL_TRACKER_MEDIA_H_ */
diff --git a/src/media/tracker/grl-tracker-notif.c b/src/media/tracker/grl-tracker-notif.c
deleted file mode 100644
index df70d10..0000000
--- a/src/media/tracker/grl-tracker-notif.c
+++ /dev/null
@@ -1,641 +0,0 @@
-/*
- * Copyright (C) 2011 Intel Corporation.
- *
- * Contact: Iago Toral Quiroga <itoral igalia com>
- *
- * Authors: 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
- * 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
- *
- */
-
-#include <tracker-sparql.h>
-
-#include "grl-tracker-notif.h"
-#include "grl-tracker-priv.h"
-#include "grl-tracker-utils.h"
-
-/* --------- Logging -------- */
-
-#define GRL_LOG_DOMAIN_DEFAULT tracker_notif_log_domain
-GRL_LOG_DOMAIN_STATIC(tracker_notif_log_domain);
-
-/* ------- Definitions ------- */
-
-#define TRACKER_SOURCE_ITEM_START \
- "SELECT rdf:type(?urn) tracker:id(?urn) nie:dataSource(?urn) " \
- "WHERE { ?urn a nfo:FileDataObject . " \
- "FILTER (tracker:id(?urn) IN ("
-
-#define TRACKER_SOURCE_ITEM_END ")) }"
-
-/**/
-
-typedef struct {
- /* tables of items for which we know the source */
- GHashTable *inserted_items;
- GHashTable *deleted_items;
- GHashTable *updated_items;
-
- /* table of items for which we don't know the source */
- GHashTable *orphan_items;
-
- /* List of new/old sources */
- GList *new_sources;
- GList *old_sources;
-
- /* Convenient stuff (for tracker/own callbacks...) */
- TrackerSparqlCursor *cursor;
- gboolean in_use;
- GrlMediaSourceChangeType change_type;
-} tracker_evt_update_t;
-
-/**/
-
-static guint tracker_dbus_signal_id = 0;
-
-/**/
-static tracker_evt_update_t *
-tracker_evt_update_new (void)
-{
- tracker_evt_update_t *evt = g_slice_new0 (tracker_evt_update_t);
-
- evt->inserted_items = g_hash_table_new (g_direct_hash, g_direct_equal);
- evt->deleted_items = g_hash_table_new (g_direct_hash, g_direct_equal);
- evt->updated_items = g_hash_table_new (g_direct_hash, g_direct_equal);
-
- evt->orphan_items = g_hash_table_new (g_direct_hash, g_direct_equal);
-
- return evt;
-}
-
-static void
-tracker_evt_update_free (tracker_evt_update_t *evt)
-{
- if (!evt)
- return;
-
- g_hash_table_destroy (evt->inserted_items);
- g_hash_table_destroy (evt->deleted_items);
- g_hash_table_destroy (evt->updated_items);
-
- g_hash_table_destroy (evt->orphan_items);
-
- g_list_free (evt->new_sources);
- g_list_free (evt->old_sources);
-
- if (evt->cursor != NULL)
- g_object_unref (evt->cursor);
-
- g_slice_free (tracker_evt_update_t, evt);
-}
-
-static void
-tracker_evt_update_source_add (tracker_evt_update_t *evt,
- const gchar *id,
- const gchar *source_name)
-{
- GrlTrackerSource *source;
- GrlTrackerSourcePriv *priv;
-
- source = g_hash_table_lookup (grl_tracker_modified_sources, id);
- if (!source) {
- source = g_object_new (GRL_TRACKER_SOURCE_TYPE,
- "source-id", id,
- "source-name", source_name,
- "source-desc", GRL_TRACKER_SOURCE_DESC,
- "tracker-connection", grl_tracker_connection,
- NULL);
- g_hash_table_insert (grl_tracker_modified_sources,
- (gpointer) grl_metadata_source_get_id (GRL_METADATA_SOURCE (source)),
- source);
- }
-
- priv = GRL_TRACKER_SOURCE_GET_PRIVATE (source);
- priv->state = GRL_TRACKER_SOURCE_STATE_INSERTING;
- priv->notification_ref++;
-
- evt->new_sources = g_list_append (evt->new_sources, source);
-
- GRL_DEBUG ("Preadd source p=%p name=%s id=%s count=%u",
- source, source_name, id, priv->notification_ref);
-}
-
-static void
-tracker_evt_update_source_del (tracker_evt_update_t *evt,
- GrlTrackerSource *source)
-{
- GrlTrackerSourcePriv *priv = GRL_TRACKER_SOURCE_GET_PRIVATE (source);
-
- priv->notification_ref++;
- priv->state = GRL_TRACKER_SOURCE_STATE_DELETING;
-
- evt->old_sources = g_list_append (evt->old_sources, source);
-
- GRL_DEBUG ("Predel source p=%p name=%s id=%s count=%u", source,
- grl_metadata_source_get_name (GRL_METADATA_SOURCE (source)),
- grl_metadata_source_get_id (GRL_METADATA_SOURCE (source)),
- priv->notification_ref);
-}
-
-static void
-tracker_evt_postupdate_sources (tracker_evt_update_t *evt)
-{
- GList *source;
-
- GRL_DEBUG ("%s: evt=%p", __FUNCTION__, evt);
-
- source = evt->old_sources;
- while (source != NULL) {
- grl_tracker_del_source (GRL_TRACKER_SOURCE (source->data));
- source = source->next;
- }
-
- source = evt->new_sources;
- while (source != NULL) {
- grl_tracker_add_source (GRL_TRACKER_SOURCE (source->data));
- source = source->next;
- }
-
- tracker_evt_update_free (evt);
-}
-
-static void
-tracker_evt_update_orphan_item_cb (GObject *object,
- GAsyncResult *result,
- tracker_evt_update_t *evt)
-{
- guint id;
- const gchar *type, *datasource;
- GrlTrackerSource *source = NULL;
- GError *error = NULL;
-
- GRL_DEBUG ("%s: evt=%p", __FUNCTION__, evt);
-
- if (!tracker_sparql_cursor_next_finish (evt->cursor, result, &error)) {
- if (error != NULL) {
- GRL_DEBUG ("\terror in parsing : %s", error->message);
- g_error_free (error);
- } else {
- GRL_DEBUG ("\tend of parsing...");
- }
-
- if (grl_tracker_per_device_source) {
- /* Once all items have been processed, add new sources and we're
- done. */
- tracker_evt_postupdate_sources (evt);
- }
-
- return;
- }
-
- type = tracker_sparql_cursor_get_string (evt->cursor, 0, NULL);
- id = tracker_sparql_cursor_get_integer (evt->cursor, 1);
- datasource = tracker_sparql_cursor_get_string (evt->cursor, 2, NULL);
-
- GRL_DEBUG ("\tOrphan item: id=%u datasource=%s", id, datasource);
-
- if (datasource)
- source = grl_tracker_source_find (datasource);
-
- if (source && GRL_IS_TRACKER_SOURCE (source)) {
- GrlMedia *media;
-
- GRL_DEBUG (" \tAdding to cache id=%u", id);
- grl_tracker_cache_add_item (grl_tracker_item_cache, id, source);
-
- if (grl_tracker_source_can_notify (source)) {
- media = grl_tracker_build_grilo_media (type);
- if (media) {
- gchar *str_id = g_strdup_printf ("%i", id);
- gint change_type =
- GPOINTER_TO_INT (g_hash_table_lookup (evt->orphan_items,
- GSIZE_TO_POINTER (id)));
-
- grl_media_set_id (media, str_id);
- g_free (str_id);
-
- GRL_DEBUG ("\tNotify id=%u source=%s p=%p", id,
- grl_metadata_source_get_name (GRL_METADATA_SOURCE (source)),
- source);
- grl_media_source_notify_change (GRL_MEDIA_SOURCE (source), media,
- change_type, FALSE);
-
- g_object_unref (media);
- }
- }
- }
-
- tracker_sparql_cursor_next_async (evt->cursor, NULL,
- (GAsyncReadyCallback) tracker_evt_update_orphan_item_cb,
- (gpointer) evt);
-}
-
-static void
-tracker_evt_update_orphans_cb (GObject *object,
- GAsyncResult *result,
- tracker_evt_update_t *evt)
-{
- GError *error = NULL;
-
- GRL_DEBUG ("%s: evt=%p", __FUNCTION__, evt);
-
- if (evt->cursor != NULL)
- g_object_unref (evt->cursor);
- evt->cursor = tracker_sparql_connection_query_finish (grl_tracker_connection,
- result, &error);
-
- if (error != NULL) {
- GRL_WARNING ("Could not execute sparql query: %s", error->message);
-
- g_error_free (error);
- tracker_evt_postupdate_sources (evt);
- return;
- }
-
- tracker_sparql_cursor_next_async (evt->cursor, NULL,
- (GAsyncReadyCallback) tracker_evt_update_orphan_item_cb,
- (gpointer) evt);
-}
-
-static void
-tracker_evt_update_orphans (tracker_evt_update_t *evt)
-{
- guint id;
- gchar *str_id;
- GString *request_str;
- GList *subject, *subjects;
- GrlMedia *media;
- GList *source, *sources;
-
- GRL_DEBUG ("%s: evt=%p", __FUNCTION__, evt);
-
- if (g_hash_table_size (evt->orphan_items) < 1) {
- tracker_evt_postupdate_sources (evt);
- return;
- }
-
- sources = grl_plugin_registry_get_sources (grl_plugin_registry_get_default (),
- FALSE);
-
- request_str = g_string_new (TRACKER_SOURCE_ITEM_START);
- subjects = g_hash_table_get_keys (evt->orphan_items);
-
- subject = subjects;
- while (subject != NULL) {
- id = GPOINTER_TO_INT (subject->data);
- if (GPOINTER_TO_INT (g_hash_table_lookup (evt->orphan_items,
- subject->data)) != GRL_CONTENT_REMOVED) {
- g_string_append_printf (request_str, "%u", id);
- break;
- } else {
- /* Notify all sources that a been removed */
- media = grl_media_new ();
- str_id = g_strdup_printf ("%u", id);
- grl_media_set_id (media, str_id);
- g_free (str_id);
-
- source = sources;
- while (source != NULL) {
- if (GRL_IS_TRACKER_SOURCE (source->data)) {
- GRL_DEBUG ("\tNotify id=%u source=%s p=%p", id,
- grl_metadata_source_get_name (GRL_METADATA_SOURCE (source->data)),
- source->data);
- if (grl_tracker_source_can_notify (GRL_TRACKER_SOURCE (source->data)))
- grl_media_source_notify_change (GRL_MEDIA_SOURCE (source->data),
- media, GRL_CONTENT_REMOVED, FALSE);
- }
- source = source->next;
- }
- g_object_unref (media);
- }
- subject = subject->next;
- }
-
- if (subject != NULL) {
- subject = subject->next;
- while (subject != NULL) {
- id = GPOINTER_TO_INT (subject->data);
- if (GPOINTER_TO_INT (g_hash_table_lookup (evt->orphan_items,
- subject->data)) != GRL_CONTENT_REMOVED) {
- g_string_append_printf (request_str, ", %u", id);
- } else {
- /* Notify all sources that a been removed */
- media = grl_media_new ();
- str_id = g_strdup_printf ("%u", id);
- grl_media_set_id (media, str_id);
- g_free (str_id);
-
- source = sources;
- while (source != NULL) {
- if (GRL_IS_TRACKER_SOURCE (source->data)) {
- GRL_DEBUG ("\tNotify id=%u source=%s p=%p", id,
- grl_metadata_source_get_name (GRL_METADATA_SOURCE (source->data)),
- source->data);
- if (grl_tracker_source_can_notify (GRL_TRACKER_SOURCE (source->data)))
- grl_media_source_notify_change (GRL_MEDIA_SOURCE (source->data),
- media, GRL_CONTENT_REMOVED, FALSE);
- }
- source = source->next;
- }
- g_object_unref (media);
- }
- subject = subject->next;
- }
- g_list_free (subjects);
-
- g_string_append (request_str, TRACKER_SOURCE_ITEM_END);
-
- GRL_DEBUG ("\trequest : '%s'", request_str->str);
-
- tracker_sparql_connection_query_async (grl_tracker_connection,
- request_str->str,
- NULL,
- (GAsyncReadyCallback) tracker_evt_update_orphans_cb,
- evt);
- } else {
- tracker_evt_postupdate_sources (evt);
- }
-
- g_string_free (request_str, TRUE);
-}
-
-static void
-tracker_evt_update_items_cb (gpointer key,
- gpointer value,
- tracker_evt_update_t *evt)
-{
- guint id = GPOINTER_TO_INT (key);
- gchar *str_id;
- GrlTrackerSource *source = (GrlTrackerSource *) value;
- GrlMedia *media;
-
- GRL_DEBUG ("%s: evt=%p", __FUNCTION__, evt);
-
- if (!source) {
- g_assert ("\tnot in cache ???");
- return;
- }
-
- if (!grl_tracker_source_can_notify (source)) {
- GRL_DEBUG ("\tno notification for source %s...",
- grl_metadata_source_get_name (GRL_METADATA_SOURCE (source)));
- return;
- }
-
- media = grl_media_new ();
- str_id = g_strdup_printf ("%i", id);
- grl_media_set_id (media, str_id);
- g_free (str_id);
-
- GRL_DEBUG ("\tNotify id=%u source=%s", id,
- grl_metadata_source_get_name (GRL_METADATA_SOURCE (source)));
- grl_media_source_notify_change (GRL_MEDIA_SOURCE (source), media,
- evt->change_type, FALSE);
-
- g_object_unref (media);
-}
-
-static void
-tracker_evt_update_items (tracker_evt_update_t *evt)
-{
- evt->change_type = GRL_CONTENT_REMOVED;
- g_hash_table_foreach (evt->deleted_items,
- (GHFunc) tracker_evt_update_items_cb, evt);
- evt->change_type = GRL_CONTENT_ADDED;
- g_hash_table_foreach (evt->inserted_items,
- (GHFunc) tracker_evt_update_items_cb, evt);
- evt->change_type = GRL_CONTENT_CHANGED;
- g_hash_table_foreach (evt->updated_items,
- (GHFunc) tracker_evt_update_items_cb, evt);
-}
-
-static void
-tracker_evt_preupdate_sources_item_cb (GObject *object,
- GAsyncResult *result,
- tracker_evt_update_t *evt)
-{
- const gchar *type, *datasource, *uri, *datasource_name;
- gboolean source_available;
- GrlTrackerSource *source;
- GError *error = NULL;
-
- GRL_DEBUG ("%s: evt=%p", __FUNCTION__, evt);
-
- if (!tracker_sparql_cursor_next_finish (evt->cursor, result, &error)) {
- if (error != NULL) {
- GRL_DEBUG ("\terror in parsing : %s", error->message);
- g_error_free (error);
- } else {
- GRL_DEBUG ("\tend of parsing... start notifying sources");
- }
-
- /* Once all sources have been preupdated, start items
- updates. */
- tracker_evt_update_items (evt);
- tracker_evt_update_orphans (evt);
-
- return;
- }
-
- type = tracker_sparql_cursor_get_string (evt->cursor, 0, NULL);
- datasource = tracker_sparql_cursor_get_string (evt->cursor, 1, NULL);
- datasource_name = tracker_sparql_cursor_get_string (evt->cursor, 2, NULL);
- uri = tracker_sparql_cursor_get_string (evt->cursor, 3, NULL);
- source_available = tracker_sparql_cursor_get_boolean (evt->cursor, 4);
-
- source = grl_tracker_source_find (datasource);
-
- GRL_DEBUG ("\tdatasource=%s uri=%s available=%i source=%p",
- datasource, uri, source_available, source);
-
- if (source_available) {
- if (source == NULL) {
- gchar *source_name = grl_tracker_get_source_name (type, uri, datasource,
- datasource_name);
- /* Defer source creation until we have processed all sources */
- tracker_evt_update_source_add (evt, datasource, source_name);
- g_free (source_name);
- } else {
- GRL_DEBUG ("\tChanges on source %p / %s", source, datasource);
- }
- } else if (!source_available && source != NULL) {
- tracker_evt_update_source_del (evt, GRL_TRACKER_SOURCE (source));
- }
-
- tracker_sparql_cursor_next_async (evt->cursor, NULL,
- (GAsyncReadyCallback) tracker_evt_preupdate_sources_item_cb,
- (gpointer) evt);
-}
-
-static void
-tracker_evt_preupdate_sources_cb (GObject *object,
- GAsyncResult *result,
- tracker_evt_update_t *evt)
-{
- GError *error = NULL;
-
- GRL_DEBUG ("%s: evt=%p", __FUNCTION__, evt);
-
- if (evt->cursor != NULL)
- g_object_unref (evt->cursor);
- evt->cursor = tracker_sparql_connection_query_finish (grl_tracker_connection,
- result, &error);
-
- if (error != NULL) {
- GRL_WARNING ("\tCannot handle datasource request : %s", error->message);
-
- g_error_free (error);
- tracker_evt_update_free (evt);
- return;
- }
-
- tracker_sparql_cursor_next_async (evt->cursor, NULL,
- (GAsyncReadyCallback) tracker_evt_preupdate_sources_item_cb,
- (gpointer) evt);
-}
-
-static void
-tracker_evt_preupdate_sources (tracker_evt_update_t *evt)
-{
- tracker_sparql_connection_query_async (grl_tracker_connection,
- TRACKER_DATASOURCES_REQUEST,
- NULL,
- (GAsyncReadyCallback) tracker_evt_preupdate_sources_cb,
- evt);
-}
-
-static void
-tracker_dbus_signal_cb (GDBusConnection *connection,
- const gchar *sender_name,
- const gchar *object_path,
- const gchar *interface_name,
- const gchar *signal_name,
- GVariant *parameters,
- gpointer user_data)
-
-{
- gchar *class_name;
- gint graph = 0, subject = 0, predicate = 0, object = 0;
- GVariantIter *iter1, *iter2;
- tracker_evt_update_t *evt = tracker_evt_update_new ();
-
- g_variant_get (parameters, "(&sa(iiii)a(iiii))", &class_name, &iter1, &iter2);
-
- GRL_DEBUG ("\tTracker update event for class=%s ins=%lu del=%lu evt=%p",
- class_name,
- (unsigned long) g_variant_iter_n_children (iter1),
- (unsigned long) g_variant_iter_n_children (iter2),
- evt);
-
- /* Avoid processing item from uninteresting classes */
- if (g_str_has_suffix (class_name, RDF_TYPE_MUSIC) ||
- g_str_has_suffix (class_name, RDF_TYPE_AUDIO) ||
- g_str_has_suffix (class_name, RDF_TYPE_VIDEO) ||
- g_str_has_suffix (class_name, RDF_TYPE_IMAGE)) {
-
- /* Process deleted items */
- while (g_variant_iter_loop (iter1, "(iiii)", &graph,
- &subject, &predicate, &object)) {
- gpointer psubject = GSIZE_TO_POINTER (subject);
- GrlTrackerSource *source =
- grl_tracker_cache_get_source (grl_tracker_item_cache, subject);
-
- /* GRL_DEBUG ("\tdelete=> subject=%i", subject); */
-
- if (source) {
- g_hash_table_insert (evt->deleted_items, psubject,
- g_object_ref (source));
- } else {
- g_hash_table_insert (evt->orphan_items, psubject,
- GSIZE_TO_POINTER (GRL_CONTENT_REMOVED));
- }
- }
-
- /* Process inserted items */
- while (g_variant_iter_loop (iter2, "(iiii)", &graph,
- &subject, &predicate, &object)) {
- gpointer psubject = GSIZE_TO_POINTER (subject);
- GrlTrackerSource *source =
- grl_tracker_cache_get_source (grl_tracker_item_cache, subject);
-
- /* GRL_DEBUG ("\tinsert=> subject=%i", subject); */
-
- if (source) {
- /* Removed & inserted items are probably just renamed items... */
- if (g_hash_table_lookup (evt->deleted_items, psubject)) {
- g_hash_table_remove (evt->deleted_items, psubject);
- g_hash_table_insert (evt->updated_items, psubject,
- g_object_ref (source));
- } else if (!g_hash_table_lookup (evt->updated_items, psubject)) {
- g_hash_table_insert (evt->inserted_items, psubject,
- g_object_ref (source));
- }
- } else {
- gpointer state;
-
- if (g_hash_table_lookup_extended (evt->orphan_items, psubject,
- NULL, &state) &&
- (GPOINTER_TO_INT (state) == GRL_CONTENT_REMOVED)) {
- g_hash_table_insert (evt->orphan_items, psubject,
- GSIZE_TO_POINTER (GRL_CONTENT_CHANGED));
- } else {
- g_hash_table_insert (evt->orphan_items, psubject,
- GSIZE_TO_POINTER (GRL_CONTENT_ADDED));
- }
- }
- }
- }
-
- g_variant_iter_free (iter1);
- g_variant_iter_free (iter2);
-
- GRL_DEBUG ("\tinserted=%i deleted=%i updated=%i orphan=%i",
- g_hash_table_size (evt->inserted_items),
- g_hash_table_size (evt->deleted_items),
- g_hash_table_size (evt->updated_items),
- g_hash_table_size (evt->orphan_items));
-
- if (grl_tracker_per_device_source) {
- tracker_evt_preupdate_sources (evt);
- } else {
- tracker_evt_update_items (evt);
- tracker_evt_update_orphans (evt);
- }
-}
-
-void
-grl_tracker_dbus_start_watch (void)
-{
- GDBusConnection *connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
-
- tracker_dbus_signal_id = g_dbus_connection_signal_subscribe (connection,
- TRACKER_DBUS_SERVICE,
- TRACKER_DBUS_INTERFACE_RESOURCES,
- "GraphUpdated",
- TRACKER_DBUS_OBJECT_RESOURCES,
- NULL,
- G_DBUS_SIGNAL_FLAGS_NONE,
- tracker_dbus_signal_cb,
- NULL,
- NULL);
-}
-
-void
-grl_tracker_init_notifs (void)
-{
- GRL_LOG_DOMAIN_INIT (tracker_notif_log_domain, "tracker-notif");
-}
diff --git a/src/media/tracker/grl-tracker-notif.h b/src/media/tracker/grl-tracker-notif.h
deleted file mode 100644
index a288fc3..0000000
--- a/src/media/tracker/grl-tracker-notif.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2011 Intel Corporation.
- *
- * Contact: Iago Toral Quiroga <itoral igalia com>
- *
- * Authors: 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
- * 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_TRACKER_NOTIF_H_
-#define _GRL_TRACKER_NOTIF_H_
-
-#include "grl-tracker.h"
-
-/* ------- Definitions ------- */
-
-#define TRACKER_DATASOURCES_REQUEST \
- "SELECT " \
- "(SELECT GROUP_CONCAT(rdf:type(?source), \":\") " \
- " WHERE { ?urn nie:dataSource ?source }) " \
- "nie:dataSource(?urn) " \
- "(SELECT GROUP_CONCAT(nie:title(?source), \":\") " \
- " WHERE { ?urn nie:dataSource ?source }) " \
- "(SELECT GROUP_CONCAT(nie:url(tracker:mountPoint(?source)), \":\") " \
- " WHERE { ?urn nie:dataSource ?source }) " \
- "tracker:available(?urn) " \
- "WHERE " \
- "{ " \
- "?urn a nfo:FileDataObject . FILTER (bound(nie:dataSource(?urn)))" \
- "} " \
- "GROUP BY (nie:dataSource(?urn))"
-
-/**/
-
-void grl_tracker_dbus_start_watch (void);
-
-void grl_tracker_init_notifs (void);
-
-#endif /* _GRL_TRACKER_NOTIF_H_ */
diff --git a/src/media/tracker/grl-tracker-priv.h b/src/media/tracker/grl-tracker-priv.h
deleted file mode 100644
index 8b9bbe0..0000000
--- a/src/media/tracker/grl-tracker-priv.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2011 Intel Corporation.
- *
- * Contact: Iago Toral Quiroga <itoral igalia com>
- *
- * Authors: 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
- * 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_TRACKER_PRIV_H_
-#define _GRL_TRACKER_PRIV_H_
-
-#include "grl-tracker.h"
-#include "grl-tracker-cache.h"
-
-#include <tracker-sparql.h>
-
-/* ---- Plugin information --- */
-
-#define GRL_TRACKER_PLUGIN_ID TRACKER_PLUGIN_ID
-
-#define GRL_TRACKER_SOURCE_ID "grl-tracker"
-#define GRL_TRACKER_SOURCE_NAME "Tracker"
-#define GRL_TRACKER_SOURCE_DESC \
- "A plugin for searching multimedia " \
- "content using Tracker"
-
-#define GRL_TRACKER_AUTHOR "Igalia S.L."
-#define GRL_TRACKER_LICENSE "LGPL"
-#define GRL_TRACKER_SITE "http://www.igalia.com"
-
-/**/
-
-#define GRL_TRACKER_SOURCE_GET_PRIVATE(object) \
- (G_TYPE_INSTANCE_GET_PRIVATE((object), \
- GRL_TRACKER_SOURCE_TYPE, \
- GrlTrackerSourcePriv))
-
-typedef enum {
- GRL_TRACKER_SOURCE_STATE_INSERTING,
- GRL_TRACKER_SOURCE_STATE_RUNNING,
- GRL_TRACKER_SOURCE_STATE_DELETING,
- GRL_TRACKER_SOURCE_STATE_DELETED,
-} GrlTrackerSourceState;
-
-struct _GrlTrackerSourcePriv {
- TrackerSparqlConnection *tracker_connection;
-
- GHashTable *operations;
-
- gchar *tracker_datasource;
- gboolean notify_changes;
-
- GrlTrackerSourceState state;
- guint notification_ref;
-};
-
-/**/
-
-extern TrackerSparqlConnection *grl_tracker_connection;
-extern const GrlPluginInfo *grl_tracker_plugin;
-
-/* shared data across */
-extern GrlTrackerCache *grl_tracker_item_cache;
-extern GHashTable *grl_tracker_modified_sources;
-
-/* tracker plugin config */
-extern gboolean grl_tracker_per_device_source;
-extern gboolean grl_tracker_browse_filesystem;
-
-#endif /* _GRL_TRACKER_PRIV_H_ */
diff --git a/src/media/tracker/grl-tracker-utils.c b/src/media/tracker/grl-tracker-utils.c
index ef06b5b..bc77ed1 100644
--- a/src/media/tracker/grl-tracker-utils.c
+++ b/src/media/tracker/grl-tracker-utils.c
@@ -23,7 +23,6 @@
*/
#include "grl-tracker-utils.h"
-#include "grl-tracker-priv.h"
/**/
@@ -165,7 +164,7 @@ get_mapping_from_grl (const GrlKeyID key)
/**/
gchar *
-grl_tracker_source_get_device_constraint (GrlTrackerSourcePriv *priv)
+grl_tracker_media_get_device_constraint (GrlTrackerMediaPriv *priv)
{
if (priv->tracker_datasource == NULL)
return g_strdup ("");
@@ -175,8 +174,8 @@ grl_tracker_source_get_device_constraint (GrlTrackerSourcePriv *priv)
}
gchar *
-grl_tracker_source_get_select_string (GrlMediaSource *source,
- const GList *keys)
+grl_tracker_media_get_select_string (GrlMediaSource *source,
+ const GList *keys)
{
const GList *key = keys;
GString *gstr = g_string_new ("");
@@ -295,10 +294,10 @@ get_tracker_upnp_name (const gchar *datasource_name)
}
gchar *
-grl_tracker_get_source_name (const gchar *rdf_type,
- const gchar *uri,
- const gchar *datasource,
- const gchar *datasource_name)
+grl_tracker_get_media_name (const gchar *rdf_type,
+ const gchar *uri,
+ const gchar *datasource,
+ const gchar *datasource_name)
{
gchar *source_name = NULL;
gchar **rdf_single_type;
@@ -323,7 +322,7 @@ grl_tracker_get_source_name (const gchar *rdf_type,
if (!source_name)
source_name = g_strdup_printf ("%s %s",
- GRL_TRACKER_SOURCE_NAME,
+ GRL_TRACKER_MEDIA_NAME,
datasource);
return source_name;
diff --git a/src/media/tracker/grl-tracker-utils.h b/src/media/tracker/grl-tracker-utils.h
index 09cc679..881828e 100644
--- a/src/media/tracker/grl-tracker-utils.h
+++ b/src/media/tracker/grl-tracker-utils.h
@@ -25,7 +25,7 @@
#ifndef _GRL_TRACKER_UTILS_H_
#define _GRL_TRACKER_UTILS_H_
-#include "grl-tracker.h"
+#include "grl-tracker-media-priv.h"
/* ------- Definitions ------- */
@@ -57,14 +57,14 @@ tracker_grl_sparql_t *grl_tracker_get_mapping_from_sparql (const gchar *key);
GrlMedia *grl_tracker_build_grilo_media (const gchar *rdf_type);
-gchar *grl_tracker_source_get_device_constraint (GrlTrackerSourcePriv *priv);
+gchar *grl_tracker_media_get_device_constraint (GrlTrackerMediaPriv *priv);
-gchar *grl_tracker_source_get_select_string (GrlMediaSource *source,
- const GList *keys);
+gchar *grl_tracker_media_get_select_string (GrlMediaSource *source,
+ const GList *keys);
-gchar *grl_tracker_get_source_name (const gchar *rdf_type,
- const gchar *uri,
- const gchar *datasource,
- const gchar *datasource_name);
+gchar *grl_tracker_get_media_name (const gchar *rdf_type,
+ const gchar *uri,
+ const gchar *datasource,
+ const gchar *datasource_name);
#endif /* _GRL_TRACKER_UTILS_H_ */
diff --git a/src/media/tracker/grl-tracker.c b/src/media/tracker/grl-tracker.c
deleted file mode 100644
index f862e9b..0000000
--- a/src/media/tracker/grl-tracker.c
+++ /dev/null
@@ -1,416 +0,0 @@
-/*
- * Copyright (C) 2011 Igalia S.L.
- * Copyright (C) 2011 Intel Corporation.
- *
- * Contact: Iago Toral Quiroga <itoral igalia com>
- *
- * Authors: Juan A. Suarez Romero <jasuarez 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 <string.h>
-#include <tracker-sparql.h>
-
-#include "grl-tracker.h"
-#include "grl-tracker-priv.h"
-#include "grl-tracker-api.h"
-#include "grl-tracker-cache.h"
-#include "grl-tracker-notif.h"
-#include "grl-tracker-utils.h"
-
-/* --------- Logging -------- */
-
-#define GRL_LOG_DOMAIN_DEFAULT tracker_general_log_domain
-GRL_LOG_DOMAIN_STATIC(tracker_general_log_domain);
-
-/* ------- Definitions ------- */
-
-#define MEDIA_TYPE "grilo-media-type"
-
-#define TRACKER_ITEM_CACHE_SIZE (10000)
-
-/* --- Other --- */
-
-enum {
- PROP_0,
- PROP_TRACKER_CONNECTION,
-};
-
-static GrlTrackerSource *grl_tracker_source_new (TrackerSparqlConnection *connection);
-
-static void grl_tracker_source_set_property (GObject *object,
- guint propid,
- const GValue *value,
- GParamSpec *pspec);
-
-static void grl_tracker_source_constructed (GObject *object);
-
-static void grl_tracker_source_finalize (GObject *object);
-
-gboolean grl_tracker_plugin_init (GrlPluginRegistry *registry,
- const GrlPluginInfo *plugin,
- GList *configs);
-
-/* ===================== Globals ================= */
-
-TrackerSparqlConnection *grl_tracker_connection = NULL;
-const GrlPluginInfo *grl_tracker_plugin;
-
-/* shared data across */
-GrlTrackerCache *grl_tracker_item_cache;
-GHashTable *grl_tracker_modified_sources;
-
-/* tracker plugin config */
-gboolean grl_tracker_per_device_source = FALSE;
-gboolean grl_tracker_browse_filesystem = FALSE;
-
-/* =================== Tracker Plugin =============== */
-
-void
-grl_tracker_add_source (GrlTrackerSource *source)
-{
- GrlTrackerSourcePriv *priv = GRL_TRACKER_SOURCE_GET_PRIVATE (source);
-
- GRL_DEBUG ("====================>add source '%s' count=%u",
- grl_metadata_source_get_name (GRL_METADATA_SOURCE (source)),
- priv->notification_ref);
-
- if (priv->notification_ref > 0) {
- priv->notification_ref--;
- }
- if (priv->notification_ref == 0) {
- g_hash_table_remove (grl_tracker_modified_sources,
- grl_metadata_source_get_id (GRL_METADATA_SOURCE (source)));
- priv->state = GRL_TRACKER_SOURCE_STATE_RUNNING;
- grl_plugin_registry_register_source (grl_plugin_registry_get_default (),
- grl_tracker_plugin,
- GRL_MEDIA_PLUGIN (source),
- NULL);
- }
-}
-
-void
-grl_tracker_del_source (GrlTrackerSource *source)
-{
- GrlTrackerSourcePriv *priv = GRL_TRACKER_SOURCE_GET_PRIVATE (source);
-
- GRL_DEBUG ("==================>del source '%s' count=%u",
- grl_metadata_source_get_name (GRL_METADATA_SOURCE (source)),
- priv->notification_ref);
- if (priv->notification_ref > 0) {
- priv->notification_ref--;
- }
- if (priv->notification_ref == 0) {
- g_hash_table_remove (grl_tracker_modified_sources,
- grl_metadata_source_get_id (GRL_METADATA_SOURCE (source)));
- grl_tracker_cache_del_source (grl_tracker_item_cache, source);
- priv->state = GRL_TRACKER_SOURCE_STATE_DELETED;
- grl_plugin_registry_unregister_source (grl_plugin_registry_get_default (),
- GRL_MEDIA_PLUGIN (source),
- NULL);
- }
-}
-
-gboolean
-grl_tracker_source_can_notify (GrlTrackerSource *source)
-{
- GrlTrackerSourcePriv *priv = GRL_TRACKER_SOURCE_GET_PRIVATE (source);
-
- if (priv->state == GRL_TRACKER_SOURCE_STATE_RUNNING)
- return priv->notify_changes;
-
- return FALSE;
-}
-
-GrlTrackerSource *
-grl_tracker_source_find (const gchar *id)
-{
- GrlMediaPlugin *source;
-
- source = grl_plugin_registry_lookup_source (grl_plugin_registry_get_default (),
- id);
-
- if (source && GRL_IS_TRACKER_SOURCE (source)) {
- return (GrlTrackerSource *) source;
- }
-
- return
- (GrlTrackerSource *) g_hash_table_lookup (grl_tracker_modified_sources,
- id);
-}
-
-static void
-tracker_get_datasource_cb (GObject *object,
- GAsyncResult *result,
- TrackerSparqlCursor *cursor)
-{
- const gchar *type, *datasource, *datasource_name, *uri;
- gboolean source_available;
- GError *error = NULL;
- GrlTrackerSource *source;
-
- GRL_DEBUG ("%s", __FUNCTION__);
-
- if (!tracker_sparql_cursor_next_finish (cursor, result, &error)) {
- if (error == NULL) {
- GRL_DEBUG ("\tEnd of parsing of devices");
- } else {
- GRL_WARNING ("\tError while parsing devices: %s", error->message);
- g_error_free (error);
- }
- g_object_unref (G_OBJECT (cursor));
- return;
- }
-
- type = tracker_sparql_cursor_get_string (cursor, 0, NULL);
- datasource = tracker_sparql_cursor_get_string (cursor, 1, NULL);
- datasource_name = tracker_sparql_cursor_get_string (cursor, 2, NULL);
- uri = tracker_sparql_cursor_get_string (cursor, 3, NULL);
- source_available = tracker_sparql_cursor_get_boolean (cursor, 4);
-
- source = grl_tracker_source_find (datasource);
-
- if ((source == NULL) && source_available) {
- gchar *source_name = grl_tracker_get_source_name (type, uri, datasource,
- datasource_name);
- GRL_DEBUG ("\tnew datasource: urn=%s name=%s uri=%s\n",
- datasource, datasource_name, uri);
- source = g_object_new (GRL_TRACKER_SOURCE_TYPE,
- "source-id", datasource,
- "source-name", source_name,
- "source-desc", GRL_TRACKER_SOURCE_DESC,
- "tracker-connection", grl_tracker_connection,
- NULL);
- grl_tracker_add_source (source);
- g_free (source_name);
- }
-
- tracker_sparql_cursor_next_async (cursor, NULL,
- (GAsyncReadyCallback) tracker_get_datasource_cb,
- cursor);
-}
-
-static void
-tracker_get_datasources_cb (GObject *object,
- GAsyncResult *result,
- gpointer data)
-{
- GError *error = NULL;
- TrackerSparqlCursor *cursor;
-
- GRL_DEBUG ("%s", __FUNCTION__);
-
- cursor = tracker_sparql_connection_query_finish (grl_tracker_connection,
- result, &error);
-
- if (error) {
- GRL_WARNING ("Cannot handle datasource request : %s", error->message);
- g_error_free (error);
- return;
- }
-
- tracker_sparql_cursor_next_async (cursor, NULL,
- (GAsyncReadyCallback) tracker_get_datasource_cb,
- cursor);
-}
-
-static void
-tracker_get_connection_cb (GObject *object,
- GAsyncResult *res,
- const GrlPluginInfo *plugin)
-{
- /* GrlTrackerSource *source; */
-
- GRL_DEBUG ("%s", __FUNCTION__);
-
- grl_tracker_connection = tracker_sparql_connection_get_finish (res, NULL);
-
- if (grl_tracker_connection != NULL) {
- grl_tracker_dbus_start_watch ();
-
- if (grl_tracker_per_device_source == TRUE) {
- /* Let's discover available data sources. */
- GRL_DEBUG ("\tper device source mode request: '"
- TRACKER_DATASOURCES_REQUEST "'");
-
- tracker_sparql_connection_query_async (grl_tracker_connection,
- TRACKER_DATASOURCES_REQUEST,
- NULL,
- (GAsyncReadyCallback) tracker_get_datasources_cb,
- NULL);
- } else {
- /* One source to rule them all. */
- grl_tracker_add_source (grl_tracker_source_new (grl_tracker_connection));
- }
- }
-}
-
-gboolean
-grl_tracker_plugin_init (GrlPluginRegistry *registry,
- const GrlPluginInfo *plugin,
- GList *configs)
-{
- GrlConfig *config;
- gint config_count;
-
- GRL_DEBUG ("%s", __FUNCTION__);
-
- GRL_LOG_DOMAIN_INIT (tracker_general_log_domain, "tracker-general");
- grl_tracker_init_notifs ();
- grl_tracker_init_requests ();
-
- grl_tracker_plugin = plugin;
- grl_tracker_item_cache = grl_tracker_cache_new (TRACKER_ITEM_CACHE_SIZE);
- grl_tracker_modified_sources = g_hash_table_new (g_str_hash, g_str_equal);
-
- if (!configs) {
- GRL_WARNING ("\tConfiguration not provided! Using default configuration.");
- } else {
- config_count = g_list_length (configs);
- if (config_count > 1) {
- GRL_WARNING ("\tProvided %i configs, but will only use one", config_count);
- }
-
- config = GRL_CONFIG (configs->data);
-
- grl_tracker_per_device_source =
- grl_config_get_boolean (config, "per-device-source");
- grl_tracker_browse_filesystem =
- grl_config_get_boolean (config, "browse-filesystem");
- }
-
- tracker_sparql_connection_get_async (NULL,
- (GAsyncReadyCallback) tracker_get_connection_cb,
- (gpointer) plugin);
- return TRUE;
-}
-
-GRL_PLUGIN_REGISTER (grl_tracker_plugin_init,
- NULL,
- GRL_TRACKER_PLUGIN_ID);
-
-/* ================== Tracker GObject ================ */
-
-static GrlTrackerSource *
-grl_tracker_source_new (TrackerSparqlConnection *connection)
-{
- GRL_DEBUG ("%s", __FUNCTION__);
-
- return g_object_new (GRL_TRACKER_SOURCE_TYPE,
- "source-id", GRL_TRACKER_SOURCE_ID,
- "source-name", GRL_TRACKER_SOURCE_NAME,
- "source-desc", GRL_TRACKER_SOURCE_DESC,
- "tracker-connection", connection,
- NULL);
-}
-
-G_DEFINE_TYPE (GrlTrackerSource, grl_tracker_source, GRL_TYPE_MEDIA_SOURCE);
-
-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->query = grl_tracker_source_query;
- source_class->metadata = grl_tracker_source_metadata;
- source_class->search = grl_tracker_source_search;
- source_class->browse = grl_tracker_source_browse;
- source_class->cancel = grl_tracker_source_cancel;
- source_class->notify_change_start = grl_tracker_source_change_start;
- source_class->notify_change_stop = grl_tracker_source_change_stop;
-
- metadata_class->supported_keys = grl_tracker_source_supported_keys;
-
- g_class->finalize = grl_tracker_source_finalize;
- g_class->set_property = grl_tracker_source_set_property;
- g_class->constructed = grl_tracker_source_constructed;
-
- g_object_class_install_property (g_class,
- PROP_TRACKER_CONNECTION,
- g_param_spec_object ("tracker-connection",
- "tracker connection",
- "A Tracker connection",
- TRACKER_SPARQL_TYPE_CONNECTION,
- G_PARAM_WRITABLE
- | G_PARAM_CONSTRUCT_ONLY
- | G_PARAM_STATIC_NAME));
-
- g_type_class_add_private (klass, sizeof (GrlTrackerSourcePriv));
-
- grl_tracker_setup_key_mappings ();
-}
-
-static void
-grl_tracker_source_init (GrlTrackerSource *source)
-{
- GrlTrackerSourcePriv *priv = GRL_TRACKER_SOURCE_GET_PRIVATE (source);
-
- source->priv = priv;
-
- priv->operations = g_hash_table_new (g_direct_hash, g_direct_equal);
-}
-
-static void
-grl_tracker_source_constructed (GObject *object)
-{
- GrlTrackerSourcePriv *priv = GRL_TRACKER_SOURCE_GET_PRIVATE (object);
-
- if (grl_tracker_per_device_source)
- g_object_get (object, "source-id", &priv->tracker_datasource, NULL);
-}
-
-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_set_property (GObject *object,
- guint propid,
- const GValue *value,
- GParamSpec *pspec)
-
-{
- GrlTrackerSourcePriv *priv = GRL_TRACKER_SOURCE_GET_PRIVATE (object);
-
- switch (propid) {
- case PROP_TRACKER_CONNECTION:
- if (priv->tracker_connection != NULL)
- g_object_unref (G_OBJECT (priv->tracker_connection));
- priv->tracker_connection = g_object_ref (g_value_get_object (value));
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
- }
-}
-
diff --git a/src/media/tracker/grl-tracker.h b/src/media/tracker/grl-tracker.h
deleted file mode 100644
index 2d9cd47..0000000
--- a/src/media/tracker/grl-tracker.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2011 Igalia S.L.
- *
- * Contact: Iago Toral Quiroga <itoral igalia com>
- *
- * Authors: Juan A. Suarez Romero <jasuarez 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_TRACKER_H_
-#define _GRL_TRACKER_H_
-
-#include <grilo.h>
-
-#define GRL_TRACKER_SOURCE_TYPE \
- (grl_tracker_source_get_type ())
-
-#define GRL_TRACKER_SOURCE(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
- GRL_TRACKER_SOURCE_TYPE, \
- GrlTrackerSource))
-
-#define GRL_IS_TRACKER_SOURCE(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
- GRL_TRACKER_SOURCE_TYPE))
-
-#define GRL_TRACKER_SOURCE_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass), \
- GRL_TRACKER_SOURCE_TYPE, \
- GrlTrackerSourceClass))
-
-#define GRL_IS_TRACKER_SOURCE_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass), \
- GRL_TRACKER_SOURCE_TYPE))
-
-#define GRL_TRACKER_SOURCE_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), \
- GRL_TRACKER_SOURCE_TYPE, \
- GrlTrackerSourceClass))
-
-typedef struct _GrlTrackerSource GrlTrackerSource;
-typedef struct _GrlTrackerSourcePriv GrlTrackerSourcePriv;
-
-struct _GrlTrackerSource {
-
- GrlMediaSource parent;
-
- /*< private >*/
- GrlTrackerSourcePriv *priv;
-
-};
-
-typedef struct _GrlTrackerSourceClass GrlTrackerSourceClass;
-
-struct _GrlTrackerSourceClass {
-
- GrlMediaSourceClass parent_class;
-
-};
-
-GType grl_tracker_source_get_type (void);
-
-gboolean grl_tracker_source_can_notify (GrlTrackerSource *source);
-
-/**/
-void grl_tracker_add_source (GrlTrackerSource *source);
-
-void grl_tracker_del_source (GrlTrackerSource *source);
-
-GrlTrackerSource *grl_tracker_source_find (const gchar *id);
-
-
-#endif /* _GRL_TRACKER_H_ */
--
1.7.4.1
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]