[gnome-photos] application, base-item: Preserve metadata when saving



commit ba4d294e2c2f55adb58a39d3cde7f2eaf1109452
Author: Umang Jain <mailumangjain gmail com>
Date:   Tue Jan 12 00:19:16 2016 +0530

    application, base-item: Preserve metadata when saving
    
    https://bugzilla.gnome.org/show_bug.cgi?id=759156

 configure.ac             |    1 +
 src/Makefile.am          |    2 +
 src/photos-application.c |    5 ++
 src/photos-base-item.c   |  122 +++++++++++++++++++++++++++++++++++++++++++++-
 4 files changed, 129 insertions(+), 1 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 0fb2b42..50ff9bd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -82,6 +82,7 @@ PKG_CHECK_MODULES(CAIRO, [cairo >= $CAIRO_MIN_VERSION cairo-gobject])
 PKG_CHECK_MODULES(GFBGRAPH, [libgfbgraph-0.2 >= $GFBGRAPH_MIN_VERSION])
 PKG_CHECK_MODULES(GDATA, [libgdata >= $GDATA_MIN_VERSION])
 PKG_CHECK_MODULES(GEGL, [gegl-0.3 >= $GEGL_MIN_VERSION])
+PKG_CHECK_MODULES(GEXIV2, [gexiv2])
 PKG_CHECK_MODULES(GDK_PIXBUF, [gdk-pixbuf-2.0])
 PKG_CHECK_MODULES(GLIB, [glib-2.0 >= $GLIB_MIN_VERSION])
 PKG_CHECK_MODULES(GIO, [gio-2.0])
diff --git a/src/Makefile.am b/src/Makefile.am
index e53b0f3..a5c5b1a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -281,6 +281,7 @@ AM_CPPFLAGS = \
        $(GDK_PIXBUF_CFLAGS) \
        $(GFBGRAPH_CFLAGS) \
        $(GEGL_CFLAGS) \
+       $(GEXIV2_CFLAGS) \
        $(GIO_CFLAGS) \
        $(GLIB_CFLAGS) \
        $(GNOME_DESKTOP_CFLAGS) \
@@ -308,6 +309,7 @@ gnome_photos_LDADD = \
        $(GDK_PIXBUF_LIBS) \
        $(GFBGRAPH_LIBS) \
        $(GEGL_LIBS) \
+       $(GEXIV2_LIBS) \
        $(GIO_LIBS) \
        $(GLIB_LIBS) \
        $(GNOME_DESKTOP_LIBS) \
diff --git a/src/photos-application.c b/src/photos-application.c
index a1f5175..999623e 100644
--- a/src/photos-application.c
+++ b/src/photos-application.c
@@ -28,6 +28,7 @@
 #include "config.h"
 
 #include <gegl.h>
+#include <gexiv2/gexiv2.h>
 #include <gio/gio.h>
 #include <glib.h>
 #include <glib/gi18n.h>
@@ -525,10 +526,14 @@ static gboolean
 photos_application_create_window (PhotosApplication *self)
 {
   PhotosApplicationPrivate *priv = self->priv;
+  gboolean gexiv2_initialized;
 
   if (priv->main_window != NULL)
     return TRUE;
 
+  gexiv2_initialized = gexiv2_initialize ();
+  g_return_val_if_fail (gexiv2_initialized, FALSE);
+
   g_return_val_if_fail (photos_application_sanity_check_gegl (self), FALSE);
 
   priv->main_window = photos_main_window_new (GTK_APPLICATION (self));
diff --git a/src/photos-base-item.c b/src/photos-base-item.c
index c678ce3..c3b6d9c 100644
--- a/src/photos-base-item.c
+++ b/src/photos-base-item.c
@@ -2,6 +2,7 @@
  * Photos - access, organize and share your photos on GNOME
  * Copyright © 2014, 2015 Pranav Kant
  * Copyright © 2012, 2013, 2014, 2015, 2016 Red Hat, Inc.
+ * Copyright © 2016 Umang Jain
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -31,6 +32,7 @@
 
 #include <gdk/gdk.h>
 #include <gegl-plugin.h>
+#include <gexiv2/gexiv2.h>
 #include <gio/gio.h>
 #include <glib.h>
 #include <glib/gi18n.h>
@@ -1059,10 +1061,122 @@ photos_base_item_save_guess_sizes_in_thread_func (GTask *task,
 
 
 static void
+photos_base_item_save_metadata_in_thread_func (GTask *task,
+                                               gpointer source_object,
+                                               gpointer task_data,
+                                               GCancellable *cancellable)
+{
+  PhotosBaseItem *self = PHOTOS_BASE_ITEM (source_object);
+  PhotosBaseItemPrivate *priv = self->priv;
+  GError *error;
+  GFile *file = G_FILE (task_data);
+  GExiv2Metadata *metadata = NULL;
+  gchar *export_path = NULL;
+  gchar *source_path = NULL;
+
+  g_mutex_lock (&priv->mutex_download);
+
+  error = NULL;
+  source_path = photos_base_item_download (self, cancellable, &error);
+  if (error != NULL)
+    {
+      g_task_return_error (task, error);
+      goto out;
+    }
+
+  metadata = gexiv2_metadata_new ();
+
+  error = NULL;
+  if (!gexiv2_metadata_open_path (metadata, source_path, &error))
+    {
+      g_task_return_error (task, error);
+      goto out;
+    }
+
+  export_path = g_file_get_path (file);
+
+  error = NULL;
+  if (!gexiv2_metadata_save_file (metadata, export_path, &error))
+    {
+      g_task_return_error (task, error);
+      goto out;
+    }
+
+  g_task_return_boolean (task, TRUE);
+
+ out:
+  g_mutex_unlock (&priv->mutex_download);
+  g_clear_object (&metadata);
+  g_free (export_path);
+  g_free (source_path);
+}
+
+
+static void
+photos_base_item_save_metadata_async (PhotosBaseItem *self,
+                                      GFile *file,
+                                      GCancellable *cancellable,
+                                      GAsyncReadyCallback callback,
+                                      gpointer user_data)
+{
+  GTask *task;
+
+  task = g_task_new (self, cancellable, callback, user_data);
+  g_task_set_source_tag (task, photos_base_item_save_metadata_async);
+  g_task_set_task_data (task, g_object_ref (file), g_object_unref);
+
+  g_task_run_in_thread (task, photos_base_item_save_metadata_in_thread_func);
+  g_object_unref (task);
+}
+
+
+static gboolean
+photos_base_item_save_metadata_finish (PhotosBaseItem *self, GAsyncResult *res, GError **error)
+{
+  GTask *task = G_TASK (res);
+
+  g_return_val_if_fail (g_task_is_valid (res, self), FALSE);
+  g_return_val_if_fail (g_task_get_source_tag (task) == photos_base_item_save_metadata_async, FALSE);
+  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+  return g_task_propagate_boolean (task, error);
+}
+
+
+static void
+photos_base_item_save_save_metadata (GObject *source_object, GAsyncResult *res, gpointer user_data)
+{
+  PhotosBaseItem *self = PHOTOS_BASE_ITEM (source_object);
+  GError *error;
+  GTask *task = G_TASK (user_data);
+
+  error = NULL;
+  if (!photos_base_item_save_metadata_finish (self, res, &error))
+    {
+      g_task_return_error (task, error);
+      goto out;
+    }
+
+  g_task_return_boolean (task, TRUE);
+
+ out:
+  g_object_unref (task);
+}
+
+
+static void
 photos_base_item_save_save_to_stream (GObject *source_object, GAsyncResult *res, gpointer user_data)
 {
   GTask *task = G_TASK (user_data);
+  PhotosBaseItem *self;
+  PhotosBaseItemSaveData *data;
+  GCancellable *cancellable;
   GError *error = NULL;
+  GFile *file = NULL;
+
+  self = PHOTOS_BASE_ITEM (g_task_get_source_object (task));
+  cancellable = g_task_get_cancellable (task);
+  data = (PhotosBaseItemSaveData *) g_task_get_task_data (task);
 
   if (!gdk_pixbuf_save_to_stream_finish (res, &error))
     {
@@ -1070,9 +1184,15 @@ photos_base_item_save_save_to_stream (GObject *source_object, GAsyncResult *res,
       goto out;
     }
 
-  g_task_return_boolean (task, TRUE);
+  file = g_file_get_child (data->dir, self->priv->filename);
+  photos_base_item_save_metadata_async (self,
+                                        file,
+                                        cancellable,
+                                        photos_base_item_save_save_metadata,
+                                        g_object_ref (task));
 
  out:
+  g_clear_object (&file);
   g_object_unref (task);
 }
 


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