[gnote] Add SyncUtils class



commit ce772638531662d1a3fee476c2e44bceea2ec05c
Author: Aurimas Äernius <aurisc4 gmail com>
Date:   Sun Jun 17 20:35:01 2012 +0300

    Add SyncUtils class
    
    Contains fuse support

 src/synchronization/syncutils.cpp |  151 +++++++++++++++++++++++++++++++++++--
 src/synchronization/syncutils.hpp |   17 ++++
 2 files changed, 161 insertions(+), 7 deletions(-)
---
diff --git a/src/synchronization/syncutils.cpp b/src/synchronization/syncutils.cpp
index 98f27af..a4a1486 100644
--- a/src/synchronization/syncutils.cpp
+++ b/src/synchronization/syncutils.cpp
@@ -18,7 +18,20 @@
  */
 
 
+#include <algorithm>
+#include <fstream>
+#include <vector>
+
+#include <glibmm.h>
+#include <glibmm/i18n.h>
+#include <pcrecpp.h>
+
+#include "debug.hpp"
 #include "syncutils.hpp"
+#include "utils.hpp"
+#include "sharp/files.hpp"
+#include "sharp/process.hpp"
+#include "sharp/string.hpp"
 #include "sharp/xmlreader.hpp"
 
 namespace gnote {
@@ -70,13 +83,6 @@ namespace sync {
 
   std::string NoteUpdate::get_inner_content(const std::string & full_content_element) const
   {
-    /*const string noteContentRegex =
-				"^<note-content([^>]+version=""(?<contentVersion>[^""]*)"")?[^>]*((/>)|(>(?<innerContent>.*)</note-content>))$";
-			Match m = Regex.Match (fullContentElement, noteContentRegex, RegexOptions.Singleline);
-			Group contentGroup = m.Groups ["innerContent"];
-			if (!contentGroup.Success)
-				return null;
-			return contentGroup.Value;*/
     sharp::XmlReader xml;
     xml.load_buffer(full_content_element);
     if(xml.read() && xml.get_name() == "note-content") {
@@ -99,5 +105,136 @@ namespace sync {
     return true;
   }
 
+
+  const char *SyncUtils::common_paths[] = {"/sbin", "/bin", "/usr/bin"};
+
+  bool SyncUtils::is_fuse_enabled()
+  {
+    try {
+      std::string fsFileName = "/proc/filesystems";
+      if(sharp::file_exists(fsFileName)) {
+        std::string fsOutput;
+        std::ifstream file(fsFileName.c_str());
+        while(file) {
+          std::string line;
+          std::getline(file, line);
+          fsOutput += "\n" + line;
+        }
+        file.close();
+        pcrecpp::RE re("\\s+fuse\\s+", pcrecpp::RE_Options(PCRE_MULTILINE|PCRE_UTF8));
+        return re.PartialMatch(fsOutput);
+      }
+    }
+    catch(...) {}
+    return false;
+  }
+
+  bool SyncUtils::enable_fuse()
+  {
+    if(is_fuse_enabled()) {
+      return true; // nothing to do
+    }
+
+    if(m_guisu_tool == "" || m_modprobe_tool == "") {
+      DBG_OUT("Couldn't enable fuse; missing either GUI 'su' tool or modprobe");
+
+      // Let the user know that FUSE could not be enabled
+      utils::HIGMessageDialog cannotEnableDlg(NULL, GTK_DIALOG_MODAL, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK,
+        _("Could not enable FUSE"),
+        _("The FUSE module could not be loaded. Please check that it is installed properly and try again."));
+
+      cannotEnableDlg.run();
+      return false;
+    }
+
+    // Prompt the user first about enabling fuse
+    utils::HIGMessageDialog dialog(NULL, GTK_DIALOG_MODAL, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO,
+      _("Enable FUSE?"),
+      // TODO: This message isn't entirely accurate.
+      //       We should fix it.
+      _("The synchronization you've chosen requires the FUSE module to be loaded.\n\n"
+        "To avoid getting this prompt in the future, you should load FUSE at startup.  "
+        "Add \"modprobe fuse\" to /etc/init.d/boot.local or \"fuse\" to /etc/modules."));
+    int response = dialog.run();
+    if(response == Gtk::RESPONSE_YES) {
+      // "modprobe fuse"
+      sharp::Process p;
+      p.file_name(m_guisu_tool);
+      std::vector<std::string> args;
+      args.push_back(m_modprobe_tool);
+      args.push_back("fuse");
+      p.arguments(args);
+      p.start();
+      p.wait_for_exit();
+
+      if(p.exit_code() != 0) {
+        DBG_OUT("Couldn't enable fuse");
+
+        // Let the user know that they don't have FUSE installed on their machine
+        utils::HIGMessageDialog failedDlg(NULL, GTK_DIALOG_MODAL, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK,
+          _("Could not enable FUSE"),
+          _("The FUSE module could not be loaded. Please check that it is installed properly and try again."));
+        failedDlg.run();
+        return false;
+      }
+
+      // "echo fuse >> /etc/modules"
+      /*
+      // Punting for now.  Can't seem to get this to work.
+      // When using /etc/init.d/boot.local, you should add "modprobe fuse",
+      // and not what has been coded below.
+      p = new Process ();
+      p.StartInfo.UseShellExecute = false;
+      p.StartInfo.FileName = guisuTool;
+      p.StartInfo.Arguments = string.Format ("\"{0} fuse >> {1}\"",
+        echoTool, bootLocalFile);
+      p.StartInfo.CreateNoWindow = true;
+      p.Start ();
+      p.WaitForExit ();
+      if (p.ExitCode != 0) {
+       Logger.Warn ("Could not enable FUSE persistently.  User will have to be prompted again during their next login session.");
+      }
+      */
+      return true;
+    }
+
+    return false;
+  }
+
+  std::string SyncUtils::find_first_executable_in_path(const std::vector<std::string> & executableNames)
+  {
+    for(std::vector<std::string>::const_iterator iter = executableNames.begin();
+        iter != executableNames.end(); ++iter) {
+      std::string pathVar = Glib::getenv("PATH");
+      std::vector<std::string> paths;
+      const char separator[] = {G_SEARCHPATH_SEPARATOR, 0};
+      sharp::string_split(paths, pathVar, separator);
+
+      for(unsigned i = 0; i < sizeof(common_paths) / sizeof(char*); ++i) {
+        std::string commonPath = common_paths[i];
+        if(std::find(paths.begin(), paths.end(), commonPath) == paths.end()) {
+          paths.push_back(commonPath);
+        }
+      }
+
+      for(std::vector<std::string>::iterator path = paths.begin(); path != paths.end(); ++path) {
+        std::string testExecutablePath = Glib::build_filename(*path, *iter);
+        if(sharp::file_exists(testExecutablePath)) {
+          return testExecutablePath;
+        }
+      }
+      DBG_OUT("Unable to locate '%s' in your PATH", iter->c_str());
+    }
+
+    return "";
+  }
+
+  std::string SyncUtils::find_first_executable_in_path(const std::string & executableName)
+  {
+    std::vector<std::string> executable_names;
+    executable_names.push_back(executableName);
+    return find_first_executable_in_path(executable_names);
+  }
+
 }
 }
diff --git a/src/synchronization/syncutils.hpp b/src/synchronization/syncutils.hpp
index e5a4efe..232df7a 100644
--- a/src/synchronization/syncutils.hpp
+++ b/src/synchronization/syncutils.hpp
@@ -23,8 +23,10 @@
 
 
 #include <string>
+#include <vector>
 
 #include "note.hpp"
+#include "base/singleton.hpp"
 
 
 namespace gnote {
@@ -79,6 +81,21 @@ namespace sync {
     bool compare_tags(const std::map<std::string, Tag::Ptr> set1, const std::map<std::string, Tag::Ptr> set2) const;
   };
 
+
+  class SyncUtils
+    : public base::Singleton<SyncUtils>
+  {
+  public:
+    bool is_fuse_enabled();
+    bool enable_fuse();
+    std::string find_first_executable_in_path(const std::vector<std::string> & executableNames);
+    std::string find_first_executable_in_path(const std::string & executableName);
+  private:
+    static const char *common_paths[];
+    std::string m_guisu_tool;
+    std::string m_modprobe_tool;
+  };
+
 }
 }
 



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