[gvfs/wip/rishi/goa: 5/5] Build path



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]