[gvfs/wip/rishi/goa: 5/5] Build path
- From: Debarshi Ray <debarshir src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gvfs/wip/rishi/goa: 5/5] Build path
- Date: Fri, 19 Jun 2015 16:57:21 +0000 (UTC)
commit 05c14b606d21967a1c68b430eafb9c82bf783a44
Author: Debarshi Ray <debarshir gnome org>
Date: Fri Jun 19 18:56:21 2015 +0200
Build path
daemon/gvfsbackendgoogle.c | 165 ++++++++++++++++++++++++++++++++++++++------
1 files changed, 143 insertions(+), 22 deletions(-)
---
diff --git a/daemon/gvfsbackendgoogle.c b/daemon/gvfsbackendgoogle.c
index 953d8f4..1fe40ee 100644
--- a/daemon/gvfsbackendgoogle.c
+++ b/daemon/gvfsbackendgoogle.c
@@ -25,6 +25,8 @@
#include <config.h>
+#include <string.h>
+
#include <glib.h>
#include <glib/gi18n.h>
#include <gio/gio.h>
@@ -47,6 +49,7 @@ struct _GVfsBackendGoogle
{
GVfsBackend parent;
GDataDocumentsService *service;
+ GDataEntry *root;
GHashTable *entries;
GHashTable *lookaside;
GHashTable *monitors;
@@ -72,6 +75,8 @@ G_DEFINE_TYPE(GVfsBackendGoogle, g_vfs_backend_google, G_VFS_TYPE_BACKEND)
#define REBUILD_ENTRIES_TIMEOUT 60 /* s */
+#define URI_PREFIX "https://www.googleapis.com/drive/v2/files/"
+
/* ---------------------------------------------------------------------------------------------------- */
static void
@@ -357,6 +362,101 @@ build_file_info (GVfsBackendGoogle *self,
/* ---------------------------------------------------------------------------------------------------- */
+static gchar *
+get_parent_id (GDataEntry *entry)
+{
+ GList *l;
+ GList *links = NULL;
+ gchar *ret_val = NULL;
+
+ links = gdata_entry_look_up_links (entry, GDATA_LINK_PARENT);
+ for (l = links; l != NULL; l = l->next)
+ {
+ GDataLink *link = GDATA_LINK (l->data);
+ const gchar *uri;
+
+ /* HACK: GDataLink does not have the ID, only the URI. Extract
+ * the ID from the GDataLink:uri by removing the prefix. Ignore
+ * links which don't have the prefix.
+ */
+ uri = gdata_link_get_uri (link);
+ if (g_str_has_prefix (uri, URI_PREFIX))
+ {
+ gsize uri_prefix_len;
+
+ uri_prefix_len = strlen (URI_PREFIX);
+ ret_val = g_strdup (uri + uri_prefix_len);
+ break;
+ }
+ }
+
+ g_list_free (links);
+ return ret_val;
+}
+
+static gchar *
+get_entry_path (GVfsBackendGoogle *self, GDataEntry *entry)
+{
+ GString *path;
+ const gchar *base_id;
+ const gchar *root_id;
+ const gchar *tmp;
+ gchar *id = NULL;
+ gchar *ret_val = NULL;
+
+ base_id = gdata_entry_get_id (entry);
+ path = g_string_new (base_id);
+ path = g_string_prepend_c (path, '/');
+
+ id = get_parent_id (entry);
+ root_id = gdata_entry_get_id (self->root);
+
+ while (id != NULL)
+ {
+ GDataEntry *parent_entry;
+
+ /* The root folder itself has an ID, so path is
+ * /root/folder1/folder2/file. Instead, we want it to be
+ * /folder1/folder2/file.
+ */
+
+ if (g_strcmp0 (id, root_id) == 0)
+ break;
+
+ parent_entry = g_hash_table_lookup (self->entries, id);
+ if (parent_entry == NULL)
+ goto out;
+
+ path = g_string_prepend (path, id);
+ path = g_string_prepend_c (path, '/');
+
+ g_free (id);
+ id = get_parent_id (parent_entry);
+ }
+
+
+ if (g_str_has_prefix (path->str + 1, root_id))
+ {
+ gsize root_id_len;
+
+ root_id_len = strlen (root_id);
+ tmp = path->str + 1 + root_id_len;
+ }
+ else
+ {
+ tmp = path->str;
+ }
+
+ ret_val = g_strdup (tmp);
+
+ out:
+ g_free (id);
+ g_string_free (path, TRUE);
+ return ret_val;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
static GoaClient *
get_goa_client_sync (GError **error)
{
@@ -403,17 +503,26 @@ rebuild_entries (GVfsBackendGoogle *self,
GError *local_error;
gboolean succeeded_once = FALSE;
- /* The paging mechanism based on start-index and
- * gdata_query_next_page is not working at the moment. If we start
- * with (1, 50) and then call gdata_query_next_page, we get a feed
- * for (1, 50) instead of (51, 50). The result is the same if we
- * create a new query instead of calling gdata_query_next_page.
- *
- * Basically, the start-index always stays at 1.
- *
- * The only way I could get it to work was to keep increasing the
- * max-results and keep the start-index at 1.
- */
+ if (self->root == NULL)
+ {
+ GDataAuthorizationDomain *domain;
+
+ domain = gdata_documents_service_get_primary_authorization_domain ();
+
+ local_error = NULL;
+ self->root = gdata_service_query_single_entry (GDATA_SERVICE (self->service),
+ domain,
+ "root",
+ NULL,
+ GDATA_TYPE_DOCUMENTS_FOLDER,
+ cancellable,
+ &local_error);
+ if (local_error != NULL)
+ {
+ g_propagate_error (error, local_error);
+ goto out;
+ }
+ }
query = gdata_documents_query_new_with_limits (NULL, 1, MAX_RESULTS);
gdata_documents_query_set_show_folders (query, TRUE);
@@ -464,6 +573,7 @@ rebuild_entries (GVfsBackendGoogle *self,
g_clear_object (&feed);
}
+ out:
g_clear_object (&feed);
g_clear_object (&query);
}
@@ -715,22 +825,27 @@ g_vfs_backend_google_enumerate (GVfsBackend *_self,
g_hash_table_iter_init (&iter, self->entries);
while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &entry))
{
- gchar *parent_path;
gchar *path;
- path = gdata_documents_entry_get_path (GDATA_DOCUMENTS_ENTRY (entry));
- parent_path = g_path_get_dirname (path);
- if (g_strcmp0 (filename, parent_path) == 0)
+ path = get_entry_path (self, entry);
+ if (path != NULL)
{
- GFileInfo *info;
+ gchar *parent_path;
- info = g_file_info_new ();
- build_file_info (self, path, entry, info, matcher, FALSE, NULL, NULL);
- g_vfs_job_enumerate_add_info (job, info);
- g_object_unref (info);
+ parent_path = g_path_get_dirname (path);
+ if (g_strcmp0 (filename, parent_path) == 0)
+ {
+ GFileInfo *info;
+
+ info = g_file_info_new ();
+ build_file_info (self, path, entry, info, matcher, FALSE, NULL, NULL);
+ g_vfs_job_enumerate_add_info (job, info);
+ g_object_unref (info);
+ }
+
+ g_free (parent_path);
}
- g_free (parent_path);
g_free (path);
}
@@ -1319,7 +1434,12 @@ g_vfs_backend_google_query_info_on_read (GVfsBackend *_self,
g_debug ("+ query_info_on_read: %p\n", handle);
entry = g_object_get_data (G_OBJECT (stream), "g-vfs-backend-google-entry");
- path = gdata_documents_entry_get_path (GDATA_DOCUMENTS_ENTRY (entry));
+ 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);
@@ -1529,6 +1649,7 @@ g_vfs_backend_google_dispose (GObject *_self)
}
g_clear_object (&self->service);
+ g_clear_object (&self->root);
g_clear_object (&self->client);
g_clear_pointer (&self->entries, (GDestroyNotify) g_hash_table_unref);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]