[gvfs/wip/rishi/goa: 4/4] Adjusted for new libgdata
- From: Debarshi Ray <debarshir src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gvfs/wip/rishi/goa: 4/4] Adjusted for new libgdata
- Date: Wed, 24 Jun 2015 11:40:31 +0000 (UTC)
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]