From 1d323dd7b4202781b14fb04c3474d4c21b4a15e8 Mon Sep 17 00:00:00 2001 From: Akira Ohgaki <akiraohgaki@gmail.com> Date: Wed, 23 Nov 2016 16:02:54 +0900 Subject: [PATCH] Update qtlibs --- src/libs/qtlibs/networkresource.cpp | 123 +++++++++++++---- src/libs/qtlibs/networkresource.h | 25 +++- src/libs/qtlibs/ocsapi.cpp | 199 ++++++++++++++++++++++++++++ src/libs/qtlibs/ocsapi.h | 60 +++++++++ src/libs/qtlibs/qtlibs.pri | 2 + 5 files changed, 376 insertions(+), 33 deletions(-) create mode 100644 src/libs/qtlibs/ocsapi.cpp create mode 100644 src/libs/qtlibs/ocsapi.h diff --git a/src/libs/qtlibs/networkresource.cpp b/src/libs/qtlibs/networkresource.cpp index 1745a1c..9452d2c 100644 --- a/src/libs/qtlibs/networkresource.cpp +++ b/src/libs/qtlibs/networkresource.cpp @@ -17,8 +17,8 @@ namespace qtlibs { -NetworkResource::NetworkResource(const QString &name, const QUrl &url, bool async, QObject *parent) - : QObject(parent), name_(name), url_(url), async_(async) +NetworkResource::NetworkResource(const QString &id, const QUrl &url, bool async, QObject *parent) + : QObject(parent), id_(id), url_(url), async_(async) { setManager(new QNetworkAccessManager(this)); } @@ -31,7 +31,7 @@ NetworkResource::~NetworkResource() NetworkResource::NetworkResource(const NetworkResource &other, QObject *parent) : QObject(parent) { - setName(other.name()); + setId(other.id()); setUrl(other.url()); setAsync(other.async()); setRequest(other.request()); @@ -40,21 +40,21 @@ NetworkResource::NetworkResource(const NetworkResource &other, QObject *parent) NetworkResource &NetworkResource::operator =(const NetworkResource &other) { - setName(other.name()); + setId(other.id()); setUrl(other.url()); setAsync(other.async()); setRequest(other.request()); return *this; } -QString NetworkResource::name() const +QString NetworkResource::id() const { - return name_; + return id_; } -void NetworkResource::setName(const QString &name) +void NetworkResource::setId(const QString &id) { - name_ = name; + id_ = id; } QUrl NetworkResource::url() const @@ -102,20 +102,64 @@ QString NetworkResource::method() const return method_; } +QString NetworkResource::contentType() const +{ + return contentType_; +} + +QByteArray NetworkResource::contentData() const +{ + return contentData_; +} + NetworkResource *NetworkResource::head() { setMethod("HEAD"); - QNetworkRequest networkRequest = request(); - networkRequest.setUrl(url()); - return send(async(), networkRequest); + return send(url(), async()); } NetworkResource *NetworkResource::get() { setMethod("GET"); - QNetworkRequest networkRequest = request(); - networkRequest.setUrl(url()); - return send(async(), networkRequest); + return send(url(), async()); +} + +NetworkResource *NetworkResource::post(const QByteArray &contentData, const QString &contentType) +{ + setMethod("POST"); + setContentType(contentType); + setContentData(contentData); + return send(url(), async()); +} + +NetworkResource *NetworkResource::post(const QUrlQuery &contentData) +{ + setMethod("POST"); + setContentType("application/x-www-form-urlencoded"); + setContentData(contentData.toString(QUrl::FullyEncoded).toUtf8()); + return send(url(), async()); +} + +NetworkResource *NetworkResource::put(const QByteArray &contentData, const QString &contentType) +{ + setMethod("PUT"); + setContentType(contentType); + setContentData(contentData); + return send(url(), async()); +} + +NetworkResource *NetworkResource::put(const QUrlQuery &contentData) +{ + setMethod("PUT"); + setContentType("application/x-www-form-urlencoded"); + setContentData(contentData.toString(QUrl::FullyEncoded).toUtf8()); + return send(url(), async()); +} + +NetworkResource *NetworkResource::deleteResource() +{ + setMethod("DELETE"); + return send(url(), async()); } bool NetworkResource::isFinishedWithNoError() @@ -155,21 +199,19 @@ void NetworkResource::replyFinished() if (isFinishedWithNoError()) { // Check if redirection // Note: An auto redirection option is available since Qt 5.6 - QString newUrl; + QUrl redirectUrl; if (reply()->hasRawHeader("Location")) { - newUrl = QString(reply()->rawHeader("Location")); + redirectUrl.setUrl(QString(reply()->rawHeader("Location"))); } else if (reply()->hasRawHeader("Refresh")) { - newUrl = QString(reply()->rawHeader("Refresh")).split("url=").last(); + redirectUrl.setUrl(QString(reply()->rawHeader("Refresh")).split("url=").last()); } - if (!newUrl.isEmpty()) { - if (newUrl.startsWith("/")) { - newUrl = reply()->url().authority() + newUrl; + if (!redirectUrl.isEmpty()) { + if (redirectUrl.isRelative()) { + redirectUrl = reply()->url().resolved(redirectUrl); } - QNetworkRequest networkRequest = request(); - networkRequest.setUrl(QUrl(newUrl)); reply()->deleteLater(); - send(true, networkRequest); + send(redirectUrl, true); return; } } @@ -191,16 +233,43 @@ void NetworkResource::setMethod(const QString &method) method_ = method; } -NetworkResource *NetworkResource::send(bool async, const QNetworkRequest &request) +void NetworkResource::setContentType(const QString &contentType) +{ + contentType_ = contentType; +} + +void NetworkResource::setContentData(const QByteArray &contentData) { + contentData_ = contentData; +} + +NetworkResource *NetworkResource::send(const QUrl &url, bool async) +{ + QNetworkRequest networkRequest = request(); + networkRequest.setUrl(url); if (method() == "HEAD") { - setReply(manager()->head(request)); + setReply(manager()->head(networkRequest)); } else if (method() == "GET") { - setReply(manager()->get(request)); - connect(reply(), &QNetworkReply::downloadProgress, this, &NetworkResource::downloadProgress); + setReply(manager()->get(networkRequest)); + } + else if (method() == "POST") { + networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, QVariant(contentType())); + setReply(manager()->post(networkRequest, contentData())); + } + else if (method() == "PUT") { + networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, QVariant(contentType())); + setReply(manager()->put(networkRequest, contentData())); + } + else if (method() == "DELETE") { + setReply(manager()->deleteResource(networkRequest)); + } + else { + Q_ASSERT(false); } connect(reply(), &QNetworkReply::finished, this, &NetworkResource::replyFinished); + connect(reply(), &QNetworkReply::downloadProgress, this, &NetworkResource::downloadProgress); + connect(reply(), &QNetworkReply::uploadProgress, this, &NetworkResource::uploadProgress); if (!async) { QEventLoop eventLoop; connect(this, &NetworkResource::finished, &eventLoop, &QEventLoop::quit); diff --git a/src/libs/qtlibs/networkresource.h b/src/libs/qtlibs/networkresource.h index 0a95190..4d9e041 100644 --- a/src/libs/qtlibs/networkresource.h +++ b/src/libs/qtlibs/networkresource.h @@ -13,6 +13,7 @@ #include <QObject> #include <QUrl> +#include <QUrlQuery> #include <QNetworkRequest> #include <QNetworkAccessManager> #include <QNetworkReply> @@ -24,14 +25,14 @@ class NetworkResource : public QObject Q_OBJECT public: - explicit NetworkResource(const QString &name = "", const QUrl &url = QUrl(), bool async = true, QObject *parent = 0); + explicit NetworkResource(const QString &id = "", const QUrl &url = QUrl(), bool async = true, QObject *parent = 0); ~NetworkResource(); NetworkResource(const NetworkResource &other, QObject *parent = 0); NetworkResource &operator =(const NetworkResource &other); - QString name() const; - void setName(const QString &name); + QString id() const; + void setId(const QString &id); QUrl url() const; void setUrl(const QUrl &url); bool async() const; @@ -41,16 +42,24 @@ public: QNetworkAccessManager *manager() const; QNetworkReply *reply() const; QString method() const; + QString contentType() const; + QByteArray contentData() const; NetworkResource *head(); NetworkResource *get(); + NetworkResource *post(const QByteArray &contentData, const QString &contentType); + NetworkResource *post(const QUrlQuery &contentData); + NetworkResource *put(const QByteArray &contentData, const QString &contentType); + NetworkResource *put(const QUrlQuery &contentData); + NetworkResource *deleteResource(); bool isFinishedWithNoError(); QByteArray readData(); bool saveData(const QString &path); signals: void finished(NetworkResource *resource); - void downloadProgress(const qint64 &bytesReceived, const qint64 &bytesTotal); + void downloadProgress(qint64 bytesReceived, qint64 bytesTotal); + void uploadProgress(qint64 bytesSent, qint64 bytesTotal); public slots: void abort(); @@ -62,16 +71,20 @@ private: void setManager(QNetworkAccessManager *manager); void setReply(QNetworkReply *reply); void setMethod(const QString &method); + void setContentType(const QString &contentType); + void setContentData(const QByteArray &contentData); - NetworkResource *send(bool async, const QNetworkRequest &request); + NetworkResource *send(const QUrl &url, bool async); - QString name_; + QString id_; QUrl url_; bool async_; QNetworkRequest request_; QNetworkAccessManager *manager_; QNetworkReply *reply_; QString method_; + QString contentType_; + QByteArray contentData_; }; } // namespace qtlibs diff --git a/src/libs/qtlibs/ocsapi.cpp b/src/libs/qtlibs/ocsapi.cpp new file mode 100644 index 0000000..389c2bf --- /dev/null +++ b/src/libs/qtlibs/ocsapi.cpp @@ -0,0 +1,199 @@ +/** + * A library for Qt app + * + * LICENSE: The GNU Lesser General Public License, version 3.0 + * + * @author Akira Ohgaki <akiraohgaki@gmail.com> + * @copyright Akira Ohgaki + * @license https://opensource.org/licenses/LGPL-3.0 The GNU Lesser General Public License, version 3.0 + * @link https://github.com/akiraohgaki/qtlibs + */ + +#include "ocsapi.h" + +#include <QXmlStreamReader> + +#include "json.h" +#include "networkresource.h" + +namespace qtlibs { + +// OCS-API Specification +// https://www.freedesktop.org/wiki/Specifications/open-collaboration-services/ + +OcsApi::OcsApi(const QString &id, const QUrl &baseUrl, const QString &userName, const QString &password, QObject *parent) + : QObject(parent), id_(id), baseUrl_(baseUrl), userName_(userName), password_(password) +{} + +OcsApi::OcsApi(const OcsApi &other, QObject *parent) + : QObject(parent) +{ + setId(other.id()); + setBaseUrl(other.baseUrl()); + setUserName(other.userName()); + setPassword(other.password()); +} + +OcsApi &OcsApi::operator =(const OcsApi &other) +{ + setId(other.id()); + setBaseUrl(other.baseUrl()); + setUserName(other.userName()); + setPassword(other.password()); + return *this; +} + +QString OcsApi::id() const +{ + return id_; +} + +void OcsApi::setId(const QString &id) +{ + id_ = id; +} + +QUrl OcsApi::baseUrl() const +{ + return baseUrl_; +} + +void OcsApi::setBaseUrl(const QUrl &baseUrl) +{ + baseUrl_ = baseUrl; +} + +QString OcsApi::userName() const +{ + return userName_; +} + +void OcsApi::setUserName(const QString &userName) +{ + userName_ = userName; +} + +QString OcsApi::password() const +{ + return password_; +} + +void OcsApi::setPassword(const QString &password) +{ + password_ = password; +} + +QJsonObject OcsApi::getConfig() +{ + QUrl url = baseUrl().resolved(QUrl("config")); + url.setQuery("format=json"); + qtlibs::NetworkResource resource(url.toString(), url, false); + return qtlibs::Json(resource.get()->readData()).toObject(); +} + +QJsonObject OcsApi::checkPerson() +{ + QUrl url = baseUrl().resolved(QUrl("person/check")); + QUrlQuery formData; + formData.addQueryItem("login", userName()); + formData.addQueryItem("password", password()); + formData.addQueryItem("format", "json"); + qtlibs::NetworkResource resource(url.toString(), url, false); + return qtlibs::Json(resource.post(formData)->readData()).toObject(); +} + +QJsonObject OcsApi::getPersonDataSet(const QUrlQuery &query) +{ + QUrl url = baseUrl().resolved(QUrl("person/data")); + url.setUserName(userName()); + url.setPassword(password()); + QUrlQuery newQuery(query); + newQuery.removeQueryItem("format"); + newQuery.addQueryItem("format", "json"); + url.setQuery(newQuery); + qtlibs::NetworkResource resource(url.toString(), url, false); + return qtlibs::Json(resource.get()->readData()).toObject(); +} + +QJsonObject OcsApi::getPersonData(const QString &personId) +{ + QUrl url = baseUrl().resolved(QUrl("person/data/" + personId)); + url.setUserName(userName()); + url.setPassword(password()); + url.setQuery("format=json"); + qtlibs::NetworkResource resource(url.toString(), url, false); + return qtlibs::Json(resource.get()->readData()).toObject(); +} + +QJsonObject OcsApi::getPersonSelf() +{ + QUrl url = baseUrl().resolved(QUrl("person/self")); + url.setUserName(userName()); + url.setPassword(password()); + url.setQuery("format=json"); + qtlibs::NetworkResource resource(url.toString(), url, false); + return qtlibs::Json(resource.get()->readData()).toObject(); +} + +QJsonObject OcsApi::getContentCategories() +{ + QUrl url = baseUrl().resolved(QUrl("content/categories")); + url.setQuery("format=json"); + qtlibs::NetworkResource resource(url.toString(), url, false); + return qtlibs::Json(resource.get()->readData()).toObject(); +} + +QJsonObject OcsApi::getContentDataSet(const QUrlQuery &query) +{ + QUrl url = baseUrl().resolved(QUrl("content/data")); + QUrlQuery newQuery(query); + newQuery.removeQueryItem("format"); + newQuery.addQueryItem("format", "json"); + url.setQuery(newQuery); + qtlibs::NetworkResource resource(url.toString(), url, false); + return qtlibs::Json(resource.get()->readData()).toObject(); +} + +QJsonObject OcsApi::getContentData(const QString &contentId) +{ + QUrl url = baseUrl().resolved(QUrl("content/data/" + contentId)); + url.setQuery("format=json"); + qtlibs::NetworkResource resource(url.toString(), url, false); + return qtlibs::Json(resource.get()->readData()).toObject(); +} + +QJsonObject OcsApi::getContentDownload(const QString &contentId, const QString &itemId) +{ + QUrl url = baseUrl().resolved(QUrl("content/download/" + contentId + "/" + itemId)); + url.setQuery("format=json"); + qtlibs::NetworkResource resource(url.toString(), url, false); + return qtlibs::Json(resource.get()->readData()).toObject(); +} + +QJsonArray OcsApi::getProviderFile(const QUrl &url) +{ + QJsonArray providers; + qtlibs::NetworkResource resource(url.toString(), url, false); + QXmlStreamReader reader(resource.get()->readData()); + QStringList whitelist; + whitelist << "id" << "location" << "name" << "icon" << "termsofuse" << "register"; + while (!reader.atEnd() && !reader.hasError()) { + reader.readNext(); + if (reader.isStartElement() && reader.name() == "provider") { + QJsonObject provider; + provider["_providerfile"] = url.toString(); + providers.append(provider); + continue; + } + QString elementName = reader.name().toString(); + if (!providers.isEmpty() && whitelist.contains(elementName)) { + int i(providers.size() - 1); + QJsonObject provider = providers[i].toObject(); + provider[elementName] = reader.readElementText(); + providers[i] = provider; + } + } + return providers; +} + +} // namespace qtlibs diff --git a/src/libs/qtlibs/ocsapi.h b/src/libs/qtlibs/ocsapi.h new file mode 100644 index 0000000..3e43748 --- /dev/null +++ b/src/libs/qtlibs/ocsapi.h @@ -0,0 +1,60 @@ +/** + * A library for Qt app + * + * LICENSE: The GNU Lesser General Public License, version 3.0 + * + * @author Akira Ohgaki <akiraohgaki@gmail.com> + * @copyright Akira Ohgaki + * @license https://opensource.org/licenses/LGPL-3.0 The GNU Lesser General Public License, version 3.0 + * @link https://github.com/akiraohgaki/qtlibs + */ + +#pragma once + +#include <QObject> +#include <QUrl> +#include <QUrlQuery> +#include <QJsonObject> +#include <QJsonArray> + +namespace qtlibs { + +class OcsApi : public QObject +{ + Q_OBJECT + +public: + explicit OcsApi(const QString &id = "", const QUrl &baseUrl = QUrl(), const QString &userName = "", const QString &password = "", QObject *parent = 0); + + OcsApi(const OcsApi &other, QObject *parent = 0); + OcsApi &operator =(const OcsApi &other); + + QString id() const; + void setId(const QString &id); + QUrl baseUrl() const; + void setBaseUrl(const QUrl &baseUrl); + QString userName() const; + void setUserName(const QString &userName); + QString password() const; + void setPassword(const QString &password); + + QJsonObject getConfig(); + QJsonObject checkPerson(); + QJsonObject getPersonDataSet(const QUrlQuery &query = QUrlQuery()); + QJsonObject getPersonData(const QString &personId); + QJsonObject getPersonSelf(); + QJsonObject getContentCategories(); + QJsonObject getContentDataSet(const QUrlQuery &query = QUrlQuery()); + QJsonObject getContentData(const QString &contentId); + QJsonObject getContentDownload(const QString &contentId, const QString &itemId); + + static QJsonArray getProviderFile(const QUrl &url); + +private: + QString id_; + QUrl baseUrl_; + QString userName_; + QString password_; +}; + +} // namespace qtlibs diff --git a/src/libs/qtlibs/qtlibs.pri b/src/libs/qtlibs/qtlibs.pri index 1050283..09fce3e 100644 --- a/src/libs/qtlibs/qtlibs.pri +++ b/src/libs/qtlibs/qtlibs.pri @@ -8,6 +8,7 @@ HEADERS += \ $${PWD}/json.h \ $${PWD}/config.h \ $${PWD}/networkresource.h \ + $${PWD}/ocsapi.h \ $${PWD}/package.h SOURCES += \ @@ -16,6 +17,7 @@ SOURCES += \ $${PWD}/json.cpp \ $${PWD}/config.cpp \ $${PWD}/networkresource.cpp \ + $${PWD}/ocsapi.cpp \ $${PWD}/package.cpp unix:!ios:!android { -- GitLab