[grilo-plugins/wip/carlosg/tracker3: 31/41] tracker3: Port store_metadata to tracker3



commit 1574246acb0cd75e5abcd61ead69249ec86a3d96
Author: Carlos Garnacho <carlosg gnome org>
Date:   Sun May 24 18:13:33 2020 +0200

    tracker3: Port store_metadata to tracker3
    
    The data stored by miner-fs is no longer considered readwrite for
    all. These updates used to trigger the tracker writeback service
    which would rewrite file metadata and make everything match again.
    Make this use the writeback service directly, the miner-fs data
    will then be updated indirectly.

 src/tracker3/grl-tracker-source-api.c  |  84 ++++++++-----------------
 src/tracker3/grl-tracker-source-priv.h |   1 +
 src/tracker3/grl-tracker-source.c      |  18 ++++++
 src/tracker3/grl-tracker-utils.c       | 112 +++++++++++++++++++++++++++++++++
 src/tracker3/grl-tracker-utils.h       |   2 +
 5 files changed, 158 insertions(+), 59 deletions(-)
---
diff --git a/src/tracker3/grl-tracker-source-api.c b/src/tracker3/grl-tracker-source-api.c
index 11143749..5ffc4728 100644
--- a/src/tracker3/grl-tracker-source-api.c
+++ b/src/tracker3/grl-tracker-source-api.c
@@ -55,15 +55,6 @@ GRL_LOG_DOMAIN_STATIC(tracker_source_result_log_domain);
   GRL_LOG (tracker_source_result_log_domain,    \
            GRL_LOG_LEVEL_DEBUG, args)
 
-/* ------- Definitions ------- */
-
-#define TRACKER_DELETE_REQUEST                          \
-  "DELETE { <%s> %s } WHERE { <%s> a nfo:Media . %s }"
-
-#define TRACKER_SAVE_REQUEST                            \
-  "DELETE { <%s> %s } WHERE { <%s> a nfo:Media . %s } " \
-  "INSERT { <%s> a nfo:Media ; %s . }"
-
 /**/
 
 /**/
@@ -470,15 +461,13 @@ tracker_store_metadata_cb (GObject      *source_object,
 {
   GrlSourceStoreMetadataSpec *sms =
     (GrlSourceStoreMetadataSpec *) os->data;
-  GrlTrackerSourcePriv *priv = GRL_TRACKER_SOURCE_GET_PRIVATE (sms->source);
   GError *tracker_error = NULL, *error = NULL;
 
-  tracker_sparql_connection_update_finish (priv->tracker_connection,
-                                           result,
-                                           &tracker_error);
+  g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object),
+                            result, &tracker_error);
 
   if (tracker_error) {
-    GRL_WARNING ("Could not execute sparql update : %s",
+    GRL_WARNING ("Could not writeback metadata: %s",
                  tracker_error->message);
 
     error = g_error_new (GRL_CORE_ERROR,
@@ -491,7 +480,7 @@ tracker_store_metadata_cb (GObject      *source_object,
     g_error_free (tracker_error);
     g_error_free (error);
   } else {
-    sms->callback (sms->source, sms->media, NULL, sms->user_data, error);
+    sms->callback (sms->source, sms->media, NULL, sms->user_data, NULL);
   }
 
   grl_tracker_op_free (os);
@@ -503,22 +492,19 @@ const GList *
 grl_tracker_source_writable_keys (GrlSource *source)
 {
   static GList *keys = NULL;
-  GrlRegistry *registry;
-  GrlKeyID grl_metadata_key_chromaprint;
 
   if (!keys) {
-    registry = grl_registry_get_default ();
-    grl_metadata_key_chromaprint = grl_registry_lookup_metadata_key (registry, "chromaprint");
-
-    keys = grl_metadata_key_list_new (GRL_METADATA_KEY_PLAY_COUNT,
-                                      GRL_METADATA_KEY_LAST_PLAYED,
-                                      GRL_METADATA_KEY_LAST_POSITION,
-                                      GRL_METADATA_KEY_FAVOURITE,
-                                      GRL_METADATA_KEY_TITLE,
-                                      GRL_METADATA_KEY_TRACK_NUMBER,
+    keys = grl_metadata_key_list_new (GRL_METADATA_KEY_ALBUM,
+                                      GRL_METADATA_KEY_ALBUM_DISC_NUMBER,
+                                      GRL_METADATA_KEY_ARTIST,
+                                      GRL_METADATA_KEY_ALBUM_ARTIST,
+                                      GRL_METADATA_KEY_AUTHOR,
+                                      GRL_METADATA_KEY_COMPOSER,
                                       GRL_METADATA_KEY_CREATION_DATE,
-                                      grl_metadata_key_chromaprint,
-                                      NULL);
+                                      GRL_METADATA_KEY_TITLE,
+                                      GRL_METADATA_KEY_SEASON,
+                                      GRL_METADATA_KEY_EPISODE,
+                                      GRL_METADATA_KEY_TRACK_NUMBER);
   }
   return keys;
 }
@@ -713,42 +699,22 @@ grl_tracker_source_store_metadata (GrlSource *source,
                                    GrlSourceStoreMetadataSpec *sms)
 {
   GrlTrackerSourcePriv *priv = GRL_TRACKER_SOURCE_GET_PRIVATE (source);
-  gchar *sparql_delete, *sparql_cdelete, *sparql_insert, *sparql_final;
-  const gchar *urn = grl_data_get_string (GRL_DATA (sms->media),
-                                          grl_metadata_key_tracker_urn);
+  TrackerResource *resource;
   GrlTrackerOp *os;
 
-  GRL_IDEBUG ("%s: urn=%s", G_STRFUNC, urn);
-
-  sparql_delete = grl_tracker_get_delete_string (sms->keys);
-  sparql_cdelete = grl_tracker_get_delete_conditional_string (urn, sms->keys);
-  sparql_insert = grl_tracker_tracker_get_insert_string (sms->media, sms->keys);
-
-  if (g_strcmp0 (sparql_insert, "") == 0) {
-    sparql_final = g_strdup_printf (TRACKER_DELETE_REQUEST,
-                                    urn, sparql_delete,
-                                    urn, sparql_cdelete);
-  } else {
-    sparql_final = g_strdup_printf (TRACKER_SAVE_REQUEST,
-                                    urn, sparql_delete,
-                                    urn, sparql_cdelete,
-                                    urn, sparql_insert);
-  }
-
-  GRL_IDEBUG ("\trequest: '%s'", sparql_final);
+  resource = grl_tracker_build_resource_from_media (sms->media, sms->keys);
 
   os = grl_tracker_op_new (GRL_TYPE_FILTER_ALL, sms->keys, sms);
 
-  tracker_sparql_connection_update_async (priv->tracker_connection,
-                                          sparql_final,
-                                          G_PRIORITY_DEFAULT,
-                                          os->cancel,
-                                          tracker_store_metadata_cb,
-                                          os);
-
-  g_free (sparql_delete);
-  g_free (sparql_cdelete);
-  g_free (sparql_insert);
+  g_dbus_proxy_call (priv->writeback,
+                     "Writeback",
+                     g_variant_new ("(@a{sv})",
+                                    tracker_resource_serialize (resource)),
+                     G_DBUS_CALL_FLAGS_NONE,
+                     -1,
+                     os->cancel,
+                     (GAsyncReadyCallback) tracker_store_metadata_cb,
+                     os);
 }
 
 void
diff --git a/src/tracker3/grl-tracker-source-priv.h b/src/tracker3/grl-tracker-source-priv.h
index 1d324823..226087c2 100644
--- a/src/tracker3/grl-tracker-source-priv.h
+++ b/src/tracker3/grl-tracker-source-priv.h
@@ -64,6 +64,7 @@ typedef enum {
 
 struct _GrlTrackerSourcePriv {
   TrackerSparqlConnection *tracker_connection;
+  GDBusProxy *writeback;
 
   GHashTable *operations;
   GrlTrackerSourceNotify *notifier;
diff --git a/src/tracker3/grl-tracker-source.c b/src/tracker3/grl-tracker-source.c
index 1af6a4a7..8fb23a8d 100644
--- a/src/tracker3/grl-tracker-source.c
+++ b/src/tracker3/grl-tracker-source.c
@@ -50,6 +50,10 @@ GRL_LOG_DOMAIN_STATIC(tracker_source_log_domain);
 
 #define TRACKER_ITEM_CACHE_SIZE (10000)
 
+#define WRITEBACK_DBUS_NAME "org.freedesktop.Tracker3.Writeback"
+#define WRITEBACK_DBUS_PATH "/org/freedesktop/Tracker3/Writeback"
+#define WRITEBACK_DBUS_IFACE "org.freedesktop.Tracker3.Writeback"
+
 /* --- Other --- */
 
 enum {
@@ -128,10 +132,23 @@ static void
 grl_tracker_source_init (GrlTrackerSource *source)
 {
   GrlTrackerSourcePriv *priv = GRL_TRACKER_SOURCE_GET_PRIVATE (source);
+  GDBusConnection *connection;
 
   source->priv = priv;
 
   priv->operations = g_hash_table_new (g_direct_hash, g_direct_equal);
+
+  connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
+  if (connection) {
+    priv->writeback =
+      g_dbus_proxy_new_sync (connection,
+                             G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START_AT_CONSTRUCTION,
+                             NULL,
+                             WRITEBACK_DBUS_NAME,
+                             WRITEBACK_DBUS_PATH,
+                             WRITEBACK_DBUS_IFACE,
+                             NULL, NULL);
+  }
 }
 
 static void
@@ -143,6 +160,7 @@ grl_tracker_source_finalize (GObject *object)
 
   g_clear_object (&self->priv->notifier);
   g_clear_object (&self->priv->tracker_connection);
+  g_clear_object (&self->priv->writeback);
 
   G_OBJECT_CLASS (grl_tracker_source_parent_class)->finalize (object);
 }
diff --git a/src/tracker3/grl-tracker-utils.c b/src/tracker3/grl-tracker-utils.c
index e8a6bfcd..48f4c2ed 100644
--- a/src/tracker3/grl-tracker-utils.c
+++ b/src/tracker3/grl-tracker-utils.c
@@ -886,3 +886,115 @@ grl_tracker_key_get_sparql_statement (const GrlKeyID key,
 
   return assoc->sparql_key_attr_call;
 }
+
+static TrackerResource *
+ensure_resource_for_property (TrackerResource *resource,
+                              const gchar     *prop,
+                              gboolean         multivalued)
+{
+  TrackerResource *child = NULL;
+
+  if (!multivalued)
+    child = tracker_resource_get_first_relation (resource, prop);
+
+  if (!child) {
+    child = tracker_resource_new (NULL);
+    tracker_resource_add_take_relation (resource, prop, child);
+  }
+
+  return child;
+}
+
+TrackerResource *
+grl_tracker_build_resource_from_media (GrlMedia *media, GList *keys)
+{
+  TrackerResource *resource;
+  GrlMediaType type;
+  GList *l;
+
+  resource = tracker_resource_new (NULL);
+  tracker_resource_set_uri (resource, "nie:isStoredAs",
+                            grl_media_get_url (media));
+
+  type = grl_media_get_media_type (media);
+  if (type & GRL_MEDIA_TYPE_IMAGE)
+    tracker_resource_add_uri (resource, "rdf:type", "nfo:Image");
+  if (type & GRL_MEDIA_TYPE_AUDIO)
+    tracker_resource_add_uri (resource, "rdf:type", "nfo:Audio");
+  if (type & GRL_MEDIA_TYPE_VIDEO)
+    tracker_resource_add_uri (resource, "rdf:type", "nfo:Video");
+
+  for (l = keys; l; l = l->next) {
+    if (l->data == GRLKEYID_TO_POINTER (GRL_METADATA_KEY_TITLE)) {
+      tracker_resource_set_string (resource, "nie:title",
+                                   grl_media_get_title (media));
+    } else if (l->data == GRLKEYID_TO_POINTER (GRL_METADATA_KEY_TRACK_NUMBER)) {
+      tracker_resource_set_int (resource, "nmm:trackNumber",
+                                grl_media_get_track_number (media));
+    } else if (l->data == GRLKEYID_TO_POINTER (GRL_METADATA_KEY_EPISODE)) {
+      tracker_resource_set_int (resource, "nmm:episodeNumber",
+                                grl_media_get_episode (media));
+    } else if (l->data == GRLKEYID_TO_POINTER (GRL_METADATA_KEY_CREATION_DATE)) {
+      GDateTime *creation;
+      gchar *date;
+
+      creation = grl_media_get_creation_date (media);
+      date = g_date_time_format_iso8601 (creation);
+      tracker_resource_set_string (resource, "nie:contentCreated", date);
+      g_free (date);
+    } else if (l->data == GRLKEYID_TO_POINTER (GRL_METADATA_KEY_ALBUM)) {
+      TrackerResource *album;
+      album = ensure_resource_for_property (resource, "nmm:musicAlbum", FALSE);
+      tracker_resource_set_string (album, "nie:title",
+                                   grl_media_get_album (media));
+    } else if (l->data == GRLKEYID_TO_POINTER (GRL_METADATA_KEY_ALBUM_DISC_NUMBER)) {
+      TrackerResource *disc;
+      disc = ensure_resource_for_property (resource, "nmm:musicAlbumDisc", FALSE);
+      tracker_resource_set_int (disc, "nmm:setNumber",
+                                grl_media_get_album_disc_number (media));
+    } else if (l->data == GRLKEYID_TO_POINTER (GRL_METADATA_KEY_SEASON)) {
+      TrackerResource *season;
+      season = ensure_resource_for_property (resource, "nmm:isPartOfSeason", FALSE);
+      tracker_resource_set_int (season, "nmm:seasonNumber",
+                                grl_media_get_season (media));
+    } else if (l->data == GRLKEYID_TO_POINTER (GRL_METADATA_KEY_ALBUM_ARTIST)) {
+      TrackerResource *album, *album_artist;
+      album = ensure_resource_for_property (resource, "nmm:musicAlbum", FALSE);
+      album_artist = ensure_resource_for_property (album, "nmm:albumArtist", FALSE);
+      tracker_resource_set_string (album_artist, "nmm:artistName",
+                                   grl_media_get_album_artist (media));
+    } else if (l->data == GRLKEYID_TO_POINTER (GRL_METADATA_KEY_ARTIST)) {
+      TrackerResource *artist;
+      const gchar *artist_name;
+      gint i;
+
+      for (i = 0; artist_name != NULL; i++) {
+        artist_name = grl_media_get_artist_nth (media, i);
+        artist = ensure_resource_for_property (resource, "nmm:performer", TRUE);
+        tracker_resource_set_string (artist, "nmm:artistName", artist_name);
+      }
+    } else if (l->data == GRLKEYID_TO_POINTER (GRL_METADATA_KEY_AUTHOR)) {
+      TrackerResource *artist;
+      const gchar *artist_name;
+      gint i;
+
+      for (i = 0; artist_name != NULL; i++) {
+        artist_name = grl_media_get_artist_nth (media, i);
+        artist = ensure_resource_for_property (resource, "nmm:performer", TRUE);
+        tracker_resource_set_string (artist, "nmm:artistName", artist_name);
+      }
+    } else if (l->data == GRLKEYID_TO_POINTER (GRL_METADATA_KEY_COMPOSER)) {
+      TrackerResource *composer;
+      const gchar *composer_name;
+      gint i;
+
+      for (i = 0; composer_name != NULL; i++) {
+        composer_name = grl_media_get_composer_nth (media, i);
+        composer = ensure_resource_for_property (resource, "nmm:composer", TRUE);
+        tracker_resource_set_string (composer, "nmm:artistName", composer_name);
+      }
+    }
+  }
+
+  return resource;
+}
diff --git a/src/tracker3/grl-tracker-utils.h b/src/tracker3/grl-tracker-utils.h
index 7db23331..e4a5a99e 100644
--- a/src/tracker3/grl-tracker-utils.h
+++ b/src/tracker3/grl-tracker-utils.h
@@ -76,6 +76,8 @@ const gchar * grl_tracker_key_get_sparql_statement (const GrlKeyID key,
 
 void grl_tracker_setup_key_mappings (void);
 
+TrackerResource * grl_tracker_build_resource_from_media (GrlMedia *media, GList *keys);
+
 tracker_grl_sparql_t *grl_tracker_get_mapping_from_sparql (const gchar *key);
 
 GrlMedia *grl_tracker_build_grilo_media (const gchar   *rdf_type,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]