[gvfs/wip/rishi/goa: 4/4] Adjusted for new libgdata



commit 7339fd8324ec9f6e6d97372389c394c81712589b
Author: Debarshi Ray <debarshir gnome org>
Date:   Fri Jun 19 16:28:36 2015 +0200

    Adjusted for new libgdata
    
    Queries can now properly page through
    Use GDataEntry:id instead of GDataDocumentsEntry:document-id
    gdata_documents_entry_get_path doesn't work anymore
    Make open work
    Native Google types now open in the browser
    Use gdata_documents_service_add_entry_to_folder for make_directory
    Set is-volatile in GFileInfo
    Honour GFileInfoQueryFlags
    
    https://bugzilla.gnome.org/show_bug.cgi?id=739008

 daemon/gvfsbackendgoogle.c |  595 +++++++++++++++++++++++---------------------
 1 files changed, 314 insertions(+), 281 deletions(-)
---
diff --git a/daemon/gvfsbackendgoogle.c b/daemon/gvfsbackendgoogle.c
index fa9f219..25344ab 100644
--- a/daemon/gvfsbackendgoogle.c
+++ b/daemon/gvfsbackendgoogle.c
@@ -2,7 +2,7 @@
 /* gvfs - extensions for gio
  *
  * Copyright (C) 2009 Thibault Saunier
- * Copyright (C) 2014 Red Hat, Inc.
+ * Copyright (C) 2014, 2015 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
@@ -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;
@@ -68,11 +71,14 @@ G_DEFINE_TYPE(GVfsBackendGoogle, g_vfs_backend_google, G_VFS_TYPE_BACKEND)
 #define CATEGORY_SCHEMA_KIND "http://schemas.google.com/g/2005#kind";
 #define CATEGORY_SCHEMA_KIND_FILE "http://schemas.google.com/docs/2007#file";
 
-#define MAX_RESULTS_INITIAL 50
-#define MAX_RESULTS_FACTOR 2
+#define CONTENT_TYPE_PREFIX_GOOGLE "application/vnd.google-apps"
+
+#define MAX_RESULTS 50
 
 #define REBUILD_ENTRIES_TIMEOUT 60 /* s */
 
+#define URI_PREFIX "https://www.googleapis.com/drive/v2/files/";
+
 /* ---------------------------------------------------------------------------------------------------- */
 
 static void
@@ -95,6 +101,14 @@ emit_create_event (gpointer monitor,
   emit_event_internal (G_VFS_MONITOR (monitor), filename, G_FILE_MONITOR_EVENT_CREATED);
 }
 
+static void
+emit_delete_event (gpointer monitor,
+                   gpointer unused,
+                   gpointer filename)
+{
+  emit_event_internal (G_VFS_MONITOR (monitor), filename, G_FILE_MONITOR_EVENT_DELETED);
+}
+
 /* ---------------------------------------------------------------------------------------------------- */
 
 static void
@@ -127,116 +141,24 @@ is_folder_or_root (const gchar *filename,
 static gchar *
 get_content_type_from_entry (GDataEntry *entry)
 {
+  GList *categories;
+  GList *l;
   gchar *ret_val = NULL;
 
-  if (!GDATA_IS_DOCUMENTS_DOCUMENT (entry))
-    goto out;
-
-  if (GDATA_IS_DOCUMENTS_DRAWING (entry))
+  categories = gdata_entry_get_categories (entry);
+  for (l = categories; l != NULL; l = l->next)
     {
-      ret_val = g_strdup ("image/png");
-    }
-  else if (GDATA_IS_DOCUMENTS_PDF (entry))
-    {
-      ret_val = g_strdup ("application/pdf");
-    }
-  else if (GDATA_IS_DOCUMENTS_PRESENTATION (entry))
-    {
-      ret_val = g_strdup ("application/vnd.ms-powerpoint");
-    }
-  else if (GDATA_IS_DOCUMENTS_SPREADSHEET (entry))
-    {
-      ret_val = g_strdup ("application/vnd.oasis.opendocument.spreadsheet");
-    }
-  else if (GDATA_IS_DOCUMENTS_TEXT (entry))
-    {
-      ret_val = g_strdup ("application/vnd.oasis.opendocument.text");
-    }
-  else
-    {
-      GList *categories;
-      GList *l;
+      GDataCategory *category = GDATA_CATEGORY (l->data);
+      const gchar *scheme;
 
-      categories = gdata_entry_get_categories (entry);
-      for (l = categories; l != NULL; l = l->next)
+      scheme = gdata_category_get_scheme (category);
+      if (g_strcmp0 (scheme, CATEGORY_SCHEMA_KIND) == 0)
         {
-          GDataCategory *category = GDATA_CATEGORY (l->data);
-          const gchar *scheme;
-          const gchar *term;
-
-          scheme = gdata_category_get_scheme (category);
-          term = gdata_category_get_term (category);
-          if (g_strcmp0 (scheme, CATEGORY_SCHEMA_KIND) == 0 &&
-              g_strcmp0 (term, CATEGORY_SCHEMA_KIND_FILE) == 0)
-            {
-              ret_val = g_strdup (gdata_category_get_label (category));
-              break;
-            }
+          ret_val = g_strdup (gdata_category_get_label (category));
+          break;
         }
     }
 
- out:
-  return ret_val;
-}
-
-static gchar *
-get_export_format_from_entry (GDataEntry *entry)
-{
-  gchar *ret_val = NULL;
-
-  if (!GDATA_IS_DOCUMENTS_DOCUMENT (entry))
-    goto out;
-
-  if (GDATA_IS_DOCUMENTS_DRAWING (entry))
-    {
-      ret_val = g_strdup (GDATA_DOCUMENTS_DRAWING_PNG);
-    }
-  else if (GDATA_IS_DOCUMENTS_PDF (entry))
-    {
-      ret_val = g_strdup (GDATA_DOCUMENTS_TEXT_PDF);
-    }
-  else if (GDATA_IS_DOCUMENTS_PRESENTATION (entry))
-    {
-      ret_val = g_strdup (GDATA_DOCUMENTS_PRESENTATION_PPT);
-    }
-  else if (GDATA_IS_DOCUMENTS_SPREADSHEET (entry))
-    {
-      ret_val = g_strdup (GDATA_DOCUMENTS_SPREADSHEET_ODS);
-    }
-  else if (GDATA_IS_DOCUMENTS_TEXT (entry))
-    {
-      ret_val = g_strdup (GDATA_DOCUMENTS_TEXT_ODT);
-    }
-  else
-    {
-      GList *categories;
-      GList *l;
-      const gchar *content_type = NULL;
-
-      categories = gdata_entry_get_categories (entry);
-      for (l = categories; l != NULL; l = l->next)
-        {
-          GDataCategory *category = GDATA_CATEGORY (l->data);
-          const gchar *scheme;
-          const gchar *term;
-
-          scheme = gdata_category_get_scheme (category);
-          term = gdata_category_get_term (category);
-          if (g_strcmp0 (scheme, CATEGORY_SCHEMA_KIND) == 0 &&
-              g_strcmp0 (term, CATEGORY_SCHEMA_KIND_FILE) == 0)
-            {
-              content_type = gdata_category_get_label (category);
-              break;
-            }
-        }
-
-      if (g_strcmp0 (content_type, "image/jpeg") == 0)
-        ret_val = g_strdup ("jpeg");
-      else if (g_strcmp0 (content_type, "image/png") == 0)
-        ret_val = g_strdup ("png");
-    }
-
- out:
   return ret_val;
 }
 
@@ -254,6 +176,7 @@ build_file_info (GVfsBackendGoogle      *self,
 {
   GFileType file_type;
   GList *authors;
+  gboolean content_type_override = FALSE;
   gboolean is_folder;
   gboolean is_root;
   const gchar *etag;
@@ -261,6 +184,7 @@ build_file_info (GVfsBackendGoogle      *self,
   const gchar *name;
   const gchar *title;
   gchar *content_type = NULL;
+  gchar *copy_name = NULL;
   gint64 atime;
   gint64 ctime;
   gint64 mtime;
@@ -274,6 +198,10 @@ build_file_info (GVfsBackendGoogle      *self,
 
   g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_DELETE, !is_root);
   g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_RENAME, !is_root);
+
+  g_file_info_set_is_symlink (info, is_symlink);
+  g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_STANDARD_IS_VOLATILE, is_symlink);
+
   g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH, FALSE);
 
   if (is_folder)
@@ -289,17 +217,34 @@ build_file_info (GVfsBackendGoogle      *self,
 
   if (is_symlink)
     {
+      GMountSpec *spec;
+      const gchar *mount_identity;
+      const gchar *type;
+      gchar *target_uri = NULL;
+
       file_type = G_FILE_TYPE_SYMBOLIC_LINK;
-      g_file_info_set_is_symlink (info, TRUE);
-      g_file_info_set_symlink_target (info, filename);
+
+      spec = g_vfs_backend_get_mount_spec (G_VFS_BACKEND (self));
+      type = g_mount_spec_get (spec, "type");
+      mount_identity = g_mount_spec_get (spec, "goa-identity");
+      target_uri = g_strdup_printf ("%s://%s%s", type, mount_identity, filename);
+      g_file_info_set_symlink_target (info, target_uri);
+      g_free (target_uri);
     }
 
   if (content_type != NULL)
     {
       GIcon *icon;
+      const gchar *virtual_content_type = content_type;
+
+      if (g_str_has_prefix (content_type, CONTENT_TYPE_PREFIX_GOOGLE))
+        {
+          content_type_override = TRUE;
+          virtual_content_type = "application/x-desktop";
+        }
 
-      g_file_info_set_content_type (info, content_type);
-      g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE, content_type);
+      g_file_info_set_content_type (info, virtual_content_type);
+      g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE, 
virtual_content_type);
 
       icon = g_content_type_get_icon (content_type);
       g_file_info_set_icon (info, icon);
@@ -312,25 +257,22 @@ build_file_info (GVfsBackendGoogle      *self,
     goto out;
 
   if (is_symlink)
-    {
-      name = symlink_name;
-    }
+    name = symlink_name;
   else
-    {
-      /* We need the document-id, not id or resource-id, because
-       * gdata_documents_entry_get_path returns a path based on it.
-       */
-      G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
-      name = gdata_documents_entry_get_document_id (GDATA_DOCUMENTS_ENTRY (entry));
-      G_GNUC_END_IGNORE_DEPRECATIONS;
-    }
+    name = gdata_entry_get_id (entry);
 
   g_file_info_set_name (info, name);
 
   title = gdata_entry_get_title (entry);
   g_file_info_set_display_name (info, title);
   g_file_info_set_edit_name (info, title);
-  g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_COPY_NAME, title);
+
+  if (content_type_override)
+    copy_name = g_strconcat (title, ".desktop", NULL);
+  else
+    copy_name = g_strdup (title);
+
+  g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_COPY_NAME, copy_name);
 
   atime = gdata_documents_entry_get_last_viewed (GDATA_DOCUMENTS_ENTRY (entry));
   g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_ACCESS, (guint64) atime);
@@ -362,11 +304,94 @@ build_file_info (GVfsBackendGoogle      *self,
   g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_ID_FILE, id);
 
  out:
+  g_free (copy_name);
   g_free (content_type);
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
 
+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;
+  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 can become
+       * /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);
+    }
+
+
+  ret_val = g_strdup (path->str);
+
+ out:
+  g_free (id);
+  g_string_free (path, TRUE);
+  return ret_val;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
 static GoaClient *
 get_goa_client_sync (GError **error)
 {
@@ -411,31 +436,36 @@ rebuild_entries (GVfsBackendGoogle  *self,
   GDataDocumentsFeed *feed = NULL;
   GDataDocumentsQuery *query = NULL;
   GError *local_error;
-  gboolean found_new;
   gboolean succeeded_once = FALSE;
-  guint max_results = MAX_RESULTS_INITIAL;
-
-  /* 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.
-   */
-
-  do
+
+  if (self->root == NULL)
     {
-      GList *entries;
-      GList *l;
+      GDataAuthorizationDomain *auth_domain;
 
-      found_new = FALSE;
+      auth_domain = gdata_documents_service_get_primary_authorization_domain ();
 
-      query = gdata_documents_query_new_with_limits (NULL, 1, max_results);
-      gdata_documents_query_set_show_folders (query, TRUE);
+      local_error = NULL;
+      self->root = gdata_service_query_single_entry (GDATA_SERVICE (self->service),
+                                                     auth_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);
+
+  while (TRUE)
+    {
+      GList *entries;
+      GList *l;
 
       local_error = NULL;
       feed = gdata_documents_service_query_documents (self->service, query, cancellable, NULL, NULL, 
&local_error);
@@ -451,7 +481,7 @@ rebuild_entries (GVfsBackendGoogle  *self,
               g_propagate_error (error, local_error);
             }
 
-          goto out;
+          break;
         }
 
       if (!succeeded_once)
@@ -461,29 +491,22 @@ rebuild_entries (GVfsBackendGoogle  *self,
         }
 
       entries = gdata_feed_get_entries (GDATA_FEED (feed));
+      if (entries == NULL)
+        break;
+
       for (l = entries; l != NULL; l = l->next)
         {
           GDataEntry *entry = GDATA_ENTRY (l->data);
-          const gchar *document_id;
-
-          /* We need the document-id, not id or resource-id, because
-           * gdata_documents_entry_get_path returns a path based on it.
-           */
-          G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
-          document_id = gdata_documents_entry_get_document_id (GDATA_DOCUMENTS_ENTRY (entry));
-          G_GNUC_END_IGNORE_DEPRECATIONS;
+          const gchar *id;
 
-          if (g_hash_table_lookup (self->entries, document_id) == NULL)
-            {
-              g_hash_table_insert (self->entries, g_strdup (document_id), g_object_ref (entry));
-              found_new = TRUE;
-            }
+          id = gdata_entry_get_id (entry);
+          if (g_hash_table_lookup (self->entries, id) == NULL)
+            g_hash_table_insert (self->entries, g_strdup (id), g_object_ref (entry));
         }
 
-      max_results *= MAX_RESULTS_FACTOR;
+      gdata_query_next_page (GDATA_QUERY (query));
       g_clear_object (&feed);
-      g_clear_object (&query);
-    } while (found_new);
+    }
 
  out:
   g_clear_object (&feed);
@@ -557,12 +580,12 @@ g_vfs_backend_google_create_dir_monitor (GVfsBackend          *_self,
   GVfsMonitor *monitor = NULL;
   gboolean is_folder;
   gboolean is_root;
-  gchar *document_id = NULL;
+  gchar *id = NULL;
 
   g_rec_mutex_lock (&self->mutex);
 
-  document_id = g_path_get_basename (filename);
-  entry = g_hash_table_lookup (self->entries, document_id);
+  id = g_path_get_basename (filename);
+  entry = g_hash_table_lookup (self->entries, id);
   is_folder_or_root (filename, entry, NULL, &is_root);
 
   if (entry == NULL && !is_root)
@@ -576,7 +599,7 @@ g_vfs_backend_google_create_dir_monitor (GVfsBackend          *_self,
           goto out;
         }
 
-      entry = g_hash_table_lookup (self->entries, document_id);
+      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"));
@@ -600,7 +623,7 @@ g_vfs_backend_google_create_dir_monitor (GVfsBackend          *_self,
 
  out:
   g_clear_object (&monitor);
-  g_free (document_id);
+  g_free (id);
   g_rec_mutex_unlock (&self->mutex);
   return TRUE;
 }
@@ -619,7 +642,8 @@ g_vfs_backend_google_delete (GVfsBackend   *_self,
   GError *error;
   gboolean is_root;
   const gchar *real_filename;
-  gchar *document_id = NULL;
+  gchar *path = NULL;
+  gchar *id = NULL;
 
   g_rec_mutex_lock (&self->mutex);
   g_debug ("+ delete: %s\n", filename);
@@ -638,8 +662,8 @@ g_vfs_backend_google_delete (GVfsBackend   *_self,
       goto out;
     }
 
-  document_id = g_path_get_basename (filename);
-  entry = g_hash_table_lookup (self->entries, document_id);
+  id = g_path_get_basename (filename);
+  entry = g_hash_table_lookup (self->entries, id);
 
   if (entry == NULL)
     {
@@ -652,7 +676,7 @@ g_vfs_backend_google_delete (GVfsBackend   *_self,
           goto out;
         }
 
-      entry = g_hash_table_lookup (self->entries, document_id);
+      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"));
@@ -671,11 +695,17 @@ g_vfs_backend_google_delete (GVfsBackend   *_self,
       goto out;
     }
 
-  g_hash_table_remove (self->entries, document_id);
+  g_hash_table_remove (self->entries, id);
+
+  path = get_entry_path (self, entry);
+  if (path != NULL)
+    g_hash_table_foreach (self->monitors, emit_delete_event, (gpointer) path);
+
   g_vfs_job_succeeded (G_VFS_JOB (job));
 
  out:
-  g_free (document_id);
+  g_free (path);
+  g_free (id);
   g_debug ("- delete\n");
   g_rec_mutex_unlock (&self->mutex);
 }
@@ -702,9 +732,9 @@ g_vfs_backend_google_enumerate (GVfsBackend           *_self,
 {
   GVfsBackendGoogle *self = G_VFS_BACKEND_GOOGLE (_self);
   GCancellable *cancellable = G_VFS_JOB (job)->cancellable;
+  GDataEntry *entry;
   GError *error;
-  GList *entries = NULL;
-  GList *l;
+  GHashTableIter iter;
 
   g_rec_mutex_lock (&self->mutex);
   g_debug ("+ enumerate: %s\n", filename);
@@ -734,33 +764,36 @@ g_vfs_backend_google_enumerate (GVfsBackend           *_self,
 
   g_vfs_job_succeeded (G_VFS_JOB (job));
 
-  entries = g_hash_table_get_values (self->entries);
-  for (l = entries; l != NULL; l = l->next)
+  g_hash_table_iter_init (&iter, self->entries);
+  while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &entry))
     {
-      GDataEntry *entry = GDATA_ENTRY (l->data);
-      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;
+
+          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);
+            }
 
-          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);
     }
 
   g_vfs_job_enumerate_done (job);
 
  out:
-  g_list_free (entries);
   g_debug ("- enumerate\n");
   g_rec_mutex_unlock (&self->mutex);
 }
@@ -774,18 +807,16 @@ g_vfs_backend_google_make_directory (GVfsBackend          *_self,
 {
   GVfsBackendGoogle *self = G_VFS_BACKEND_GOOGLE (_self);
   GCancellable *cancellable = G_VFS_JOB (job)->cancellable;
-  GDataAuthorizationDomain *auth_domain;
+  GDataDocumentsEntry *new_entry = NULL;
   GDataDocumentsFolder *folder = NULL;
   GDataDocumentsFolder *parent = NULL;
-  GDataEntry *new_entry = NULL;
   GError *error;
   gboolean is_root;
-  const gchar *document_id;
+  const gchar *id;
   gchar *parent_id = NULL;
   gchar *parent_path = NULL;
   gchar *path = NULL;
   gchar *title = NULL;
-  gchar *upload_uri = NULL;
 
   g_rec_mutex_lock (&self->mutex);
   g_debug ("+ make_directory: %s\n", filename);
@@ -827,26 +858,16 @@ g_vfs_backend_google_make_directory (GVfsBackend          *_self,
         }
     }
 
-  upload_uri = gdata_documents_service_get_upload_uri (parent);
-  if (upload_uri == NULL)
-    {
-      g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("Upload URI not found"));
-      goto out;
-    }
-
   folder = gdata_documents_folder_new (NULL);
   title = g_path_get_basename (filename);
   gdata_entry_set_title (GDATA_ENTRY (folder), title);
 
-  auth_domain = gdata_documents_service_get_primary_authorization_domain ();
-
   error = NULL;
-  new_entry = gdata_service_insert_entry (GDATA_SERVICE (self->service),
-                                          auth_domain,
-                                          upload_uri,
-                                          GDATA_ENTRY (folder),
-                                          cancellable,
-                                          &error);
+  new_entry = gdata_documents_service_add_entry_to_folder (self->service,
+                                                           GDATA_DOCUMENTS_ENTRY (folder),
+                                                           parent,
+                                                           cancellable,
+                                                           &error);
   if (error != NULL)
     {
       g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
@@ -854,20 +875,14 @@ g_vfs_backend_google_make_directory (GVfsBackend          *_self,
       goto out;
     }
 
-  /* We need the document-id, not id or resource-id, because
-   * gdata_documents_entry_get_path returns a path based on it.
-   */
-  G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
-  document_id = gdata_documents_entry_get_document_id (GDATA_DOCUMENTS_ENTRY (new_entry));
-  G_GNUC_END_IGNORE_DEPRECATIONS;
-
-  g_hash_table_insert (self->entries, g_strdup (document_id), g_object_ref (new_entry));
+  id = gdata_entry_get_id (GDATA_ENTRY (new_entry));
+  g_hash_table_insert (self->entries, g_strdup (id), g_object_ref (new_entry));
 
-  path = gdata_documents_entry_get_path (GDATA_DOCUMENTS_ENTRY (new_entry));
+  path = get_entry_path (self, GDATA_ENTRY (new_entry));
   g_hash_table_insert (self->lookaside, g_strdup (filename), g_strdup (path));
 
   self->entries_stale = TRUE;
-  //g_hash_table_foreach (self->monitors, emit_create_event, (gpointer) path);
+  g_hash_table_foreach (self->monitors, emit_create_event, (gpointer) path);
 
   g_vfs_job_succeeded (G_VFS_JOB (job));
 
@@ -878,7 +893,6 @@ g_vfs_backend_google_make_directory (GVfsBackend          *_self,
   g_free (parent_path);
   g_free (path);
   g_free (title);
-  g_free (upload_uri);
   g_debug ("- make_directory\n");
   g_rec_mutex_unlock (&self->mutex);
 }
@@ -978,18 +992,23 @@ g_vfs_backend_google_open_for_read (GVfsBackend        *_self,
   GVfsBackendGoogle *self = G_VFS_BACKEND_GOOGLE (_self);
   GCancellable *cancellable = G_VFS_JOB (job)->cancellable;
   GDataEntry *entry;
-  GDataDownloadStream *stream;
+  GInputStream *stream;
   GError *error;
   gboolean is_folder;
   gboolean is_root;
-  gchar *document_id = NULL;
-  gchar *export_format = NULL;
+  const gchar *real_filename;
+  gchar *content_type = NULL;
+  gchar *id = NULL;
 
   g_rec_mutex_lock (&self->mutex);
   g_debug ("+ open_for_read: %s\n", filename);
 
-  document_id = g_path_get_basename (filename);
-  entry = g_hash_table_lookup (self->entries, document_id);
+  real_filename = g_hash_table_lookup (self->lookaside, filename);
+  if (real_filename != NULL)
+    filename = real_filename;
+
+  id = g_path_get_basename (filename);
+  entry = g_hash_table_lookup (self->entries, id);
 
   is_folder_or_root (filename, entry, NULL, &is_root);
   if (is_root)
@@ -1009,7 +1028,7 @@ g_vfs_backend_google_open_for_read (GVfsBackend        *_self,
           goto out;
         }
 
-      entry = g_hash_table_lookup (self->entries, document_id);
+      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"));
@@ -1024,24 +1043,50 @@ g_vfs_backend_google_open_for_read (GVfsBackend        *_self,
       goto out;
     }
 
-  export_format = get_export_format_from_entry (entry);
-  if (export_format == NULL)
+  content_type = get_content_type_from_entry (entry);
+  if (content_type == NULL)
     {
-      g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, _("Not supported"));
+      g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_FAILED, _("Unknown content type"));
       goto out;
     }
 
-  error = NULL;
-  stream = gdata_documents_document_download (GDATA_DOCUMENTS_DOCUMENT (entry),
-                                              self->service,
-                                              export_format,
-                                              cancellable,
-                                              &error);
-  if (error != NULL)
+  if (g_str_has_prefix (content_type, CONTENT_TYPE_PREFIX_GOOGLE))
     {
-      g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
-      g_error_free (error);
-      goto out;
+      GDataLink *alternate;
+      GKeyFile *file;
+      const gchar *title;
+      const gchar *uri;
+      gchar *data;
+      gchar *icon_name = NULL;
+      gsize length;
+
+      file = g_key_file_new ();
+
+      title = gdata_entry_get_title (entry);
+      g_key_file_set_string (file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NAME, title);
+      g_key_file_set_string (file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_TYPE, "Link");
+
+      alternate = gdata_entry_look_up_link (entry, GDATA_LINK_ALTERNATE);
+      uri = gdata_link_get_uri (alternate);
+      g_key_file_set_string (file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_URL, uri);
+
+      icon_name = g_content_type_get_generic_icon_name (content_type);
+      g_key_file_set_string (file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_ICON, icon_name);
+
+      data = g_key_file_to_data (file, &length, NULL);
+      stream = g_memory_input_stream_new_from_data (data, (gssize) length, g_free);
+
+      g_free (icon_name);
+      g_key_file_free (file);
+    }
+  else
+    {
+      GDataAuthorizationDomain *auth_domain;
+      const gchar *uri;
+
+      auth_domain = gdata_documents_service_get_primary_authorization_domain ();
+      uri = gdata_entry_get_content_uri (entry);
+      stream = gdata_download_stream_new (GDATA_SERVICE (self->service), auth_domain, uri, cancellable);
     }
 
   g_object_set_data_full (G_OBJECT (stream), "g-vfs-backend-google-entry", g_object_ref (entry), 
g_object_unref);
@@ -1051,8 +1096,8 @@ g_vfs_backend_google_open_for_read (GVfsBackend        *_self,
   g_vfs_job_succeeded (G_VFS_JOB (job));
 
  out:
-  g_free (export_format);
-  g_free (document_id);
+  g_free (content_type);
+  g_free (id);
   g_debug ("- open_for_read\n");
   g_rec_mutex_unlock (&self->mutex);
 }
@@ -1081,13 +1126,12 @@ g_vfs_backend_google_push (GVfsBackend           *_self,
   GFileInfo *info = NULL;
   gboolean is_root;
   const gchar *content_type;
-  const gchar *document_id;
+  const gchar *id;
   const gchar *real_parent_path;
   const gchar *title;
   gchar *parent_id = NULL;
   gchar *parent_path = NULL;
   gchar *path = NULL;
-  gchar *upload_uri = NULL;
 
   g_rec_mutex_lock (&self->mutex);
   g_debug ("+ push: %s -> %s\n", local_path, destination);
@@ -1161,13 +1205,6 @@ g_vfs_backend_google_push (GVfsBackend           *_self,
         }
     }
 
-  upload_uri = gdata_documents_service_get_upload_uri (parent);
-  if (upload_uri == NULL)
-    {
-      g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("Upload URI not found"));
-      goto out;
-    }
-
   document = gdata_documents_document_new (NULL);
   title = g_file_info_get_display_name (info);
   gdata_entry_set_title (GDATA_ENTRY (document), title);
@@ -1211,16 +1248,10 @@ g_vfs_backend_google_push (GVfsBackend           *_self,
       goto out;
     }
 
-  /* We need the document-id, not id or resource-id, because
-   * gdata_documents_entry_get_path returns a path based on it.
-   */
-  G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
-  document_id = gdata_documents_entry_get_document_id (GDATA_DOCUMENTS_ENTRY (new_document));
-  G_GNUC_END_IGNORE_DEPRECATIONS;
-
-  g_hash_table_insert (self->entries, g_strdup (document_id), g_object_ref (new_document));
+  id = gdata_entry_get_id (GDATA_ENTRY (new_document));
+  g_hash_table_insert (self->entries, g_strdup (id), g_object_ref (new_document));
 
-  path = gdata_documents_entry_get_path (GDATA_DOCUMENTS_ENTRY (new_document));
+  path = get_entry_path (self, GDATA_ENTRY (new_document));
   g_hash_table_insert (self->lookaside, g_strdup (destination), g_strdup (path));
 
   self->entries_stale = TRUE;
@@ -1238,7 +1269,6 @@ g_vfs_backend_google_push (GVfsBackend           *_self,
   g_free (parent_id);
   g_free (parent_path);
   g_free (path);
-  g_free (upload_uri);
   g_debug ("- push\n");
   g_rec_mutex_unlock (&self->mutex);
 }
@@ -1287,22 +1317,25 @@ g_vfs_backend_google_query_info (GVfsBackend           *_self,
   gboolean is_root;
   gboolean is_symlink = FALSE;
   const gchar *real_filename;
-  gchar *document_id = NULL;
+  gchar *id = NULL;
   gchar *symlink_name = NULL;
 
   g_rec_mutex_lock (&self->mutex);
-  g_debug ("+ query_info: %s\n", filename);
+  g_debug ("+ query_info: %s, %d\n", filename, flags);
 
   real_filename = g_hash_table_lookup (self->lookaside, filename);
   if (real_filename != NULL)
     {
-      is_symlink = TRUE;
-      symlink_name = g_path_get_basename (filename);
       filename = real_filename;
+      if ((flags & G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS) != 0)
+        {
+          is_symlink = TRUE;
+          symlink_name = g_path_get_basename (filename);
+        }
     }
 
-  document_id = g_path_get_basename (filename);
-  entry = g_hash_table_lookup (self->entries, document_id);
+  id = g_path_get_basename (filename);
+  entry = g_hash_table_lookup (self->entries, id);
   is_folder_or_root (filename, entry, NULL, &is_root);
 
   if (entry == NULL && !is_root)
@@ -1316,7 +1349,7 @@ g_vfs_backend_google_query_info (GVfsBackend           *_self,
           goto out;
         }
 
-      entry = g_hash_table_lookup (self->entries, document_id);
+      entry = g_hash_table_lookup (self->entries, id);
     }
 
   error = NULL;
@@ -1331,7 +1364,7 @@ g_vfs_backend_google_query_info (GVfsBackend           *_self,
   g_vfs_job_succeeded (G_VFS_JOB (job));
 
  out:
-  g_free (document_id);
+  g_free (id);
   g_free (symlink_name);
   g_debug ("- query_info\n");
   g_rec_mutex_unlock (&self->mutex);
@@ -1355,7 +1388,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);
@@ -1422,9 +1460,9 @@ g_vfs_backend_google_set_display_name (GVfsBackend           *_self,
   GDataEntry *new_entry = NULL;
   GError *error;
   gboolean is_root;
-  const gchar *new_document_id;
+  const gchar *new_id;
   const gchar *real_filename;
-  gchar *document_id = NULL;
+  gchar *id = NULL;
   gchar *path = NULL;
 
   g_rec_mutex_lock (&self->mutex);
@@ -1444,8 +1482,8 @@ g_vfs_backend_google_set_display_name (GVfsBackend           *_self,
       goto out;
     }
 
-  document_id = g_path_get_basename (filename);
-  entry = g_hash_table_lookup (self->entries, document_id);
+  id = g_path_get_basename (filename);
+  entry = g_hash_table_lookup (self->entries, id);
 
   if (entry == NULL)
     {
@@ -1458,7 +1496,7 @@ g_vfs_backend_google_set_display_name (GVfsBackend           *_self,
           goto out;
         }
 
-      entry = g_hash_table_lookup (self->entries, document_id);
+      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"));
@@ -1479,18 +1517,12 @@ g_vfs_backend_google_set_display_name (GVfsBackend           *_self,
       goto out;
     }
 
-  g_hash_table_remove (self->entries, document_id);
-
-  /* We need the document-id, not id or resource-id, because
-   * gdata_documents_entry_get_path returns a path based on it.
-   */
-  G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
-  new_document_id = gdata_documents_entry_get_document_id (GDATA_DOCUMENTS_ENTRY (new_entry));
-  G_GNUC_END_IGNORE_DEPRECATIONS;
+  g_hash_table_remove (self->entries, id);
 
-  g_hash_table_insert (self->entries, g_strdup (new_document_id), g_object_ref (new_entry));
+  new_id = gdata_entry_get_id (new_entry);
+  g_hash_table_insert (self->entries, g_strdup (new_id), g_object_ref (new_entry));
 
-  path = gdata_documents_entry_get_path (GDATA_DOCUMENTS_ENTRY (new_entry));
+  path = get_entry_path (self, new_entry);
   g_vfs_job_set_display_name_set_new_path (job, path);
 
   g_warn_if_fail (g_strcmp0 (filename, path) == 0);
@@ -1499,7 +1531,7 @@ g_vfs_backend_google_set_display_name (GVfsBackend           *_self,
 
  out:
   g_clear_object (&new_entry);
-  g_free (document_id);
+  g_free (id);
   g_free (path);
   g_debug ("- set_display_name\n");
   g_rec_mutex_unlock (&self->mutex);
@@ -1571,6 +1603,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]