[gvfs/wip/goa: 2/2] Add GVfsBackendGoogle
- From: Debarshi Ray <debarshir src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gvfs/wip/goa: 2/2] Add GVfsBackendGoogle
- Date: Wed, 22 Oct 2014 11:54:30 +0000 (UTC)
commit 45116d598034152b6b4131bd25f7e6d0959f437c
Author: Debarshi Ray <debarshir gnome org>
Date: Wed Oct 22 13:53:23 2014 +0200
Add GVfsBackendGoogle
configure.ac | 23 +++
daemon/Makefile.am | 20 +++
daemon/google.mount.in | 4 +
daemon/gvfsbackendgoogle.c | 379 ++++++++++++++++++++++++++++++++++++++++++++
daemon/gvfsbackendgoogle.h | 62 +++++++
5 files changed, 488 insertions(+), 0 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 1e21fdb..7205ed3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -407,6 +407,28 @@ AC_SUBST(GOA_CFLAGS)
AM_CONDITIONAL(USE_GOA, [test "$msg_goa" = "yes"])
+dnl ****************************************************
+dnl *** Check if we should build with Google backend ***
+dnl ****************************************************
+AC_ARG_ENABLE(google, AS_HELP_STRING([--disable-google],[build without Google backend]))
+msg_google=no
+GOOGLE_LIBS=
+GOOGLE_CFLAGS=
+
+if test "x$enable_google" != "xno" ; then
+ PKG_CHECK_EXISTS(libgdata >= 0.13.1, msg_google=yes)
+
+ if test "x$msg_google" = "xyes"; then
+ PKG_CHECK_MODULES(GOOGLE, libgdata)
+ AC_DEFINE(HAVE_GOOGLE, 1, [Define to 1 if Google is going to be built])
+ fi
+fi
+
+AC_SUBST(GOOGLE_LIBS)
+AC_SUBST(GOOGLE_CFLAGS)
+
+AM_CONDITIONAL(USE_GOOGLE, [test "$msg_google" = "yes"])
+
dnl *****************************************************
dnl *** Check if we should build with obexftp backend ***
dnl *****************************************************
@@ -938,6 +960,7 @@ echo "
hotplug backend: $msg_hotplug_backend
Blu-ray metadata support: $msg_bluray
+ Google support: $msg_google
HTTP/WebDAV support: $msg_http
ObexFTP support $msg_obexftp
Samba support: $msg_samba
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index a6a9ae1..5cb89ae 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -48,6 +48,12 @@ libexec_PROGRAMS=gvfsd gvfsd-sftp gvfsd-trash gvfsd-computer gvfsd-burn gvfsd-lo
mount_in_files = sftp.mount.in ftp.mount.in trash.mount.in computer.mount.in burn.mount.in
localtest.mount.in network.mount.in
mount_DATA = sftp.mount ftp.mount trash.mount computer.mount burn.mount localtest.mount network.mount
+mount_in_files +=google.mount.in
+if USE_GOOGLE
+mount_DATA += google.mount
+libexec_PROGRAMS += gvfsd-google
+endif
+
mount_in_files +=recent.mount.in
if USE_GTK
mount_DATA += recent.mount
@@ -459,6 +465,20 @@ else
gvfsd_cdda_LDADD = $(libraries) $(CDDA_LIBS) $(HAL_LIBS)
endif
+gvfsd_google_SOURCES = \
+ gvfsbackendgoogle.c gvfsbackendgoogle.h \
+ daemon-main.c daemon-main.h \
+ daemon-main-generic.c
+
+gvfsd_google_CPPFLAGS = \
+ $(flags) \
+ -DBACKEND_HEADER=gvfsbackendgoogle.h \
+ -DDEFAULT_BACKEND_TYPE=google-drive \
+ -DBACKEND_TYPES='"google-drive", G_VFS_TYPE_BACKEND_GOOGLE,' \
+ $(GOOGLE_CFLAGS)
+
+gvfsd_google_LDADD = $(libraries) $(GOOGLE_LIBS)
+
gvfsd_gphoto2_SOURCES = \
gvfsbackendgphoto2.c gvfsbackendgphoto2.h \
daemon-main.c daemon-main.h \
diff --git a/daemon/google.mount.in b/daemon/google.mount.in
new file mode 100644
index 0000000..059b228
--- /dev/null
+++ b/daemon/google.mount.in
@@ -0,0 +1,4 @@
+[Mount]
+Type=google-drive
+Exec= libexecdir@/gvfsd-google
+AutoMount=false
diff --git a/daemon/gvfsbackendgoogle.c b/daemon/gvfsbackendgoogle.c
new file mode 100644
index 0000000..ef813b4
--- /dev/null
+++ b/daemon/gvfsbackendgoogle.c
@@ -0,0 +1,379 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* gvfs - extensions for gio
+ *
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * 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; either
+ * version 2 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 Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * Author: Debarshi Ray <debarshir gnome org>
+ */
+
+#include <config.h>
+
+#include <gdata/gdata.h>
+#include <glib.h>
+#include <gio/gio.h>
+
+#define GOA_API_IS_SUBJECT_TO_CHANGE
+#include <goa/goa.h>
+
+#include "gvfsbackendgoogle.h"
+
+struct _GVfsBackendGoogle
+{
+ GVfsBackend parent;
+};
+
+struct _GVfsBackendGoogleClass
+{
+ GVfsBackendClass parent_class;
+};
+
+G_DEFINE_TYPE(GVfsBackendGoogle, g_vfs_backend_google, G_VFS_TYPE_BACKEND)
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+diff_sorted_lists (GList *list1,
+ GList *list2,
+ GCompareFunc compare,
+ GList **added,
+ GList **removed,
+ GList **unchanged)
+{
+ int order;
+
+ *added = *removed = NULL;
+ if (unchanged != NULL)
+ *unchanged = NULL;
+
+ while (list1 != NULL &&
+ list2 != NULL)
+ {
+ order = (*compare) (list1->data, list2->data);
+ if (order < 0)
+ {
+ *removed = g_list_prepend (*removed, list1->data);
+ list1 = list1->next;
+ }
+ else if (order > 0)
+ {
+ *added = g_list_prepend (*added, list2->data);
+ list2 = list2->next;
+ }
+ else
+ { /* same item */
+ if (unchanged != NULL)
+ *unchanged = g_list_prepend (*unchanged, list1->data);
+ list1 = list1->next;
+ list2 = list2->next;
+ }
+ }
+
+ while (list1 != NULL)
+ {
+ *removed = g_list_prepend (*removed, list1->data);
+ list1 = list1->next;
+ }
+ while (list2 != NULL)
+ {
+ *added = g_list_prepend (*added, list2->data);
+ list2 = list2->next;
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static gint
+account_compare (GoaObject *a, GoaObject *b)
+{
+ GoaAccount *account_a;
+ GoaAccount *account_b;
+
+ account_a = goa_object_peek_account (a);
+ account_b = goa_object_peek_account (b);
+
+ return g_strcmp0 (goa_account_get_id (account_a), goa_account_get_id (account_b));
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static gint
+uuid_compare (GVolume *volume_a, const gchar *uuid_b)
+{
+ gchar *uuid_a;
+ gint ret_val;
+
+ uuid_a = g_volume_get_uuid (volume_a);
+ ret_val = g_strcmp0 (uuid_a, uuid_b);
+ g_free (uuid_a);
+
+ return ret_val;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static gint
+volume_compare (GVolume *a, GVolume *b)
+{
+ gchar *uuid_a;
+ gchar *uuid_b;
+ gint ret_val;
+
+ uuid_a = g_volume_get_uuid (a);
+ uuid_b = g_volume_get_uuid (b);
+
+ ret_val = g_strcmp0 (uuid_a, uuid_b);
+
+ g_free (uuid_a);
+ g_free (uuid_b);
+
+ return ret_val;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+object_list_emit (GVfsBackendGoogle *monitor,
+ const gchar *monitor_signal,
+ const gchar *object_signal,
+ GList *objects)
+{
+ GList *l;
+
+ for (l = objects; l != NULL; l = l->next)
+ {
+ g_signal_emit_by_name (monitor, monitor_signal, l->data);
+ if (object_signal)
+ g_signal_emit_by_name (l->data, object_signal);
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+update_accounts (GVfsBackendGoogle *self, GList **added_accounts, GList **removed_accounts)
+{
+ GList *added;
+ GList *l;
+ GList *new_accounts;
+ GList *new_files_accounts = NULL;
+ GList *removed;
+
+ if (added_accounts != NULL)
+ *added_accounts = NULL;
+
+ if (removed_accounts != NULL)
+ *removed_accounts = NULL;
+
+ new_accounts = goa_client_get_accounts (self->client);
+ for (l = new_accounts; l != NULL; l = l->next)
+ {
+ GoaObject *object = GOA_OBJECT (l->data);
+
+ if (goa_object_peek_files (object) != NULL)
+ new_files_accounts = g_list_prepend (new_files_accounts, object);
+ }
+
+ new_files_accounts = g_list_sort (new_files_accounts, (GCompareFunc) account_compare);
+ diff_sorted_lists (self->accounts,
+ new_files_accounts,
+ (GCompareFunc) account_compare,
+ &added,
+ &removed,
+ NULL);
+
+ for (l = removed; l != NULL; l = l->next)
+ {
+ GList *llink;
+ GoaObject *object = GOA_OBJECT (l->data);
+
+ if (removed_accounts != NULL)
+ *removed_accounts = g_list_prepend (*removed_accounts, g_object_ref (object));
+
+ llink = g_list_find_custom (self->accounts, object, (GCompareFunc) account_compare);
+ self->accounts = g_list_remove_link (self->accounts, llink);
+ g_list_free_full (llink, g_object_unref);
+ }
+
+ for (l = added; l != NULL; l = l->next)
+ {
+ GoaObject *object = GOA_OBJECT (l->data);
+
+ self->accounts = g_list_prepend (self->accounts, g_object_ref (object));
+
+ if (added_accounts != NULL)
+ *added_accounts = g_list_prepend (*added_accounts, g_object_ref (object));
+ }
+
+ self->accounts = g_list_sort (self->accounts, (GCompareFunc) account_compare);
+
+ g_list_free (added);
+ g_list_free (removed);
+ g_list_free (new_files_accounts);
+ g_list_free_full (new_accounts, g_object_unref);
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+update_volumes (GVfsBackendGoogle *self, GList **added_volumes, GList **removed_volumes)
+{
+ GList *added;
+ GList *l;
+ GList *new_volumes = NULL;
+ GList *removed;
+
+ if (added_volumes != NULL)
+ *added_volumes = NULL;
+
+ if (removed_volumes != NULL)
+ *removed_volumes = NULL;
+
+ for (l = self->accounts; l != NULL; l = l->next)
+ {
+ GVolume *volume;
+ GoaFiles *files;
+ GoaObject *object = GOA_OBJECT (l->data);
+ const gchar *uri;
+
+ files = goa_object_peek_files (object);
+ uri = goa_files_get_uri (files);
+
+ volume = g_vfs_goa_volume_new (object, uri);
+ new_volumes = g_list_prepend (new_volumes, volume);
+ }
+
+ new_volumes = g_list_sort (new_volumes, (GCompareFunc) volume_compare);
+ diff_sorted_lists (self->volumes,
+ new_volumes,
+ (GCompareFunc) volume_compare,
+ &added,
+ &removed,
+ NULL);
+
+ for (l = removed; l != NULL; l = l->next)
+ {
+ GList *llink;
+ GVolume *volume = G_VOLUME (l->data);
+
+ if (removed_volumes != NULL)
+ *removed_volumes = g_list_prepend (*removed_volumes, g_object_ref (volume));
+
+ llink = g_list_find_custom (self->volumes, volume, (GCompareFunc) volume_compare);
+ self->volumes = g_list_remove_link (self->volumes, llink);
+ g_list_free_full (llink, g_object_unref);
+ }
+
+ for (l = added; l != NULL; l = l->next)
+ {
+ GVolume *volume = G_VOLUME (l->data);
+
+ self->volumes = g_list_prepend (self->volumes, g_object_ref (volume));
+
+ if (added_volumes != NULL)
+ *added_volumes = g_list_prepend (*added_volumes, g_object_ref (volume));
+ }
+
+ self->volumes = g_list_sort (self->volumes, (GCompareFunc) volume_compare);
+
+ g_list_free (added);
+ g_list_free (removed);
+ g_list_free_full (new_volumes, g_object_unref);
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+update_all (GVfsBackendGoogle *self)
+{
+ GList *added_volumes;
+ GList *removed_volumes;
+
+ update_accounts (self, NULL, NULL);
+ update_volumes (self, &added_volumes, &removed_volumes);
+
+ object_list_emit (self, "volume-removed", "removed", removed_volumes);
+ object_list_emit (self, "volume-added", NULL, added_volumes);
+
+ g_list_free_full (added_volumes, g_object_unref);
+ g_list_free_full (removed_volumes, g_object_unref);
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static GoaClient *
+get_goa_client_sync (GError **error)
+{
+ static GoaClient *client = NULL;
+ static GError *_error = NULL;
+ static volatile gsize initialized = 0;
+
+ if (g_once_init_enter (&initialized))
+ {
+ client = goa_client_new_sync (NULL, &_error);
+ g_once_init_leave (&initialized, 1);
+ }
+
+ if (_error != NULL && error != NULL)
+ *error = g_error_copy (_error);
+
+ return client;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+g_vfs_backend_google_mount (GVfsBackend *_self,
+ GVfsJobMount *job,
+ GMountSpec *mount_spec,
+ GMountSource *mount_source,
+ gboolean is_automount)
+{
+ g_vfs_job_succeeded (G_VFS_JOB (job));
+}
+
+static void
+g_vfs_backend_google_dispose (GObject *_self)
+{
+ GVfsBackendGoogle *self = G_VFS_BACKEND_GOOGLE (_self);
+
+ G_OBJECT_CLASS (g_vfs_backend_google_parent_class)->dispose (_self);
+}
+
+static void
+g_vfs_backend_google_class_init (GVfsBackendGoogleClass * klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GVfsBackendClass *backend_class = G_VFS_BACKEND_CLASS (klass);
+
+ gobject_class->dispose = g_vfs_backend_google_dispose;
+
+ backend_class->try_mount = NULL;
+ backend_class->mount = g_vfs_backend_google_mount;
+}
+
+static void
+g_vfs_backend_google_init (GVfsBackendGoogle *self)
+{
+ g_vfs_backend_set_user_visible (G_VFS_BACKEND (self), FALSE);
+}
+
+GVfsBackend *
+g_vfs_backend_google_new (void)
+{
+ return g_object_new (G_VFS_TYPE_BACKEND_GOOGLE, NULL);
+}
diff --git a/daemon/gvfsbackendgoogle.h b/daemon/gvfsbackendgoogle.h
new file mode 100644
index 0000000..21b209f
--- /dev/null
+++ b/daemon/gvfsbackendgoogle.h
@@ -0,0 +1,62 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* gvfs - extensions for gio
+ *
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * 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; either
+ * version 2 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 Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * Author: Debarshi Ray <debarshir gnome org>
+ */
+
+#ifndef __G_VFS_BACKEND_GOOGLE_H__
+#define __G_VFS_BACKEND_GOOGLE_H__
+
+#include <gvfsbackend.h>
+
+G_BEGIN_DECLS
+
+#define G_VFS_TYPE_BACKEND_GOOGLE (g_vfs_backend_google_get_type())
+
+#define G_VFS_BACKEND_GOOGLE(o) \
+ (G_TYPE_CHECK_INSTANCE_CAST((o), \
+ G_VFS_TYPE_BACKEND_GOOGLE, GVfsBackendGoogle))
+
+#define G_VFS_BACKEND_GOOGLE_CLASS(k) \
+ (G_TYPE_CHECK_CLASS_CAST((k), \
+ G_VFS_TYPE_BACKEND_GOOGLE, GVfsBackendGoogleClass))
+
+#define G_VFS_IS_BACKEND_GOOGLE(o) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((o), \
+ G_VFS_TYPE_BACKEND_GOOGLE))
+
+#define G_VFS_IS_BACKEND_GOOGLE_CLASS(k) \
+ (G_TYPE_CHECK_CLASS_TYPE((k), \
+ G_VFS_TYPE_BACKEND_GOOGLE))
+
+#define G_VFS_BACKEND_GOOGLE_GET_CLASS(o) \
+ (G_TYPE_INSTANCE_GET_CLASS((o), \
+ G_VFS_TYPE_BACKEND_GOOGLE, GVfsBackendGoogleClass))
+
+typedef struct _GVfsBackendGoogle GVfsBackendGoogle;
+typedef struct _GVfsBackendGoogleClass GVfsBackendGoogleClass;
+
+GType g_vfs_backend_google_get_type (void) G_GNUC_CONST;
+
+GVfsBackend *g_vfs_backend_google_new (void);
+
+G_END_DECLS
+
+#endif /* __G_VFS_BACKEND_GOOGLE_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]