[gnote] Refactor WebDAV sync to use GVFS



commit 4bb2e2cc5d0e142d5d4f60463345de56dd1939cb
Author: Aurimas Černius <aurisc4 gmail com>
Date:   Sat Feb 6 13:53:06 2021 +0200

    Refactor WebDAV sync to use GVFS

 .../webdavsyncservice/webdavsyncserviceaddin.cpp   | 156 +++++++++++++--------
 .../webdavsyncservice/webdavsyncserviceaddin.hpp   |  26 ++--
 2 files changed, 103 insertions(+), 79 deletions(-)
---
diff --git a/src/addins/webdavsyncservice/webdavsyncserviceaddin.cpp 
b/src/addins/webdavsyncservice/webdavsyncserviceaddin.cpp
index 588ce1be..e7c1c3a4 100644
--- a/src/addins/webdavsyncservice/webdavsyncserviceaddin.cpp
+++ b/src/addins/webdavsyncservice/webdavsyncserviceaddin.cpp
@@ -1,7 +1,7 @@
 /*
  * gnote
  *
- * Copyright (C) 2012-2013,2017,2019-2020 Aurimas Cernius
+ * Copyright (C) 2012-2013,2017,2019-2021 Aurimas Cernius
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -19,6 +19,7 @@
 
 
 #include <glibmm/i18n.h>
+#include <glibmm/thread.h>
 
 #include "debug.hpp"
 #include "ignote.hpp"
@@ -26,8 +27,10 @@
 #include "webdavsyncserviceaddin.hpp"
 #include "gnome_keyring/keyringexception.hpp"
 #include "gnome_keyring/ring.hpp"
+#include "sharp/directory.hpp"
 #include "sharp/string.hpp"
 #include "synchronization/isyncmanager.hpp"
+#include "synchronization/filesystemsyncserver.hpp"
 
 
 using gnome::keyring::KeyringException;
@@ -43,11 +46,44 @@ WebDavSyncServiceModule::WebDavSyncServiceModule()
 }
 
 
+class WebDavSyncServer
+  : public gnote::sync::FileSystemSyncServer
+{
+public:
+  static WebDavSyncServer *create(const Glib::RefPtr<Gio::File> & path, Preferences & prefs)
+    {
+      return new WebDavSyncServer(path, prefs.sync_client_id());
+    }
+protected:
+  void mkdir_p(const Glib::RefPtr<Gio::File> & path) override
+    {
+      // in WebDAV creating directory fails, if parent doesn't exist, can't create entire path
+      if(sharp::directory_exists(path) == false) {
+        auto parent = path->get_parent();
+        if(parent) {
+          mkdir_p(parent);
+        }
+        sharp::directory_create(path);
+      }
+    }
+private:
+  WebDavSyncServer(const Glib::RefPtr<Gio::File> & local_sync_path, const Glib::ustring & client_id)
+    : gnote::sync::FileSystemSyncServer(local_sync_path, client_id)
+  {}
+};
 
 
 const char *WebDavSyncServiceAddin::KEYRING_ITEM_NAME = "Tomboy sync WebDAV account";
 std::map<Glib::ustring, Glib::ustring> WebDavSyncServiceAddin::s_request_attributes;
 
+
+WebDavSyncServiceAddin::WebDavSyncServiceAddin()
+  : m_url_entry(nullptr)
+  , m_username_entry(nullptr)
+  , m_password_entry(nullptr)
+{
+}
+
 WebDavSyncServiceAddin * WebDavSyncServiceAddin::create()
 {
   s_request_attributes["name"] = KEYRING_ITEM_NAME;
@@ -112,89 +148,85 @@ Glib::ustring WebDavSyncServiceAddin::id()
   return "wdfs";
 }
 
-Glib::ustring WebDavSyncServiceAddin::fuse_mount_directory_error()
+gnote::sync::SyncServer *WebDavSyncServiceAddin::create_sync_server()
 {
-  const char *res = _("There was an error connecting to the server.  This may be caused by using an 
incorrect user name and/or password.");
-  return res;
-}
+  gnote::sync::SyncServer *server;
 
-std::vector<Glib::ustring> WebDavSyncServiceAddin::get_fuse_mount_exe_args(const Glib::ustring & mountPath, 
bool fromStoredValues)
-{
-  Glib::ustring url, username, password;
-  if(fromStoredValues) {
-    get_config_settings(url, username, password);
+  Glib::ustring sync_uri, username, password;
+  if(get_config_settings(sync_uri, username, password)) {
+    m_uri = sync_uri;
+
+    auto path = Gio::File::create_for_uri(m_uri);
+    if(!mount_sync(path, create_mount_operation(username, password))) {
+      throw sharp::Exception(_("Failed to mount the folder"));
+    }
+    if(!path->query_exists())
+      throw sharp::Exception(Glib::ustring::format(_("Synchronization destination %1 doesn't exist!"), 
sync_uri));
+
+    server = WebDavSyncServer::create(path, ignote().preferences());
   }
   else {
-    get_pref_widget_settings(url, username, password);
-  }
-  
-  return get_fuse_mount_exe_args(mountPath, url, username, password, accept_ssl_cert());
-}
-
-Glib::ustring WebDavSyncServiceAddin::get_fuse_mount_exe_args_for_display(const Glib::ustring & mountPath, 
bool fromStoredValues)
-{
-  std::vector<Glib::ustring> args = get_fuse_mount_exe_args(mountPath, fromStoredValues);
-  Glib::ustring result;
-  for(auto iter : args) {
-    result += iter + " ";
+    throw std::logic_error("GvfsSyncServiceAddin.create_sync_server() called without being configured");
   }
 
-  return result;
-}
-
-Glib::ustring WebDavSyncServiceAddin::fuse_mount_exe_name()
-{
-  return "wdfs";
+  return server;
 }
 
-bool WebDavSyncServiceAddin::verify_configuration()
+bool WebDavSyncServiceAddin::save_configuration(const sigc::slot<void, bool, Glib::ustring> & on_saved)
 {
   Glib::ustring url, username, password;
-
   if(!get_pref_widget_settings(url, username, password)) {
-    // TODO: Figure out a way to send the error back to the client
-    DBG_OUT("One of url, username, or password was empty");
     throw gnote::sync::GnoteSyncException(_("URL, username, or password field is empty."));
   }
 
+  auto path = Gio::File::create_for_uri(url);
+  auto on_mount_completed = [this, path, url, username, password, on_saved](bool success, Glib::ustring 
error) {
+      if(success) {
+        success = test_sync_directory(path, url, error);
+      }
+      unmount_async([this, url, username, password, on_saved, success, error] {
+        if(success) {
+          m_uri = url;
+          save_config_settings(url, username, password);
+        }
+        on_saved(success, error);
+      });
+  };
+  auto operation = create_mount_operation(username, password);
+  if(mount_async(path, on_mount_completed, operation)) {
+    Glib::Thread::create([this, url, on_mount_completed]() {
+      on_mount_completed(true, "");
+    }, false);
+  }
+
   return true;
 }
 
-void WebDavSyncServiceAddin::save_configuration_values()
+Glib::RefPtr<Gio::MountOperation> WebDavSyncServiceAddin::create_mount_operation(const Glib::ustring & 
username, const Glib::ustring & password)
 {
-  Glib::ustring url, username, password;
-  get_pref_widget_settings(url, username, password);
-
-  save_config_settings(url, username, password);
+  auto operation = Gio::MountOperation::create();
+  operation->signal_ask_password().connect(
+    [operation, username, password](const Glib::ustring & /* message */, const Glib::ustring & /* 
default_user */, const Glib::ustring & /* default_domain */, Gio::AskPasswordFlags flags) {
+      if(flags & Gio::ASK_PASSWORD_NEED_DOMAIN) {
+        operation->reply(Gio::MOUNT_OPERATION_ABORTED);
+        return;
+      }
+
+      if(flags & Gio::ASK_PASSWORD_NEED_USERNAME) {
+        operation->set_username(username);
+      }
+      if(flags & Gio::ASK_PASSWORD_NEED_PASSWORD) {
+        operation->set_password(password);
+      }
+
+      operation->reply(Gio::MOUNT_OPERATION_HANDLED);
+    });
+  return operation;
 }
 
-void WebDavSyncServiceAddin::reset_configuration_values()
+void WebDavSyncServiceAddin::reset_configuration()
 {
   save_config_settings("", "", "");
-
-  // TODO: Unmount the FUSE mount!
-}
-
-std::vector<Glib::ustring> WebDavSyncServiceAddin::get_fuse_mount_exe_args(const Glib::ustring & mountPath, 
const Glib::ustring & url,
-    const Glib::ustring & username, const Glib::ustring & password, bool acceptSsl)
-{
-  std::vector<Glib::ustring> args;
-  args.reserve(12);
-  args.push_back(url);
-  args.push_back(mountPath);
-  args.push_back("-o");
-  args.push_back("username=" + username);
-  args.push_back("-o");
-  args.push_back("password=" + password);
-  args.push_back("-o");
-  args.push_back("fsname=gnotewdfs");
-  if(acceptSsl) {
-    args.push_back("-o");
-    args.push_back("accept_sslcert");
-  }
-  args.push_back("-o");
-  args.push_back("fsname=gnotewdfs");
-  return args;
 }
 
 bool WebDavSyncServiceAddin::get_config_settings(Glib::ustring & url, Glib::ustring & username, 
Glib::ustring & password)
diff --git a/src/addins/webdavsyncservice/webdavsyncserviceaddin.hpp 
b/src/addins/webdavsyncservice/webdavsyncserviceaddin.hpp
index 3e84e5b8..48d4a22b 100644
--- a/src/addins/webdavsyncservice/webdavsyncserviceaddin.hpp
+++ b/src/addins/webdavsyncservice/webdavsyncserviceaddin.hpp
@@ -1,7 +1,7 @@
 /*
  * gnote
  *
- * Copyright (C) 2012-2013,2017,2019 Aurimas Cernius
+ * Copyright (C) 2012-2013,2017,2019,2021 Aurimas Cernius
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -26,7 +26,7 @@
 #include <gtkmm/table.h>
 
 #include "sharp/dynamicmodule.hpp"
-#include "synchronization/fusesyncserviceaddin.hpp"
+#include "synchronization/gvfssyncservice.hpp"
 
 
 namespace webdavsyncserviceaddin {
@@ -43,11 +43,13 @@ DECLARE_MODULE(WebDavSyncServiceModule)
 
 
 class WebDavSyncServiceAddin
-  : public gnote::sync::FuseSyncServiceAddin
+  : public gnote::sync::GvfsSyncService
 {
 public:
   static WebDavSyncServiceAddin * create();
 
+  WebDavSyncServiceAddin();
+
   /// <summary>
   /// Creates a Gtk.Widget that's used to configure the service.  This
   /// will be used in the Synchronization Preferences.  Preferences should
@@ -77,21 +79,11 @@ public:
   /// </summary>
   virtual Glib::ustring id() override;
 
-  virtual Glib::ustring fuse_mount_directory_error() override;
-protected:
-  virtual std::vector<Glib::ustring> get_fuse_mount_exe_args(const Glib::ustring & mountPath, bool 
fromStoredValues) override;
-  virtual Glib::ustring get_fuse_mount_exe_args_for_display(const Glib::ustring & mountPath, bool 
fromStoredValues) override;
-  virtual Glib::ustring fuse_mount_exe_name() override;
-  virtual bool verify_configuration() override;
-  virtual void save_configuration_values() override;
-
-  /// <summary>
-  /// Reset the configuration so that IsConfigured will return false.
-  /// </summary>
-  virtual void reset_configuration_values() override;
+  virtual gnote::sync::SyncServer *create_sync_server() override;
+  virtual bool save_configuration(const sigc::slot<void, bool, Glib::ustring> & on_saved) override;
+  virtual void reset_configuration() override;
 private:
-  std::vector<Glib::ustring> get_fuse_mount_exe_args(const Glib::ustring & mountPath, const Glib::ustring & 
url,
-      const Glib::ustring & username, const Glib::ustring & password, bool acceptSsl);
+  static Glib::RefPtr<Gio::MountOperation> create_mount_operation(const Glib::ustring & username, const 
Glib::ustring & password);
   bool get_config_settings(Glib::ustring & url, Glib::ustring & username, Glib::ustring & password);
   void save_config_settings(const Glib::ustring & url, const Glib::ustring & username, const Glib::ustring & 
password);
   bool get_pref_widget_settings(Glib::ustring & url, Glib::ustring & username, Glib::ustring & password);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]