[gnome-photos/wip/rishi/collection: 3/10] utils: Add photos_utils_copy_files_async
- From: Debarshi Ray <debarshir src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-photos/wip/rishi/collection: 3/10] utils: Add photos_utils_copy_files_async
- Date: Thu, 8 Feb 2018 05:19:40 +0000 (UTC)
commit 66566acc48cfc7f65975210a2fd69198a7af768c
Author: Debarshi Ray <debarshir gnome org>
Date: Sun Feb 4 20:38:00 2018 +0100
utils: Add photos_utils_copy_files_async
It's meant to copy a list of source GFiles to a destination directory
and handle name collisions in the process. A subsequent commit will use
this to copy files while importing content from attached devices.
https://gitlab.gnome.org/GNOME/gnome-photos/issues/29
src/photos-utils.c | 186 +++++++++++++++++++++++++++++++++++++++++++++++++++++
src/photos-utils.h | 13 ++++
2 files changed, 199 insertions(+)
---
diff --git a/src/photos-utils.c b/src/photos-utils.c
index 9f333e8b..25adde86 100644
--- a/src/photos-utils.c
+++ b/src/photos-utils.c
@@ -40,6 +40,7 @@
#include "photos-facebook-item.h"
#include "photos-flickr-item.h"
#include "photos-gegl.h"
+#include "photos-glib.h"
#include "photos-google-item.h"
#include "photos-local-item.h"
#include "photos-media-server-item.h"
@@ -71,6 +72,18 @@
#include "photos-utils.h"
+typedef struct _PhotosUtilsCopyFilesData PhotosUtilsCopyFilesData;
+
+struct _PhotosUtilsCopyFilesData
+{
+ GError *error;
+ GFile *destination_dir;
+ GList *files;
+ PhotosUtilsCopiedCallback copied_callback;
+ gint io_priority;
+ gpointer copied_callback_data;
+};
+
static const gdouble EPSILON = 1e-5;
@@ -101,6 +114,179 @@ photos_utils_center_pixbuf (GdkPixbuf *pixbuf, gint size)
}
+static void
+photos_utils_copy_files_data_free (PhotosUtilsCopyFilesData *data)
+{
+ g_clear_error (&data->error);
+ g_object_unref (data->destination_dir);
+ g_list_free_full (data->files, g_object_unref);
+ g_slice_free (PhotosUtilsCopyFilesData, data);
+}
+
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (PhotosUtilsCopyFilesData, photos_utils_copy_files_data_free);
+
+
+static PhotosUtilsCopyFilesData *
+photos_utils_copy_files_data_new (GList *files,
+ GFile *destination_dir,
+ gint io_priority,
+ PhotosUtilsCopiedCallback copied_callback,
+ gpointer copied_callback_data)
+{
+ PhotosUtilsCopyFilesData *data;
+
+ data = g_slice_new0 (PhotosUtilsCopyFilesData);
+
+ data->files = g_list_copy_deep (files, (GCopyFunc) g_object_ref, NULL);
+ data->destination_dir = g_object_ref (destination_dir);
+ data->io_priority = io_priority;
+ data->copied_callback = copied_callback;
+ data->copied_callback_data = copied_callback_data;
+
+ return data;
+}
+
+
+static void
+photos_utils_copy_files_copy (GObject *source_object, GAsyncResult *res, gpointer user_data)
+{
+ GCancellable *cancellable;
+ g_autoptr (GTask) task = G_TASK (user_data);
+ PhotosUtilsCopyFilesData *data;
+
+ cancellable = g_task_get_cancellable (task);
+ data = (PhotosUtilsCopyFilesData *) g_task_get_task_data (task);
+
+ g_assert_nonnull (data->files);
+ data->files = g_list_remove_link (data->files, data->files);
+
+ {
+ g_autoptr (GFile) destination = NULL;
+ GFile *source = G_FILE (source_object);
+
+ {
+ g_autoptr (GError) error = NULL;
+
+ destination = photos_glib_file_copy_finish (source, res, &error);
+ if (error != NULL)
+ {
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)
+ || g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NO_SPACE))
+ {
+ g_task_return_error (task, g_steal_pointer (&error));
+ goto out;
+ }
+ else
+ {
+ if (data->error == NULL)
+ {
+ g_autofree gchar *uri = NULL;
+
+ uri = g_file_get_uri (source);
+ g_prefix_error (&error, "Unable to copy %s: ", uri);
+ data->error = g_steal_pointer (&error);
+ }
+ }
+ }
+
+ if (destination != NULL && data->copied_callback != NULL)
+ (*data->copied_callback) (source, destination, data->copied_callback_data);
+ }
+ }
+
+ if (data->files == NULL)
+ {
+ if (data->error)
+ g_task_return_error (task, g_error_copy (data->error));
+ else
+ g_task_return_boolean (task, TRUE);
+
+ goto out;
+ }
+
+ {
+ g_autoptr (GFile) destination = NULL;
+ GFile *source;
+ g_autofree gchar *filename = NULL;
+
+ source = G_FILE (data->files->data);
+ filename = g_file_get_basename (source);
+ destination = g_file_get_child (data->destination_dir, filename);
+
+ photos_glib_file_copy_async (source,
+ destination,
+ G_FILE_COPY_TARGET_DEFAULT_PERMS,
+ data->io_priority,
+ cancellable,
+ photos_utils_copy_files_copy,
+ g_object_ref (task));
+ }
+
+ out:
+ return;
+}
+
+
+void
+photos_utils_copy_files_async (GList *files,
+ GFile *destination_dir,
+ gint io_priority,
+ GCancellable *cancellable,
+ PhotosUtilsCopiedCallback copied_callback,
+ gpointer copied_callback_data,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_autoptr (GFile) destination = NULL;
+ GFile *source;
+ g_autoptr (GTask) task = NULL;
+ g_autoptr (PhotosUtilsCopyFilesData) data = NULL;
+ g_autofree gchar *filename = NULL;
+
+ g_return_if_fail (files != NULL);
+ g_return_if_fail (G_IS_FILE (destination_dir));
+ g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+
+ task = g_task_new (NULL, cancellable, callback, user_data);
+ g_task_set_source_tag (task, photos_utils_copy_files_async);
+
+ data = photos_utils_copy_files_data_new (files,
+ destination_dir,
+ io_priority,
+ copied_callback,
+ copied_callback_data);
+ g_task_set_task_data (task, g_steal_pointer (&data), (GDestroyNotify) photos_utils_copy_files_data_free);
+
+ source = G_FILE (files->data);
+ filename = g_file_get_basename (source);
+ destination = g_file_get_child (destination_dir, filename);
+
+ photos_glib_file_copy_async (source,
+ destination,
+ G_FILE_COPY_TARGET_DEFAULT_PERMS,
+ io_priority,
+ cancellable,
+ photos_utils_copy_files_copy,
+ g_object_ref (task));
+}
+
+
+gboolean
+photos_utils_copy_files_finish (GAsyncResult *res, GError **error)
+{
+ GTask *task;
+
+ g_return_val_if_fail (g_task_is_valid (res, NULL), FALSE);
+ task = G_TASK (res);
+
+ g_return_val_if_fail (g_task_get_source_tag (task) == photos_utils_copy_files_async, FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ return g_task_propagate_boolean (task, error);
+}
+
+
gchar *
photos_utils_convert_path_to_uri (const gchar *path)
{
diff --git a/src/photos-utils.h b/src/photos-utils.h
index b1662451..567e5828 100644
--- a/src/photos-utils.h
+++ b/src/photos-utils.h
@@ -58,8 +58,21 @@ typedef enum
PHOTOS_ZOOM_EVENT_TOUCH
} PhotosZoomEvent;
+typedef void (*PhotosUtilsCopiedCallback) (GFile *source, GFile *destination, gpointer user_data);
+
GdkPixbuf *photos_utils_center_pixbuf (GdkPixbuf *pixbuf, gint size);
+void photos_utils_copy_files_async (GList *files,
+ GFile *destination_dir,
+ gint io_priority,
+ GCancellable *cancellable,
+ PhotosUtilsCopiedCallback copied_callback,
+ gpointer copied_callback_data,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+gboolean photos_utils_copy_files_finish (GAsyncResult *res, GError **error);
+
gchar *photos_utils_convert_path_to_uri (const gchar *path);
GIcon *photos_utils_create_collection_icon (gint base_size, GList *pixbufs);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]