[gvfs/wip/rishi/goa: 4/5] Drive continued ...
- From: Debarshi Ray <debarshir src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gvfs/wip/rishi/goa: 4/5] Drive continued ...
- Date: Wed, 5 Aug 2015 18:16:49 +0000 (UTC)
commit 468add67dcf5ef9f7e7f677a5e07a6b579da802b
Author: Debarshi Ray <debarshir gnome org>
Date: Mon Jun 29 20:15:18 2015 +0200
Drive continued ...
Honour remove_source in push
Implement replace/write/query_info_on_write/...
Guard against backups
daemon/gvfsbackendgoogle.c | 284 +++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 280 insertions(+), 4 deletions(-)
---
diff --git a/daemon/gvfsbackendgoogle.c b/daemon/gvfsbackendgoogle.c
index e34f08a..3490756 100644
--- a/daemon/gvfsbackendgoogle.c
+++ b/daemon/gvfsbackendgoogle.c
@@ -38,12 +38,15 @@
#include "gvfsbackendgoogle.h"
#include "gvfsicon.h"
#include "gvfsjobcloseread.h"
+#include "gvfsjobcopy.h"
#include "gvfsjobcreatemonitor.h"
#include "gvfsjobenumerate.h"
#include "gvfsjobopenforread.h"
+#include "gvfsjobopenforwrite.h"
#include "gvfsjobread.h"
#include "gvfsjobseekread.h"
#include "gvfsjobsetdisplayname.h"
+#include "gvfsjobwrite.h"
#include "gvfsmonitor.h"
struct _GVfsBackendGoogle
@@ -740,6 +743,8 @@ rebuild_entries (GVfsBackendGoogle *self,
g_clear_object (&feed);
}
+ self->entries_stale = FALSE;
+
out:
g_clear_object (&feed);
g_clear_object (&query);
@@ -799,6 +804,54 @@ g_vfs_backend_google_close_read (GVfsBackend *_self,
/* ---------------------------------------------------------------------------------------------------- */
static void
+g_vfs_backend_google_close_write (GVfsBackend *_self,
+ GVfsJobCloseWrite *job,
+ GVfsBackendHandle handle)
+{
+ GVfsBackendGoogle *self = G_VFS_BACKEND_GOOGLE (_self);
+ GCancellable *cancellable = G_VFS_JOB (job)->cancellable;
+ GDataDocumentsDocument *entry = NULL;
+ GDataUploadStream *stream = GDATA_UPLOAD_STREAM (handle);
+ GError *error;
+
+ g_debug ("+ close_write: %p\n", handle);
+
+ if (!g_output_stream_is_closed (G_OUTPUT_STREAM (stream)))
+ {
+ error = NULL;
+ g_output_stream_close (G_OUTPUT_STREAM (stream), cancellable, &error);
+ if (error != NULL)
+ {
+ g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+ g_error_free (error);
+ goto out;
+ }
+ }
+
+ error = NULL;
+ entry = gdata_documents_service_finish_upload (self->service, stream, &error);
+ if (error != NULL)
+ {
+ g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+ g_error_free (error);
+ goto out;
+ }
+ else if (entry == NULL)
+ {
+ g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_FAILED, _("Failed to write"));
+ goto out;
+ }
+
+ g_vfs_job_succeeded (G_VFS_JOB (job));
+
+ out:
+ g_clear_object (&entry);
+ g_debug ("- close_write\n");
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
g_vfs_backend_google_copy (GVfsBackend *_self,
GVfsJobCopy *job,
const gchar *source,
@@ -847,6 +900,16 @@ g_vfs_backend_google_copy (GVfsBackend *_self,
unescaped_destination);
source = unescaped_source;
+ if (flags & G_FILE_COPY_BACKUP)
+ {
+ /* Return G_IO_ERROR_NOT_SUPPORTED instead of
+ * G_IO_ERROR_CANT_CREATE_BACKUP to proceed with the GIO
+ * fallback copy.
+ */
+ g_vfs_job_failed_literal (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "Operation not
supported");
+ goto out;
+ }
+
error = NULL;
find_root (self, cancellable, &error);
if (error != NULL)
@@ -1205,8 +1268,6 @@ g_vfs_backend_google_enumerate (GVfsBackend *_self,
g_error_free (error);
goto out;
}
-
- self->entries_stale = FALSE;
}
g_vfs_job_succeeded (G_VFS_JOB (job));
@@ -1822,6 +1883,18 @@ g_vfs_backend_google_push (GVfsBackend *_self,
self->entries_stale = TRUE;
+ if (remove_source)
+ {
+ error = NULL;
+ g_file_delete (local_file, cancellable, &error);
+ if (error != NULL)
+ {
+ g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+ g_error_free (error);
+ goto out;
+ }
+ }
+
g_vfs_job_succeeded (G_VFS_JOB (job));
out:
@@ -1991,6 +2064,48 @@ g_vfs_backend_google_query_info_on_read (GVfsBackend *_self,
/* ---------------------------------------------------------------------------------------------------- */
+static gboolean
+g_vfs_backend_google_query_info_on_write (GVfsBackend *_self,
+ GVfsJobQueryInfoWrite *job,
+ GVfsBackendHandle handle,
+ GFileInfo *info,
+ GFileAttributeMatcher *matcher)
+{
+ GVfsBackendGoogle *self = G_VFS_BACKEND_GOOGLE (_self);
+ GDataEntry *entry;
+ GError *error;
+ GDataUploadStream *stream = GDATA_UPLOAD_STREAM (handle);
+ gchar *path = NULL;
+
+ g_debug ("+ query_info_on_write: %p\n", handle);
+
+ entry = gdata_upload_stream_get_entry (stream);
+ path = get_entry_path (self, entry);
+ if (path == NULL)
+ {
+ g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("No such file or directory"));
+ goto out;
+ }
+
+ error = NULL;
+ build_file_info (self, path, entry, info, matcher, FALSE, NULL, &error);
+ if (error != NULL)
+ {
+ g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+ g_error_free (error);
+ goto out;
+ }
+
+ g_vfs_job_succeeded (G_VFS_JOB (job));
+
+ out:
+ g_free (path);
+ g_debug ("- query_info_on_write\n");
+ return TRUE;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
static void
g_vfs_backend_google_seek_on_read (GVfsBackend *_self,
GVfsJobSeekRead *job,
@@ -2128,12 +2243,11 @@ read_cb (GObject *source_object,
GAsyncResult *res,
gpointer user_data)
{
- GError *error;
+ GError *error = NULL;
GInputStream *stream = G_INPUT_STREAM (source_object);
GVfsJobRead *job = G_VFS_JOB_READ (user_data);
gssize nread;
- error = NULL;
nread = g_input_stream_read_finish (stream, res, &error);
if (error != NULL)
{
@@ -2176,6 +2290,164 @@ g_vfs_backend_google_read (GVfsBackend *_self,
/* ---------------------------------------------------------------------------------------------------- */
static void
+g_vfs_backend_google_replace (GVfsBackend *_self,
+ GVfsJobOpenForWrite *job,
+ const gchar *filename,
+ const gchar *etag,
+ gboolean make_backup,
+ GFileCreateFlags flags)
+{
+ GVfsBackendGoogle *self = G_VFS_BACKEND_GOOGLE (_self);
+ GCancellable *cancellable = G_VFS_JOB (job)->cancellable;
+ GDataEntry *entry;
+ GDataUploadStream *stream;
+ GError *error;
+ gboolean is_display_name;
+ gboolean is_root;
+ gchar *content_type = NULL;
+ gchar *id = NULL;
+ gchar *unescaped_filename = NULL;
+
+ g_rec_mutex_lock (&self->mutex);
+ unescaped_filename = unescape_basename_and_map_dirname (self, filename, &is_display_name);
+ g_debug ("+ replace: %s (%s, %d)\n", filename, unescaped_filename, is_display_name);
+
+ if (unescaped_filename == NULL)
+ {
+ g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("No such file or directory"));
+ goto out;
+ }
+
+ is_folder_or_root (unescaped_filename, NULL, NULL, &is_root);
+ if (is_root)
+ {
+ g_vfs_job_failed (G_VFS_JOB (job),
+ G_IO_ERROR,
+ G_IO_ERROR_NOT_SUPPORTED,
+ _("Can not create root directory"));
+ goto out;
+ }
+
+ if (make_backup)
+ {
+ g_vfs_job_failed (G_VFS_JOB (job),
+ G_IO_ERROR,
+ G_IO_ERROR_CANT_CREATE_BACKUP,
+ _("Backup file creation failed"));
+ goto out;
+ }
+
+ if (is_display_name)
+ {
+ }
+ else
+ {
+ const gchar *title;
+
+ id = g_path_get_basename (unescaped_filename);
+ entry = g_hash_table_lookup (self->entries, id);
+
+ if (entry == NULL)
+ {
+ error = NULL;
+ rebuild_entries (self, cancellable, &error);
+ if (error != NULL)
+ {
+ g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+ g_error_free (error);
+ goto out;
+ }
+
+ entry = g_hash_table_lookup (self->entries, id);
+ if (entry == NULL)
+ {
+ g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("No such file or
directory"));
+ goto out;
+ }
+ }
+
+ title = gdata_entry_get_title (entry);
+ content_type = get_content_type_from_entry (entry);
+
+ error = NULL;
+ stream = gdata_documents_service_update_document (self->service,
+ GDATA_DOCUMENTS_DOCUMENT (entry),
+ title,
+ content_type,
+ cancellable,
+ &error);
+ if (error != NULL)
+ {
+ g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+ g_error_free (error);
+ goto out;
+ }
+ }
+
+ g_vfs_job_open_for_write_set_handle (job, stream);
+ g_vfs_job_succeeded (G_VFS_JOB (job));
+
+ out:
+ g_free (content_type);
+ g_free (unescaped_filename);
+ g_debug ("- replace\n");
+ g_rec_mutex_unlock (&self->mutex);
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+write_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GError *error = NULL;
+ GOutputStream *stream = G_OUTPUT_STREAM (source_object);
+ GVfsJobWrite *job = G_VFS_JOB_WRITE (user_data);
+ gssize nwrite;
+
+ nwrite = g_output_stream_write_finish (stream, res, &error);
+ if (error != NULL)
+ {
+ g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+ g_error_free (error);
+ goto out;
+ }
+
+ g_vfs_job_write_set_written_size (job, (gsize) nwrite);
+ g_vfs_job_succeeded (G_VFS_JOB (job));
+
+ out:
+ g_object_unref (job);
+ g_debug ("- write\n");
+}
+
+static gboolean
+g_vfs_backend_google_write (GVfsBackend *_self,
+ GVfsJobWrite *job,
+ GVfsBackendHandle handle,
+ gchar *buffer,
+ gsize buffer_size)
+{
+ GCancellable *cancellable = G_VFS_JOB (job)->cancellable;
+ GOutputStream *stream = G_OUTPUT_STREAM (handle);
+
+ g_debug ("+ write: %p\n", handle);
+
+ g_output_stream_write_async (stream,
+ buffer,
+ buffer_size,
+ G_PRIORITY_DEFAULT,
+ cancellable,
+ write_cb,
+ g_object_ref (job));
+
+ return TRUE;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
g_vfs_backend_google_dispose (GObject *_self)
{
GVfsBackendGoogle *self = G_VFS_BACKEND_GOOGLE (_self);
@@ -2219,6 +2491,7 @@ g_vfs_backend_google_class_init (GVfsBackendGoogleClass * klass)
gobject_class->finalize = g_vfs_backend_google_finalize;
backend_class->try_close_read = g_vfs_backend_google_close_read;
+ backend_class->close_write = g_vfs_backend_google_close_write;
backend_class->copy = g_vfs_backend_google_copy;
backend_class->try_create_dir_monitor = g_vfs_backend_google_create_dir_monitor;
backend_class->delete = g_vfs_backend_google_delete;
@@ -2231,9 +2504,12 @@ g_vfs_backend_google_class_init (GVfsBackendGoogleClass * klass)
backend_class->try_query_fs_info = g_vfs_backend_google_query_fs_info;
backend_class->query_info = g_vfs_backend_google_query_info;
backend_class->query_info_on_read = g_vfs_backend_google_query_info_on_read;
+ backend_class->try_query_info_on_write = g_vfs_backend_google_query_info_on_write;
backend_class->seek_on_read = g_vfs_backend_google_seek_on_read;
backend_class->set_display_name = g_vfs_backend_google_set_display_name;
backend_class->try_read = g_vfs_backend_google_read;
+ backend_class->replace = g_vfs_backend_google_replace;
+ backend_class->try_write = g_vfs_backend_google_write;
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]