Add support for the directEditing capability
authorMichael Schuster <michael@schuster.ms>
Sat, 18 Jan 2020 14:07:51 +0000 (15:07 +0100)
committerMichael Schuster <michael@schuster.ms>
Sat, 18 Jan 2020 14:07:51 +0000 (15:07 +0100)
- Fetch in ConnectionValidator::slotCapabilitiesRecieved
- Add editors to a list made of the new DirectEditor class

TODO:
- Add support for re-fetch and continously check for changes (ETag)

Signed-off-by: Michael Schuster <michael@schuster.ms>
src/gui/connectionvalidator.cpp
src/libsync/account.cpp
src/libsync/account.h
src/libsync/capabilities.cpp
src/libsync/capabilities.h

index b2f04d9b5fcd9eedb47850f15291229fadcebe71..36ac177aa2611c1f5d04decaa45721b01a18fe78 100644 (file)
@@ -249,6 +249,11 @@ void ConnectionValidator::slotCapabilitiesRecieved(const QJsonDocument &json)
         return;
     }
 
+    // Check for the directEditing capability
+    QUrl directEditingURL = QUrl(caps["files"].toObject()["directEditing"].toObject()["url"].toString());
+    QString directEditingETag = caps["files"].toObject()["directEditing"].toObject()["etag"].toString();
+    _account->fetchDirectEditors(directEditingURL, directEditingETag);
+
     fetchUser();
 }
 
index 076fb196d382155f14f53ab341237a7b9726ec26..97ae971a41bd9b7ae2f71d726764a8e3d9bd81b4 100644 (file)
@@ -35,6 +35,9 @@
 #include <QSslKey>
 #include <QAuthenticator>
 #include <QStandardPaths>
+#include <QJsonDocument>
+#include <QJsonObject>
+#include <QJsonArray>
 
 #include <keychain.h>
 #include "creds/abstractcredentials.h"
@@ -600,4 +603,49 @@ void Account::deleteAppPassword(){
     job->start();
 }
 
+void Account::fetchDirectEditors(const QUrl &directEditingURL, const QString &directEditingETag)
+{
+    if(directEditingURL.isEmpty() || directEditingETag.isEmpty())
+        return;
+
+    // Check for the directEditing capability
+    if (!directEditingURL.isEmpty() &&
+        (directEditingETag.isEmpty() || directEditingETag != _lastDirectEditingETag)) {
+            // Fetch the available editors and their mime types
+            JsonApiJob *job = new JsonApiJob(sharedFromThis(), QLatin1String("ocs/v2.php/apps/files/api/v1/directEditing"), this);
+            QObject::connect(job, &JsonApiJob::jsonReceived, this, &Account::slotDirectEditingRecieved);
+            job->start();
+    }
+}
+
+void Account::slotDirectEditingRecieved(const QJsonDocument &json)
+{
+    auto data = json.object().value("ocs").toObject().value("data").toObject();
+    auto editors = data.value("editors").toObject();
+
+    foreach (auto editorKey, editors.keys()) {
+        auto editor = editors.value(editorKey).toObject();
+
+        const QString id = editor.value("id").toString();
+        const QString name = editor.value("name").toString();
+
+        if(!id.isEmpty() && !name.isEmpty()) {
+            auto mimeTypes = editor.value("mimetypes").toArray();
+            auto optionalMimeTypes = editor.value("optionalMimetypes").toArray();
+
+            DirectEditor *directEditor = new DirectEditor(id, name);
+
+            foreach(auto mimeType, mimeTypes) {
+                directEditor->addMimetype(mimeType.toString().toLatin1());
+            }
+
+            foreach(auto optionalMimeType, optionalMimeTypes) {
+                directEditor->addOptionalMimetype(optionalMimeType.toString().toLatin1());
+            }
+
+            _capabilities.addDirectEditor(directEditor);
+        }
+    }
+}
+
 } // namespace OCC
index 1caef1991a81aafe9fc934cb6b7a777d242c57f0..32b79f4637a6951947a9bcf0f61a04ea65d4f374 100644 (file)
@@ -246,6 +246,10 @@ public:
     void writeAppPasswordOnce(QString appPassword);
     void deleteAppPassword();
 
+    /// Direct Editing
+    // Check for the directEditing capability
+    void fetchDirectEditors(const QUrl &directEditingURL, const QString &directEditingETag);
+
 public slots:
     /// Used when forgetting credentials
     void clearQNAMCache();
@@ -278,6 +282,7 @@ signals:
 protected Q_SLOTS:
     void slotCredentialsFetched();
     void slotCredentialsAsked();
+    void slotDirectEditingRecieved(const QJsonDocument &json);
 
 private:
     Account(QObject *parent = nullptr);
@@ -324,6 +329,9 @@ private:
 
     friend class AccountManager;
 
+    // Direct Editing
+    QString _lastDirectEditingETag;
+
     /* IMPORTANT - remove later - FIXME MS@2019-12-07 -->
      * TODO: For "Log out" & "Remove account": Remove client CA certs and KEY!
      *
index d0c5f727f7dbbf3e1dbdc84229b5efa61ae90ab3..ae32176ccd87f751c88dcfa7e9697cea58b4463b 100644 (file)
@@ -176,4 +176,85 @@ bool Capabilities::uploadConflictFiles() const
 
     return _capabilities["uploadConflictFiles"].toBool();
 }
+
+/*-------------------------------------------------------------------------------------*/
+
+// Direct Editing
+void Capabilities::addDirectEditor(DirectEditor* directEditor)
+{
+    if(directEditor)
+        _directEditors.append(directEditor);
+}
+
+DirectEditor* Capabilities::getDirectEditorForMimetype(const QMimeType &mimeType)
+{
+    foreach(DirectEditor* editor, _directEditors) {
+        if(editor->hasMimetype(mimeType))
+            return editor;
+    }
+
+    return nullptr;
+}
+
+DirectEditor* Capabilities::getDirectEditorForOptionalMimetype(const QMimeType &mimeType)
+{
+    foreach(DirectEditor* editor, _directEditors) {
+        if(editor->hasOptionalMimetype(mimeType))
+            return editor;
+    }
+
+    return nullptr;
+}
+
+/*-------------------------------------------------------------------------------------*/
+
+DirectEditor::DirectEditor(const QString &id, const QString &name, QObject* parent)
+    : QObject(parent)
+    , _id(id)
+    , _name(name)
+{
+}
+
+QString DirectEditor::id() const
+{
+    return _id;
+}
+
+QString DirectEditor::name() const
+{
+    return _name;
+}
+
+void DirectEditor::addMimetype(const QByteArray &mimeType)
+{
+    _mimeTypes.append(mimeType);
+}
+
+void DirectEditor::addOptionalMimetype(const QByteArray &mimeType)
+{
+    _optionalMimeTypes.append(mimeType);
+}
+
+QList<QByteArray> DirectEditor::mimeTypes() const
+{
+    return _mimeTypes;
+}
+
+QList<QByteArray> DirectEditor::optionalMimeTypes() const
+{
+    return _optionalMimeTypes;
+}
+
+bool DirectEditor::hasMimetype(const QMimeType &mimeType)
+{
+    return _mimeTypes.contains(mimeType.name().toLatin1());
+}
+
+bool DirectEditor::hasOptionalMimetype(const QMimeType &mimeType)
+{
+    return _optionalMimeTypes.contains(mimeType.name().toLatin1());
+}
+
+/*-------------------------------------------------------------------------------------*/
+
 }
index 8f8fd826a8ec7e752c4c13bf6fb46367fcc95357..fa0312b794fc8bed0af47287f208691d647901a7 100644 (file)
 
 #include <QVariantMap>
 #include <QStringList>
+#include <QMimeDatabase>
 
 namespace OCC {
 
+class DirectEditor;
+
 /**
  * @brief The Capabilities class represents the capabilities of an ownCloud
  * server
@@ -127,9 +130,47 @@ public:
      */
     bool uploadConflictFiles() const;
 
+    // Direct Editing
+    void addDirectEditor(DirectEditor* directEditor);
+    DirectEditor* getDirectEditorForMimetype(const QMimeType &mimeType);
+    DirectEditor* getDirectEditorForOptionalMimetype(const QMimeType &mimeType);
+
 private:
     QVariantMap _capabilities;
+
+    QList<DirectEditor*> _directEditors;
 };
+
+/*-------------------------------------------------------------------------------------*/
+
+class OWNCLOUDSYNC_EXPORT DirectEditor : public QObject
+{
+    Q_OBJECT
+public:
+    DirectEditor(const QString &id, const QString &name, QObject* parent = 0);
+
+    void addMimetype(const QByteArray &mimeType);
+    void addOptionalMimetype(const QByteArray &mimeType);
+
+    bool hasMimetype(const QMimeType &mimeType);
+    bool hasOptionalMimetype(const QMimeType &mimeType);
+
+    QString id() const;
+    QString name() const;
+
+    QList<QByteArray> mimeTypes() const;
+    QList<QByteArray> optionalMimeTypes() const;
+
+private:
+    QString _id;
+    QString _name;
+
+    QList<QByteArray> _mimeTypes;
+    QList<QByteArray> _optionalMimeTypes;
+};
+
+/*-------------------------------------------------------------------------------------*/
+
 }
 
 #endif //CAPABILITIES_H