[bijiben] own-cloud-note: Fix saving notes
- From: Isaque Galdino de Araujo <igaldino src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [bijiben] own-cloud-note: Fix saving notes
- Date: Thu, 25 Jan 2018 12:11:43 +0000 (UTC)
commit 5cf5e9d847f83d1d4ea18d5e9482cbcf8dc63d9a
Author: Isaque Galdino <igaldino gmail com>
Date: Tue Jan 23 02:11:30 2018 -0200
own-cloud-note: Fix saving notes
Owncloud integration is buggy. Saving notes action happens multiple
times, mainly when changing notes titles in an async way. That triggers
many file update actions in paralell and, in case of title change,
causes notes files being lost in the process.
This patch makes all file saving actions to be in sync, to make sure
that all operations will happen in order, preventing loosing data.
That may increase the saving time due to operations being in sync, but
it also reduces the number of saving actions.
https://bugzilla.gnome.org/show_bug.cgi?id=786239
src/libbiji/provider/biji-own-cloud-note.c | 178 ++++++++++------------------
1 files changed, 60 insertions(+), 118 deletions(-)
---
diff --git a/src/libbiji/provider/biji-own-cloud-note.c b/src/libbiji/provider/biji-own-cloud-note.c
index ccccf1d..def1bb3 100644
--- a/src/libbiji/provider/biji-own-cloud-note.c
+++ b/src/libbiji/provider/biji-own-cloud-note.c
@@ -27,7 +27,6 @@
#include "biji-item.h"
#include "biji-own-cloud-note.h"
#include "biji-own-cloud-provider.h"
-#include "biji-timeout.h"
#include "../serializer/biji-lazy-serializer.h"
struct _BijiOwnCloudNote
@@ -36,15 +35,12 @@ struct _BijiOwnCloudNote
BijiOwnCloudProvider *prov;
BijiNoteID *id;
- BijiTimeout *timeout;
-
-
GFile *location;
gchar *basename;
GCancellable *cancellable; //TODO cancel write to file
/* Ensure not to save while application quits & unneeded. */
- gboolean needs_save;
+ gboolean needs_rename;
};
@@ -125,8 +121,7 @@ ocloud_note_ensure_ressource (BijiNoteObj *note)
BijiInfoSet *info;
BijiItem *item;
BijiOwnCloudNote *ocnote;
- GFile *file;
- GFileInfo *file_info;
+ g_autoptr(GFileInfo) file_info = NULL;
const BijiProviderInfo *provider;
g_return_if_fail (BIJI_IS_OWN_CLOUD_NOTE (note));
@@ -134,15 +129,15 @@ ocloud_note_ensure_ressource (BijiNoteObj *note)
item = BIJI_ITEM (note);
ocnote = BIJI_OWN_CLOUD_NOTE (note);
- file = ocnote->location;
- file_info = g_file_query_info (file, "time::modified", G_FILE_QUERY_INFO_NONE, NULL, NULL);
+ file_info = g_file_query_info (ocnote->location, G_FILE_ATTRIBUTE_TIME_MODIFIED,
+ G_FILE_QUERY_INFO_NONE, NULL, NULL);
provider = biji_provider_get_info (BIJI_PROVIDER (ocnote->prov));
info = biji_info_set_new ();
info->url = (gchar*) biji_item_get_uuid (item);
info->title = (gchar*) biji_item_get_title (item);
info->content = (gchar*) biji_note_obj_get_raw_text (note);
- info->mtime = g_file_info_get_attribute_uint64 (file_info, "time::modified");
+ info->mtime = g_file_info_get_attribute_uint64 (file_info, G_FILE_ATTRIBUTE_TIME_MODIFIED);
info->created = biji_note_obj_get_create_date (note);
info->datasource_urn = g_strdup (provider->datasource);
@@ -150,118 +145,79 @@ ocloud_note_ensure_ressource (BijiNoteObj *note)
info);
}
-
-/* TODO: propagate error if any
- * through generic provider -> manager */
static void
-on_content_replaced (GObject *source_object,
- GAsyncResult *res,
- gpointer user_data)
+ocloud_note_set_id (BijiOwnCloudNote *self)
{
- GError *error = NULL;
+ g_autofree gchar *key = NULL;
- if (!g_file_replace_contents_finish (G_FILE (source_object),
- res,
- NULL, //etag
- &error))
- {
- if (error)
- {
- g_warning ("ownCloud note not saved. %s", error->message);
- g_error_free (error);
- }
- }
-
-
- else
- {
- ocloud_note_ensure_ressource (user_data);
- }
+ key = g_strdup_printf ("%s/%s",
+ biji_own_cloud_provider_get_readable_path (self->prov),
+ self->basename);
+ g_object_set (self->id, "path", key, NULL);
}
-
-
-
-
static void
ocloud_note_save (BijiNoteObj *note)
{
BijiOwnCloudNote *self;
- GString *str;
+ GFile *folder, *tmp_file;
+ const gchar *str;
+ g_autoptr(GError) error = NULL;
+ GFileOutputStream *new_file;
g_return_if_fail (BIJI_IS_OWN_CLOUD_NOTE (note));
self = BIJI_OWN_CLOUD_NOTE (note);
- str = g_string_new (biji_note_obj_get_raw_text (note));
+ str = biji_note_obj_get_raw_text (note);
+ /* create note file if it doesn't exist */
+ if (self->location == NULL || !g_file_query_exists (self->location, NULL))
+ {
+ folder = biji_own_cloud_provider_get_folder (self->prov);
+ if (self->location)
+ g_object_unref (self->location);
+ self->location = g_file_get_child (folder, self->basename);
+ new_file = g_file_create (self->location, G_FILE_CREATE_NONE,
+ NULL, &error);
+ if (error)
+ {
+ g_warning ("ownCloud note not created. %s", error->message);
+ return;
+ }
+ g_clear_object (&new_file);
+ self->needs_rename = FALSE;
+ ocloud_note_set_id (self);
+ }
+ /* if file exists and its title was changed */
+ else if (self->needs_rename)
+ {
+ tmp_file = self->location;
+ self->location = g_file_set_display_name (self->location, self->basename,
+ NULL, &error);
+ if (error)
+ {
+ g_warning ("ownCloud note not renamed. %s", error->message);
+ self->location = tmp_file;
+ return;
+ }
+ g_clear_object (&tmp_file);
+ self->needs_rename = FALSE;
+ ocloud_note_set_id (self);
+ }
/* backup would fail for some reason.
* gfilemove for workaround? */
- g_file_replace_contents_async (
- self->location,
- str->str,
- str->len,
- NULL, // etag
- FALSE, //backup
- G_FILE_CREATE_REPLACE_DESTINATION,
- self->cancellable,
- on_content_replaced,
- self);
-
-
- g_string_free (str, FALSE);
-}
-
-
-
-
-
-
-
-
-/* Rename the file
- * when note title change
- * Also handle new notes being populated
- * the noteID still keep some path, which we will remove */
-
-static void
-create_new_file (BijiOwnCloudNote *self, const gchar *basename)
-{
- GFile *folder;
- BijiNoteObj *note;
- gchar *key;
-
- note = BIJI_NOTE_OBJ (self);
- folder = biji_own_cloud_provider_get_folder (self->prov);
-
- /* TODO just free old location before, but check for no mistake */
-
- self->location = g_file_get_child (folder, basename);
- key = g_strdup_printf (
- "%s/%s",
- biji_own_cloud_provider_get_readable_path (self->prov),
- basename);
- g_object_set (self->id, "path", key, NULL);
-
- g_file_create (self->location, G_FILE_CREATE_NONE, NULL, NULL);
- ocloud_note_save (note);
- ocloud_note_ensure_ressource (note);
-
- g_free (key);
-}
-
-
-/* When the title is stable, handle io */
-static void
-on_timeout (BijiOwnCloudNote *self)
-{
- if (!self->needs_save)
- return;
+ if (!g_file_replace_contents (self->location, str, strlen(str), NULL, FALSE,
+ G_FILE_CREATE_REPLACE_DESTINATION, NULL,
+ self->cancellable, &error))
+ {
+ g_file_get_path (self->location);
+ g_warning ("ownCloud note not updated. %s", error->message);
+ return;
+ }
- self->needs_save = FALSE;
- create_new_file (self, self->basename);
+ ocloud_note_ensure_ressource (BIJI_NOTE_OBJ (self));
}
-
static void
on_title_change (BijiOwnCloudNote *self)
{
@@ -272,16 +228,7 @@ on_title_change (BijiOwnCloudNote *self)
g_free (self->basename);
new_title = biji_note_id_get_title (self->id);
self->basename = g_strdup_printf ("%s.txt", new_title);
- self->needs_save = TRUE;
-
-
- g_file_delete_async (self->location,
- G_PRIORITY_LOW,
- NULL,
- NULL,
- NULL);
-
- biji_timeout_reset (self->timeout, 3000);
+ self->needs_rename = TRUE;
}
@@ -298,7 +245,6 @@ biji_own_cloud_note_finalize (GObject *object)
self = BIJI_OWN_CLOUD_NOTE (object);
g_object_unref (self->location);
- g_object_unref (self->timeout);
g_object_unref (self->cancellable);
G_OBJECT_CLASS (biji_own_cloud_note_parent_class)->finalize (object);
@@ -318,10 +264,6 @@ static void
biji_own_cloud_note_init (BijiOwnCloudNote *self)
{
self->cancellable = g_cancellable_new ();
-
- self->timeout = biji_timeout_new ();
- g_signal_connect_swapped (self->timeout, "timeout",
- G_CALLBACK (on_timeout), self);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]