wsd/DocumentBroker.cpp |   54 ++++++++++++++++++++++++++++++++++++++++++++++++-
 wsd/Storage.hpp        |    8 +++++++
 2 files changed, 61 insertions(+), 1 deletion(-)

New commits:
commit 2ed9d4c5ce5bfb9d61df157b23457565009d00d7
Author: Tor Lillqvist <t...@collabora.com>
Date:   Tue Nov 7 15:15:36 2017 +0200

    Add handling of "prefilter" plug-ins
    
    When the name of a document to be edited ends with an extension
    matching that mentioned in a prefilter plug-in's configuration file,
    the command specified is run and it is the output file that is
    actually edited.
    
    Change-Id: I3f107a50bb25a5a93e52932ba3c40a8758a1dc35
    Reviewed-on: https://gerrit.libreoffice.org/44718
    Reviewed-by: Aron Budea <aron.bu...@collabora.com>
    Tested-by: Aron Budea <aron.bu...@collabora.com>

diff --git a/wsd/DocumentBroker.cpp b/wsd/DocumentBroker.cpp
index 0d5e7342..93d285f9 100644
--- a/wsd/DocumentBroker.cpp
+++ b/wsd/DocumentBroker.cpp
@@ -21,6 +21,7 @@
 #include <Poco/Path.h>
 #include <Poco/SHA1Engine.h>
 #include <Poco/DigestStream.h>
+#include <Poco/Exception.h>
 #include <Poco/StreamCopier.h>
 #include <Poco/StringTokenizer.h>
 
@@ -534,7 +535,58 @@ bool DocumentBroker::load(const 
std::shared_ptr<ClientSession>& session, const s
     // Let's load the document now, if not loaded.
     if (!_storage->isLoaded())
     {
-        const auto localPath = 
_storage->loadStorageFileToLocal(session->getAuthorization());
+        auto localPath = 
_storage->loadStorageFileToLocal(session->getAuthorization());
+
+        // Check if we have a prefilter "plugin" for this document format
+        for (const auto& plugin : LOOLWSD::PluginConfigurations)
+        {
+            try
+            {
+                std::string 
extension(plugin->getString("prefilter.extension"));
+                std::string 
newExtension(plugin->getString("prefilter.newextension"));
+                std::string 
commandLine(plugin->getString("prefilter.commandline"));
+
+                if (localPath.length() > extension.length()+1 &&
+                    strcasecmp(localPath.substr(localPath.length() - 
extension.length() -1).data(), (std::string(".") + extension).data()) == 0)
+                {
+                    // Extension matches, try the conversion. We convert the 
file to another one in
+                    // the same (jail) directory, with just the new extension 
tacked on.
+
+                    std::string newRootPath = _storage->getRootFilePath() + 
"." + newExtension;
+
+                    // The commandline must contain the space-separated 
substring @INPUT@ that is
+                    // replaced with the input file name, and @OUTPUT@ for the 
output file name.
+
+                    std::vector<std::string>args;
+
+                    Poco::StringTokenizer tokenizer(commandLine, " ");
+                    if (tokenizer.replace("@INPUT@", 
_storage->getRootFilePath()) != 1 ||
+                        tokenizer.replace("@OUTPUT@", newRootPath) != 1)
+                        throw Poco::NotFoundException();
+
+                    for (std::size_t i = 1; i < tokenizer.count(); i++)
+                        args.push_back(tokenizer[i]);
+
+                    Poco::ProcessHandle process = 
Poco::Process::launch(tokenizer[0], args);
+                    int rc = process.wait();
+                    if (rc != 0)
+                    {
+                        LOG_ERR("Conversion from " << extension << " to " << 
newExtension <<" failed");
+                        return false;
+                    }
+                    _storage->setRootFilePath(newRootPath);
+                    localPath += "." + newExtension;
+                }
+
+                // We successfully converted the file to something LO can use; 
break out of the for
+                // loop.
+                break;
+            }
+            catch (const Poco::NotFoundException&)
+            {
+                // This plugin is not a proper prefilter one
+            }
+        }
 
         std::ifstream istr(localPath, std::ios::binary);
         Poco::SHA1Engine sha1;
diff --git a/wsd/Storage.hpp b/wsd/Storage.hpp
index 90dad874..c15ed130 100644
--- a/wsd/Storage.hpp
+++ b/wsd/Storage.hpp
@@ -129,6 +129,14 @@ public:
     /// Returns the root path to the jailed file.
     const std::string& getRootFilePath() const { return _jailedFilePath; };
 
+    /// Set the root path of the jailed file, only for use in cases where we 
actually have converted
+    /// it to another format, in the same directory
+    void setRootFilePath(const std::string& newPath)
+    {
+        // Could assert here that it is in the same directory?
+        _jailedFilePath = newPath;
+    };
+
     bool isLoaded() const { return _isLoaded; }
 
     /// Asks the storage object to force overwrite to storage upon next save
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to