From a19e2ffd7d661f00bb9c2f71b366e237528b54e9 Mon Sep 17 00:00:00 2001 From: ssakone Date: Mon, 30 Jun 2025 11:15:07 +0000 Subject: [PATCH 1/2] update --- .qmlls.ini | 5 + CMakeLists.txt | 5 - src/PocketBase.hpp | 12 +- src/PocketBaseCollection.cpp | 42 +- src/PocketBaseCollection.h | 6 +- src/PocketRequest.cpp | 1091 ++++++++++++++++++---------------- 6 files changed, 576 insertions(+), 585 deletions(-) create mode 100644 .qmlls.ini diff --git a/.qmlls.ini b/.qmlls.ini new file mode 100644 index 0000000..6629cc2 --- /dev/null +++ b/.qmlls.ini @@ -0,0 +1,5 @@ +[General] +buildDir="/Users/enokas/WorkStation/01STUDIO/BMASTER/build" +no-cmake-calls=false +docDir=/Users/enokas/Qt/Docs/Qt-6.9.0 +importPaths="/Users/enokas/Qt/6.9.0/macos/qml" diff --git a/CMakeLists.txt b/CMakeLists.txt index c5cca24..d1c89e2 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,11 +17,6 @@ qt6_add_qml_module(PocketBase SOURCES src/PocketBase.hpp SOURCES src/PocketBaseCollection.h src/PocketBaseCollection.cpp SOURCES src/PocketBaseCollectionPromise.h src/PocketBaseCollectionPromise.cpp - SOURCES src/PocketBaseCollectionSchema.h src/PocketBaseCollectionSchema.cpp - SOURCES src/PocketBaseCollectionField.h src/PocketBaseCollectionField.cpp - SOURCES src/CollectionFieldOptions.h src/CollectionFieldOptions.cpp - SOURCES src/CollectionTextFieldOptions.h src/CollectionTextFieldOptions.cpp - SOURCES src/CollectionFileFieldOptions.h src/CollectionFileFieldOptions.cpp SOURCES src/PocketBaseClient.h src/PocketBaseClient.cpp SOURCES src/PocketRequest.h src/PocketRequest.cpp SOURCES src/PocketUtility.h src/PocketUtility.cpp diff --git a/src/PocketBase.hpp b/src/PocketBase.hpp index 13dfd7c..12787ec 100755 --- a/src/PocketBase.hpp +++ b/src/PocketBase.hpp @@ -1,20 +1,11 @@ #include "CollectionSubscriber.h" #include "PocketBaseCollection.h" -#include "PocketBaseCollectionField.h" -#include "PocketBaseCollectionSchema.h" -#include "CollectionFileFieldOptions.h" -#include "CollectionFieldOptions.h" -#include "CollectionTextFieldOptions.h" #include "PocketBaseClient.h" #include "PocketBaseServer.h" #include void registerPocketBaseType() { - qmlRegisterType("PocketBase", 1, 0, "BaseCollection"); - qmlRegisterType("PocketBase", 1, 0, "CollectionField"); - qmlRegisterType("PocketBase", 1, 0, "CollectionSchema"); - qmlRegisterType("PocketBase", 1, 0, "FileFieldOptions"); - qmlRegisterType("PocketBase", 1, 0, "TextFieldOptions"); + // qmlRegisterType("PocketBase", 1, 0, "BaseCollection"); qmlRegisterSingletonType("PocketBase", 1, 0, "PocketRequest", [](QQmlEngine *engine, QJSEngine *scriptEngine) -> QObject* { Q_UNUSED(engine) Q_UNUSED(scriptEngine) @@ -22,7 +13,6 @@ void registerPocketBaseType() { }); qmlRegisterType("PocketBase", 1, 0, "Subscriber"); - qmlRegisterUncreatableType("PocketBase", 1, 0, "FieldOptions", "FieldOptions is an abstract class"); qmlRegisterSingletonType("PocketBase", 1, 0, "PocketBaseClient", [](QQmlEngine *engine, QJSEngine *scriptEngine) -> QObject* { Q_UNUSED(engine) diff --git a/src/PocketBaseCollection.cpp b/src/PocketBaseCollection.cpp index 8c0bc1e..fdce318 100755 --- a/src/PocketBaseCollection.cpp +++ b/src/PocketBaseCollection.cpp @@ -115,19 +115,7 @@ QJsonObject PocketBaseCollection::getOptions(QJSValue options) void PocketBaseCollection::prepare() { - PocketBaseCollectionSchema *schema = findChild(); - QJsonObject collectionSchema = {}; - collectionSchema["schema"] = schema->schemaJson(); - collectionSchema["name"] = schema->name(); - collectionSchema["type"] = "base"; - collectionSchema["indexes"] = QJsonArray(); - collectionSchema["listRule"] = schema->listRule(); - collectionSchema["viewRule"] = schema->viewRule(); - collectionSchema["createRule"] = schema->createRule(); - collectionSchema["updateRule"] = schema->updateRule(); - collectionSchema["deleteRule"] = schema->deleteRule(); - collectionSchema["id"] = schema->collectionId(); - collectionSchema["options"] = QJsonObject(); + } @@ -172,18 +160,6 @@ void PocketBaseCollection::setName(const QString &newName) emit nameChanged(); } -PocketBaseCollectionSchema *PocketBaseCollection::schema() const -{ - return m_schema; -} - -void PocketBaseCollection::setSchema(PocketBaseCollectionSchema *newSchema) -{ - if (m_schema == newSchema) - return; - m_schema = newSchema; - emit schemaChanged(); -} PocketRequest *PocketBaseCollection::getRequest() const { @@ -192,21 +168,5 @@ PocketRequest *PocketBaseCollection::getRequest() const QJsonObject PocketBaseCollection::toJson() { - if (m_schema) { - PocketBaseCollectionSchema *schema = findChild(); - QJsonObject collectionSchema = {}; - collectionSchema["schema"] = schema->schemaJson(); - collectionSchema["name"] = schema->name(); - collectionSchema["type"] = "base"; - collectionSchema["indexes"] = QJsonArray(); - collectionSchema["listRule"] = schema->listRule(); - collectionSchema["viewRule"] = schema->viewRule(); - collectionSchema["createRule"] = schema->createRule(); - collectionSchema["updateRule"] = schema->updateRule(); - collectionSchema["deleteRule"] = schema->deleteRule(); - collectionSchema["id"] = schema->collectionId(); - collectionSchema["options"] = QJsonObject(); - return collectionSchema; - } return QJsonObject(); } diff --git a/src/PocketBaseCollection.h b/src/PocketBaseCollection.h index 2d1f004..4904b75 100755 --- a/src/PocketBaseCollection.h +++ b/src/PocketBaseCollection.h @@ -17,11 +17,11 @@ class PocketBaseCollection : public QObject { Q_OBJECT QML_ELEMENT + QML_NAMED_ELEMENT(BaseCollection) Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged FINAL) Q_PROPERTY(QString expands READ expands WRITE setExpands NOTIFY expandChangeds FINAL) Q_PROPERTY(QStringList fields READ fields WRITE setFields NOTIFY fieldsChanged FINAL) - Q_PROPERTY(PocketBaseCollectionSchema *schema READ schema WRITE setSchema NOTIFY schemaChanged FINAL) public: explicit PocketBaseCollection(QObject *parent = nullptr); @@ -57,9 +57,6 @@ class PocketBaseCollection : public QObject QString name() const; void setName(const QString &newName); - PocketBaseCollectionSchema *schema() const; - void setSchema(PocketBaseCollectionSchema *newSchema); - PocketRequest *getRequest() const; QJsonObject toJson(); @@ -79,7 +76,6 @@ class PocketBaseCollection : public QObject PocketRequest *viewRequest; - PocketBaseCollectionSchema *m_schema = nullptr; signals: void expandChangeds(); diff --git a/src/PocketRequest.cpp b/src/PocketRequest.cpp index ec16812..f85217a 100644 --- a/src/PocketRequest.cpp +++ b/src/PocketRequest.cpp @@ -1,523 +1,568 @@ -#include "PocketRequest.h" -#include "PocketUtility.h" -#include "qjsondocument.h" -#include "qurlquery.h" -#include "pocketnetworkmanager.h" -#include "PocketBaseSettings.h" -#include -#include -#include - -PocketRequest::PocketRequest(QObject *parent) - : QObject{parent} -{ - manager = PocketNetworkManager::instance2(); -} - -PocketBaseCollectionPromise *PocketRequest::getOne(QString id, QJsonObject options) -{ - return makeRequest(getRequest(getRequestParams(options), false, "/" + id), HttpMethod::GET); -} - -PocketBaseCollectionPromise *PocketRequest::getList(int page, int perPage, QJsonObject options) -{ - options.insert("page", QString::number(page)); - options.insert("perPage", QString::number(perPage)); - QNetworkRequest request = getRequest(getRequestParams(options), false); - - return makeRequest(request); -} - -PocketBaseCollectionPromise *PocketRequest::create(QJSValue data, QJsonObject options) -{ - const QJsonObject& obj = PocketUtility::jsvalueToJsonObject(data); - return makeRequest(getRequest(getRequestParams(options), true), HttpMethod::POST, QJsonDocument(obj).toJson()); -} - -PocketBaseCollectionPromise *PocketRequest::create(QJsonObject data, QJsonObject options) -{ - return makeRequest(getRequest(getRequestParams(options), true), HttpMethod::POST, QJsonDocument(data).toJson()); -} - -PocketBaseCollectionPromise *PocketRequest::createWithFile(QJSValue data, QJSValue files, QJsonObject options) -{ - QJsonObject obj = PocketUtility::jsvalueToJsonObject(data); - QJsonObject fobj = files.toVariant().toJsonObject(); - - QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType); - - PocketUtility::jsonToFormData(multiPart, obj); - PocketUtility::jsonFilesToFormData(multiPart, fobj); - QNetworkRequest request = getRequest(getRequestParams(options), false); - return makeRequest(&request, HttpMethod::POST, multiPart); -} - -PocketBaseCollectionPromise *PocketRequest::update(QString id, QJSValue data, QJsonObject options) -{ - const QJsonObject& obj = PocketUtility::jsvalueToJsonObject(data); - return makeRequest(getRequest(getRequestParams(options), true, "/" + id), HttpMethod::PATCH, QJsonDocument(obj).toJson()); -} - -PocketBaseCollectionPromise *PocketRequest::update(QString id, QJsonObject data, QJsonObject options) -{ - return makeRequest(getRequest(getRequestParams(options), true, "/" + id), HttpMethod::PATCH, QJsonDocument(data).toJson()); -} - -PocketBaseCollectionPromise *PocketRequest::updateWithFile(QString id, QJSValue data, QJSValue files, QJsonObject options) -{ - QJsonObject obj = PocketUtility::jsvalueToJsonObject(data); - QJsonObject fobj = files.toVariant().toJsonObject(); - - QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType); - - PocketUtility::jsonToFormData(multiPart, obj); - PocketUtility::jsonFilesToFormData(multiPart, fobj); - - multiPart->dumpObjectTree(); - - QNetworkRequest request = getRequest(getRequestParams(options), false, "/" + id); - return makeRequest(&request, HttpMethod::PATCH, multiPart); -} - -PocketBaseCollectionPromise *PocketRequest::deleteFile(QString id, QJSValue files, QJsonObject options) -{ - QJsonObject fobj = files.toVariant().toJsonObject(); - QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType); - PocketUtility::jsonFilesToFormData(multiPart, fobj); - - QNetworkRequest request = getRequest(getRequestParams(options), false, "/" + id); - return makeRequest(&request, HttpMethod::PATCH, multiPart); -} - -PocketBaseCollectionPromise *PocketRequest::deleteOne(QString id, QJsonObject options) -{ - return makeRequest(getRequest(getRequestParams(options), false, "/" + id), HttpMethod::DELETE); -} - -PocketBaseCollectionPromise *PocketRequest::authWithPassword(QString identity, QString password) -{ - QJsonObject obj; - obj.insert("identity", identity); - obj.insert("password", password); - return makeRequest(getRequest(getRequestParams({}), true), HttpMethod::POST, QJsonDocument(obj).toJson(QJsonDocument::Compact)); -} - -PocketBaseCollectionPromise *PocketRequest::authRefresh() -{ - return makeRequest(getRequest(getRequestParams({}), true), HttpMethod::POST); -} - -PocketBaseCollectionPromise *PocketRequest::HttpGet(QString path, QJSValue options, bool other) -{ - const QJsonObject& obj = PocketUtility::jsvalueToJsonObject(options); - return makeRequest(getRequest(getRequestParams(obj), false, path, true, other), HttpMethod::GET); -} - -PocketBaseCollectionPromise *PocketRequest::HttpPostFile(QString path, QJSValue data, QJSValue files, QJSValue options, bool other) -{ - const QJsonObject& op = PocketUtility::jsvalueToJsonObject(options); - QJsonObject obj = PocketUtility::jsvalueToJsonObject(data); - QJsonObject fobj = files.toVariant().toJsonObject(); - - QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType); - - PocketUtility::jsonToFormData(multiPart, obj); - PocketUtility::jsonFilesToFormData(multiPart, fobj); - QNetworkRequest request = getRequest(getRequestParams(op), true, path, true, other); - return makeRequest(&request, HttpMethod::POST, multiPart); - -} - -PocketBaseCollectionPromise *PocketRequest::HttpPost(QString path, QJSValue data, QJSValue options, bool other) -{ - const QJsonObject& obj = PocketUtility::jsvalueToJsonObject(options); - const QJsonObject& datas = PocketUtility::jsvalueToJsonObject(data); - return makeRequest(getRequest(getRequestParams(obj), true, path, true, other), HttpMethod::POST, QJsonDocument(datas).toJson()); -} - -PocketBaseCollectionPromise *PocketRequest::HttpPost(QString path, QJsonObject datas, QJsonObject obj) -{ - return makeRequest(getRequest(getRequestParams(obj), true, path, true), HttpMethod::POST, QJsonDocument(datas).toJson()); -} - -PocketBaseCollectionPromise *PocketRequest::HttpPut(QString path, QJSValue data, QJSValue options) -{ - const QJsonObject& obj = PocketUtility::jsvalueToJsonObject(options); - QJsonObject datas = data.toVariant().toJsonObject(); - return makeRequest(getRequest(QUrlQuery(), true, path, true), HttpMethod::PUT, QJsonDocument(datas).toJson()); -} - -PocketBaseCollectionPromise *PocketRequest::HttpPut(QString path, QJsonObject datas) -{ - return makeRequest(getRequest(QUrlQuery(), true, path, true), HttpMethod::PUT, QJsonDocument(datas).toJson()); -} - -PocketBaseCollectionPromise *PocketRequest::HttpPatch(QString path, QJSValue data, QJSValue options) -{ - const QJsonObject& obj = PocketUtility::jsvalueToJsonObject(options); - const QJsonObject& datas = PocketUtility::jsvalueToJsonObject(data); - return makeRequest(getRequest(getRequestParams(obj), true, path, true), HttpMethod::PATCH, QJsonDocument(datas).toJson()); -} - -PocketBaseCollectionPromise *PocketRequest::HttpDelete(QString path, QJSValue options) -{ - const QJsonObject& obj = PocketUtility::jsvalueToJsonObject(options); - return makeRequest(getRequest(getRequestParams(obj), false, path, true, true), HttpMethod::DELETE); -} - -PocketBaseCollectionPromise *PocketRequest::makeRequest(QNetworkRequest request, HttpMethod method) -{ - PocketBaseCollectionPromise *promise = new PocketBaseCollectionPromise(this); - - QNetworkReply *reply; - - reply = manager->sendCustomRequest(request, methodToString(method)); - - connect(reply, &QNetworkReply::finished, promise, [=]() - { - if (reply->error() == QNetworkReply::NoError) { - promise->callThen(QJSValueList{QString(reply->readAll())}); - }else if (reply->error() != QNetworkReply::ConnectionRefusedError && reply->error() != QNetworkReply::HostNotFoundError && reply->error() != QNetworkReply::TimeoutError && reply->error() != QNetworkReply::UnknownNetworkError) { - QJsonObject error; - error.insert("code", reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt()); - error.insert("message", reply->errorString()); - error.insert("data", QString(reply->readAll())); - promise->callError(QJSValueList{QString(QJsonDocument(error).toJson())}); - } - }); - - connect(reply, &QNetworkReply::errorOccurred, promise, [=](QNetworkReply::NetworkError error) - { - if (error == QNetworkReply::ConnectionRefusedError || error == QNetworkReply::HostNotFoundError || error == QNetworkReply::TimeoutError || error == QNetworkReply::UnknownNetworkError) { - QJsonObject errorJson; - errorJson.insert("code", 0); - errorJson.insert("message", reply->errorString()); - promise->callError(QJSValueList{QString(QJsonDocument(errorJson).toJson())}); - } - }); - - return promise; -} - -PocketBaseCollectionPromise *PocketRequest::makeRequest(QNetworkRequest request, HttpMethod method, QByteArray data) -{ - PocketBaseCollectionPromise *promise = new PocketBaseCollectionPromise(this); - - QNetworkReply *reply; - - reply = manager->sendCustomRequest(request, methodToString(method), data); - connect(reply, &QNetworkReply::finished, promise, [reply, promise]() - { - if (reply->error() == QNetworkReply::NoError) { - promise->callThen(QJSValueList{QString(reply->readAll())}); - }else if (reply->error() != QNetworkReply::ConnectionRefusedError && reply->error() != QNetworkReply::HostNotFoundError && reply->error() != QNetworkReply::TimeoutError && reply->error() != QNetworkReply::UnknownNetworkError) { - QJsonObject error; - QString data = reply->readAll(); - error.insert("code", reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt()); - error.insert("message", reply->errorString() + "," + data); - error.insert("data", data); - promise->callError(QJSValueList{QString(QJsonDocument(error).toJson())}); - } - }); - - connect(reply, &QNetworkReply::errorOccurred, promise, [=](QNetworkReply::NetworkError error) - { - if (error == QNetworkReply::ConnectionRefusedError || error == QNetworkReply::HostNotFoundError || error == QNetworkReply::TimeoutError || error == QNetworkReply::UnknownNetworkError) { - QJsonObject errorJson; - errorJson.insert("code", reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt()); - errorJson.insert("message", reply->errorString() + reply->readAll()); - promise->callError(QJSValueList{QString(QJsonDocument(errorJson).toJson())}); - } - }); - - return promise; -} - -PocketBaseCollectionPromise *PocketRequest::makeRequest(QNetworkRequest *request, HttpMethod method, QHttpMultiPart *multipart) -{ - PocketBaseCollectionPromise *promise = new PocketBaseCollectionPromise(this); - - QNetworkReply *reply; - - reply = manager->sendCustomRequest(*request, methodToString(method), multipart); - - connect(reply, &QNetworkReply::finished, promise, [=]() - { - if (reply->error() == QNetworkReply::NoError) { - promise->callThen(QJSValueList{QString(reply->readAll())}); - } else if (reply->error() != QNetworkReply::ConnectionRefusedError && reply->error() != QNetworkReply::HostNotFoundError && reply->error() != QNetworkReply::TimeoutError && reply->error() != QNetworkReply::UnknownNetworkError) { - QJsonObject error; - error.insert("code", reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt()); - error.insert("message", reply->errorString()); - error.insert("data", QString(reply->readAll())); - promise->callError(QJSValueList{QString(QJsonDocument(error).toJson())}); - } - }); - - connect(reply, &QNetworkReply::errorOccurred, promise, [=](QNetworkReply::NetworkError error) - { - if (error == QNetworkReply::ConnectionRefusedError || error == QNetworkReply::HostNotFoundError || error == QNetworkReply::TimeoutError || error == QNetworkReply::UnknownNetworkError) - { - QJsonObject errorJson; - errorJson.insert("code", 0); - errorJson.insert("message", reply->errorString()); - promise->callError(QJSValueList{QString(QJsonDocument(errorJson).toJson())}); - } - }); - - connect( - reply, &QNetworkReply::uploadProgress, - promise, [promise](qint64 bytesSent, qint64 bytesTotal) - { - promise->callProgress(QJSValueList{QString::number(bytesSent).toInt(), QString::number(bytesTotal).toInt()}); - }); - - return promise; -} - -PocketBaseCollectionPromise *PocketRequest::get(QString url, QJSValue headers) -{ - QNetworkRequest request; - request.setUrl(QUrl(url)); - const QJsonObject& header = PocketUtility::jsvalueToJsonObject(headers); - request.setRawHeader("Accept", "application/json"); - request.setRawHeader("Content-Type", "application/json"); - request.setRawHeader("Authorization", header.value("Authorization").toString().toUtf8()); - - return makeRequest(request, HttpMethod::GET); -} - -PocketBaseCollectionPromise *PocketRequest::post(QString url, QJSValue data, QJSValue headers) -{ - const QJsonObject& obj = PocketUtility::jsvalueToJsonObject(data); - QNetworkRequest request= getRequest(QUrlQuery(), true, url, true, true); - const QJsonObject& header = PocketUtility::jsvalueToJsonObject(headers); - request.setRawHeader("Accept", "application/json"); - request.setRawHeader("Content-Type", "application/json"); - request.setRawHeader("Authorization", header.value("Authorization").toString().toUtf8()); - return makeRequest(request, HttpMethod::POST, QJsonDocument(obj).toJson()); -} - -PocketBaseCollectionPromise *PocketRequest::put(QString url, QJSValue data, QJSValue headers) -{ - const QJsonObject& obj = PocketUtility::jsvalueToJsonObject(data); - return makeRequest(getRequest(QUrlQuery(), true, url, true, true), HttpMethod::PUT, QJsonDocument(obj).toJson()); -} - -PocketBaseCollectionPromise *PocketRequest::postFile(QString url, QJSValue data, QJSValue files, QJSValue headers) -{ - QJsonObject obj = PocketUtility::jsvalueToJsonObject(data); - QJsonObject fobj = files.toVariant().toJsonObject(); - const QJsonObject& header = PocketUtility::jsvalueToJsonObject(headers); - - QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType); - - PocketUtility::jsonToFormData(multiPart, obj); - PocketUtility::jsonFilesToFormData(multiPart, fobj); - - QNetworkRequest request; - request.setUrl(QUrl(url)); - request.setRawHeader("Accept", "application/json"); - request.setRawHeader("Authorization", header.value("Authorization").toString().toUtf8()); - return makeRequest(&request, HttpMethod::POST, multiPart); -} - -PocketBaseCollectionPromise *PocketRequest::putFile(QString url, QJSValue data, QJSValue files, QJSValue headers) -{ - QJsonObject obj = PocketUtility::jsvalueToJsonObject(data); - QJsonObject fobj = files.toVariant().toJsonObject(); - const QJsonObject& header = PocketUtility::jsvalueToJsonObject(headers); - - QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType); - - PocketUtility::jsonToFormData(multiPart, obj); - PocketUtility::jsonFilesToFormData(multiPart, fobj); - - QNetworkRequest request; - request.setUrl(QUrl(url)); - request.setRawHeader("Accept", "application/json"); - request.setRawHeader("Authorization", header.value("Authorization").toString().toUtf8()); - return makeRequest(&request, HttpMethod::PATCH, multiPart); -} - -PocketBaseCollectionPromise *PocketRequest::removeFile(QString url, QJSValue files, QJSValue headers) -{ - QJsonObject fobj = files.toVariant().toJsonObject(); - QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType); - PocketUtility::jsonFilesToFormData(multiPart, fobj, true); - const QJsonObject& header = PocketUtility::jsvalueToJsonObject(headers); - - QNetworkRequest request; - request.setUrl(QUrl(url)); - request.setRawHeader("Authorization", header.value("Authorization").toString().toUtf8()); - request.setRawHeader("Accept", "application/json"); - - return makeRequest(&request, HttpMethod::PATCH, multiPart); -} - -PocketBaseCollectionPromise *PocketRequest::patch(QString url, QJSValue data, QJSValue headers) -{ - const QJsonObject& obj = PocketUtility::jsvalueToJsonObject(data); - QNetworkRequest request; - request.setUrl(QUrl(url)); - const QJsonObject& header = PocketUtility::jsvalueToJsonObject(headers); - request.setRawHeader("Accept", "application/json"); - request.setRawHeader("Content-Type", "application/json"); - request.setRawHeader("Authorization", header.value("Authorization").toString().toUtf8()); - return makeRequest(request, HttpMethod::PATCH, QJsonDocument(obj).toJson()); -} - -PocketBaseCollectionPromise *PocketRequest::del(QString url, QJSValue headers) -{ - QNetworkRequest request; - request.setUrl(QUrl(url)); - request.setRawHeader("Accept", "application/json"); - return makeRequest(request, HttpMethod::DELETE); -} - -QNetworkRequest PocketRequest::getRequest(QUrlQuery query, bool contentType, QString path, bool full, bool other) -{ - QNetworkRequest request; - QUrl url; - QString _url; - if (other) - { - _url = path; - url = QUrl(_url); - } - - else { - _url = PocketBaseSettings::getApiUrl(); - if (full == true) - url = QUrl(_url + path); - else - url = QUrl(_url + "/api" + route + path); - } - - url.setQuery(query); - request.setUrl(url); - if (contentType) - request.setRawHeader("Content-Type", "application/json"); - request.setRawHeader("Authorization", PocketBaseSettings::getToken().toUtf8()); - request.setRawHeader("Accept", "application/json"); - - return request; -} - -QUrlQuery PocketRequest::getRequestParams(QJsonObject obj) -{ - if (obj.isEmpty()) - return QUrlQuery(); - QUrlQuery params; - - QStringList keys = obj.keys(); - for (int i = 0; i < keys.size(); i++) - { - params.addQueryItem(keys[i], obj.value(keys[i]).toString()); - } - - return params; -} - -void PocketRequest::setRoute(const QString &newRoute) -{ - if (route == newRoute) - return; - route = newRoute; -} - -QString PocketRequest::getRoute() const -{ - return route; -} - -QByteArray PocketRequest::methodToString(HttpMethod method) -{ - switch (method) - { - case HttpMethod::GET: - return "GET"; - case HttpMethod::POST: - return "POST"; - case HttpMethod::PATCH: - return "PATCH"; - case HttpMethod::DELETE: - return "DELETE"; - case HttpMethod::PUT: - return "PUT"; - break; - } - return ""; -} - -PocketBaseCollectionPromise *PocketRequest::downloadFile(const QString &url, const QString &saveDir, QJSValue headers) -{ - PocketBaseCollectionPromise *promise = new PocketBaseCollectionPromise(this); - - const QJsonObject& header = PocketUtility::jsvalueToJsonObject(headers); - QNetworkRequest request; - request.setUrl(QUrl(url)); - request.setRawHeader("Authorization", header.value("Authorization").toString().toUtf8()); - - QNetworkReply *reply = manager->get(request); - - // Générer un nom de fichier basé sur l'URL - QString fileName = QFileInfo(QUrl(url).path()).fileName(); - if (fileName.isEmpty()) { - fileName = "downloaded_file"; - } - - // Assurer un nom de fichier unique - QString filePath = QDir(saveDir).filePath(fileName); - int counter = 1; - while (QFile::exists(filePath)) { - QString newName = QString("%1_%2").arg(QFileInfo(fileName).baseName()).arg(counter); - if (QFileInfo(fileName).completeSuffix().isEmpty()) { - filePath = QDir(saveDir).filePath(newName); - } else { - filePath = QDir(saveDir).filePath(newName + "." + QFileInfo(fileName).completeSuffix()); - } - counter++; - } - - QFile *file = new QFile(filePath); - if (!file->open(QIODevice::WriteOnly)) { - delete file; - QJsonObject error; - error.insert("code", 0); - error.insert("message", "Impossible d'ouvrir le fichier pour l'écriture"); - promise->callError(QJSValueList{QString(QJsonDocument(error).toJson())}); - return promise; - } - - connect(reply, &QNetworkReply::readyRead, [=]() { - if (file->isOpen()) { - file->write(reply->readAll()); - } - }); - - connect(reply, &QNetworkReply::finished, promise, [=]() { - if (file->isOpen()) { - file->close(); - } - - if (reply->error() == QNetworkReply::NoError) { - promise->callThen(QJSValueList{filePath}); - } else { - QJsonObject error; - error.insert("code", reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt()); - error.insert("message", reply->errorString()); - promise->callError(QJSValueList{QString(QJsonDocument(error).toJson())}); - } - - file->deleteLater(); - reply->deleteLater(); - }); - - connect(reply, &QNetworkReply::downloadProgress, promise, [promise](qint64 bytesReceived, qint64 bytesTotal) { - promise->callProgress(QJSValueList{QString::number(bytesReceived).toInt(), QString::number(bytesTotal).toInt()}); - }); - - return promise; -} - +#include "PocketRequest.h" +#include "PocketUtility.h" +#include "qjsondocument.h" +#include "qurlquery.h" +#include "pocketnetworkmanager.h" +#include "PocketBaseSettings.h" +#include +#include +#include +#include +#include + +PocketRequest::PocketRequest(QObject *parent) + : QObject{parent} +{ + manager = PocketNetworkManager::instance2(); +} + +PocketBaseCollectionPromise *PocketRequest::getOne(QString id, QJsonObject options) +{ + return makeRequest(getRequest(getRequestParams(options), false, "/" + id), HttpMethod::GET); +} + +PocketBaseCollectionPromise *PocketRequest::getList(int page, int perPage, QJsonObject options) +{ + options.insert("page", QString::number(page)); + options.insert("perPage", QString::number(perPage)); + QNetworkRequest request = getRequest(getRequestParams(options), false); + + return makeRequest(request); +} + +PocketBaseCollectionPromise *PocketRequest::create(QJSValue data, QJsonObject options) +{ + const QJsonObject &obj = PocketUtility::jsvalueToJsonObject(data); + return makeRequest(getRequest(getRequestParams(options), true), HttpMethod::POST, QJsonDocument(obj).toJson()); +} + +PocketBaseCollectionPromise *PocketRequest::create(QJsonObject data, QJsonObject options) +{ + return makeRequest(getRequest(getRequestParams(options), true), HttpMethod::POST, QJsonDocument(data).toJson()); +} + +PocketBaseCollectionPromise *PocketRequest::createWithFile(QJSValue data, QJSValue files, QJsonObject options) +{ + QJsonObject obj = PocketUtility::jsvalueToJsonObject(data); + QJsonObject fobj = files.toVariant().toJsonObject(); + + QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType); + + PocketUtility::jsonToFormData(multiPart, obj); + PocketUtility::jsonFilesToFormData(multiPart, fobj); + QNetworkRequest request = getRequest(getRequestParams(options), false); + return makeRequest(&request, HttpMethod::POST, multiPart); +} + +PocketBaseCollectionPromise *PocketRequest::update(QString id, QJSValue data, QJsonObject options) +{ + const QJsonObject &obj = PocketUtility::jsvalueToJsonObject(data); + return makeRequest(getRequest(getRequestParams(options), true, "/" + id), HttpMethod::PATCH, QJsonDocument(obj).toJson()); +} + +PocketBaseCollectionPromise *PocketRequest::update(QString id, QJsonObject data, QJsonObject options) +{ + return makeRequest(getRequest(getRequestParams(options), true, "/" + id), HttpMethod::PATCH, QJsonDocument(data).toJson()); +} + +PocketBaseCollectionPromise *PocketRequest::updateWithFile(QString id, QJSValue data, QJSValue files, QJsonObject options) +{ + QJsonObject obj = PocketUtility::jsvalueToJsonObject(data); + QJsonObject fobj = files.toVariant().toJsonObject(); + + QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType); + + for (QString key : obj.keys()) + { + QHttpPart jsonPart; + jsonPart.setHeader(QNetworkRequest::ContentDispositionHeader, + QVariant("form-data; name=\"" + key + "\"")); + + QJsonValue value = obj.value(key); + if (value.isObject() || value.isArray()) + { + jsonPart.setBody(QJsonDocument(value.toObject()).toJson()); + } + else + { + jsonPart.setBody(value.toString().toUtf8()); + } + + multiPart->append(jsonPart); + } + + QStringList keys = fobj.keys(); + for (int i = 0; i < keys.size(); i++) + { + QJsonArray filePaths = fobj[keys[i]].toArray(); + + for (const QJsonValue &jsonfilePath : filePaths) + { + QString filePath = jsonfilePath.toString(); + QFile *file = new QFile(filePath); + + if (!file->open(QIODevice::ReadOnly)) + { + qWarning() << "Impossible d'ouvrir le fichier:" << file->errorString(); + delete file; + continue; + } + + QMimeDatabase mimeDb; + QMimeType mimeType = mimeDb.mimeTypeForFile(filePath); + + QHttpPart filePart; + filePart.setHeader(QNetworkRequest::ContentTypeHeader, + QVariant(mimeType.name())); + filePart.setHeader(QNetworkRequest::ContentDispositionHeader, + QVariant("form-data; name=\"" + keys[i] + + "\"; filename=\"" + QFileInfo(filePath).fileName() + "\"")); + + filePart.setBodyDevice(file); + file->setParent(multiPart); + + multiPart->append(filePart); + } + } + + QNetworkRequest request = getRequest(getRequestParams(options), false, "/" + id); + + return makeRequest(&request, HttpMethod::PATCH, multiPart); +} + +PocketBaseCollectionPromise *PocketRequest::deleteFile(QString id, QJSValue files, QJsonObject options) +{ + QJsonObject fobj = files.toVariant().toJsonObject(); + QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType); + PocketUtility::jsonFilesToFormData(multiPart, fobj); + + QNetworkRequest request = getRequest(getRequestParams(options), false, "/" + id); + return makeRequest(&request, HttpMethod::PATCH, multiPart); +} + +PocketBaseCollectionPromise *PocketRequest::deleteOne(QString id, QJsonObject options) +{ + return makeRequest(getRequest(getRequestParams(options), false, "/" + id), HttpMethod::DELETE); +} + +PocketBaseCollectionPromise *PocketRequest::authWithPassword(QString identity, QString password) +{ + QJsonObject obj; + obj.insert("identity", identity); + obj.insert("password", password); + return makeRequest(getRequest(getRequestParams({}), true), HttpMethod::POST, QJsonDocument(obj).toJson(QJsonDocument::Compact)); +} + +PocketBaseCollectionPromise *PocketRequest::authRefresh() +{ + return makeRequest(getRequest(getRequestParams({}), true), HttpMethod::POST); +} + +PocketBaseCollectionPromise *PocketRequest::HttpGet(QString path, QJSValue options, bool other) +{ + const QJsonObject &obj = PocketUtility::jsvalueToJsonObject(options); + return makeRequest(getRequest(getRequestParams(obj), false, path, true, other), HttpMethod::GET); +} + +PocketBaseCollectionPromise *PocketRequest::HttpPostFile(QString path, QJSValue data, QJSValue files, QJSValue options, bool other) +{ + const QJsonObject &op = PocketUtility::jsvalueToJsonObject(options); + QJsonObject obj = PocketUtility::jsvalueToJsonObject(data); + QJsonObject fobj = files.toVariant().toJsonObject(); + + QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType); + + PocketUtility::jsonToFormData(multiPart, obj); + PocketUtility::jsonFilesToFormData(multiPart, fobj); + QNetworkRequest request = getRequest(getRequestParams(op), true, path, true, other); + return makeRequest(&request, HttpMethod::POST, multiPart); +} + +PocketBaseCollectionPromise *PocketRequest::HttpPost(QString path, QJSValue data, QJSValue options, bool other) +{ + const QJsonObject &obj = PocketUtility::jsvalueToJsonObject(options); + const QJsonObject &datas = PocketUtility::jsvalueToJsonObject(data); + return makeRequest(getRequest(getRequestParams(obj), true, path, true, other), HttpMethod::POST, QJsonDocument(datas).toJson()); +} + +PocketBaseCollectionPromise *PocketRequest::HttpPost(QString path, QJsonObject datas, QJsonObject obj) +{ + return makeRequest(getRequest(getRequestParams(obj), true, path, true), HttpMethod::POST, QJsonDocument(datas).toJson()); +} + +PocketBaseCollectionPromise *PocketRequest::HttpPut(QString path, QJSValue data, QJSValue options) +{ + const QJsonObject &obj = PocketUtility::jsvalueToJsonObject(options); + QJsonObject datas = data.toVariant().toJsonObject(); + return makeRequest(getRequest(QUrlQuery(), true, path, true), HttpMethod::PUT, QJsonDocument(datas).toJson()); +} + +PocketBaseCollectionPromise *PocketRequest::HttpPut(QString path, QJsonObject datas) +{ + return makeRequest(getRequest(QUrlQuery(), true, path, true), HttpMethod::PUT, QJsonDocument(datas).toJson()); +} + +PocketBaseCollectionPromise *PocketRequest::HttpPatch(QString path, QJSValue data, QJSValue options) +{ + const QJsonObject &obj = PocketUtility::jsvalueToJsonObject(options); + const QJsonObject &datas = PocketUtility::jsvalueToJsonObject(data); + return makeRequest(getRequest(getRequestParams(obj), true, path, true), HttpMethod::PATCH, QJsonDocument(datas).toJson()); +} + +PocketBaseCollectionPromise *PocketRequest::HttpDelete(QString path, QJSValue options) +{ + const QJsonObject &obj = PocketUtility::jsvalueToJsonObject(options); + return makeRequest(getRequest(getRequestParams(obj), false, path, true, true), HttpMethod::DELETE); +} + +PocketBaseCollectionPromise *PocketRequest::makeRequest(QNetworkRequest request, HttpMethod method) +{ + PocketBaseCollectionPromise *promise = new PocketBaseCollectionPromise(this); + + QNetworkReply *reply; + + reply = manager->sendCustomRequest(request, methodToString(method)); + + connect(reply, &QNetworkReply::finished, promise, [=]() + { + if (reply->error() == QNetworkReply::NoError) { + promise->callThen(QJSValueList{QString(reply->readAll())}); + }else if (reply->error() != QNetworkReply::ConnectionRefusedError && reply->error() != QNetworkReply::HostNotFoundError && reply->error() != QNetworkReply::TimeoutError && reply->error() != QNetworkReply::UnknownNetworkError) { + QJsonObject error; + error.insert("code", reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt()); + error.insert("message", reply->errorString()); + error.insert("data", QString(reply->readAll())); + promise->callError(QJSValueList{QString(QJsonDocument(error).toJson())}); + } }); + + connect(reply, &QNetworkReply::errorOccurred, promise, [=](QNetworkReply::NetworkError error) + { + if (error == QNetworkReply::ConnectionRefusedError || error == QNetworkReply::HostNotFoundError || error == QNetworkReply::TimeoutError || error == QNetworkReply::UnknownNetworkError) { + QJsonObject errorJson; + errorJson.insert("code", 0); + errorJson.insert("message", reply->errorString()); + promise->callError(QJSValueList{QString(QJsonDocument(errorJson).toJson())}); + } }); + + return promise; +} + +PocketBaseCollectionPromise *PocketRequest::makeRequest(QNetworkRequest request, HttpMethod method, QByteArray data) +{ + PocketBaseCollectionPromise *promise = new PocketBaseCollectionPromise(this); + + QNetworkReply *reply; + + reply = manager->sendCustomRequest(request, methodToString(method), data); + connect(reply, &QNetworkReply::finished, promise, [reply, promise]() + { + if (reply->error() == QNetworkReply::NoError) { + promise->callThen(QJSValueList{QString(reply->readAll())}); + }else if (reply->error() != QNetworkReply::ConnectionRefusedError && reply->error() != QNetworkReply::HostNotFoundError && reply->error() != QNetworkReply::TimeoutError && reply->error() != QNetworkReply::UnknownNetworkError) { + QJsonObject error; + QString data = reply->readAll(); + error.insert("code", reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt()); + error.insert("message", reply->errorString() + "," + data); + error.insert("data", data); + promise->callError(QJSValueList{QString(QJsonDocument(error).toJson())}); + } }); + + connect(reply, &QNetworkReply::errorOccurred, promise, [=](QNetworkReply::NetworkError error) + { + if (error == QNetworkReply::ConnectionRefusedError || error == QNetworkReply::HostNotFoundError || error == QNetworkReply::TimeoutError || error == QNetworkReply::UnknownNetworkError) { + QJsonObject errorJson; + errorJson.insert("code", reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt()); + errorJson.insert("message", reply->errorString() + reply->readAll()); + promise->callError(QJSValueList{QString(QJsonDocument(errorJson).toJson())}); + } }); + + return promise; +} + +PocketBaseCollectionPromise *PocketRequest::makeRequest(QNetworkRequest *request, HttpMethod method, QHttpMultiPart *multipart) +{ + PocketBaseCollectionPromise *promise = new PocketBaseCollectionPromise(this); + + QNetworkReply *reply; + + reply = manager->sendCustomRequest(*request, methodToString(method), multipart); + + connect(reply, &QNetworkReply::finished, promise, [=]() + { + if (reply->error() == QNetworkReply::NoError) { + promise->callThen(QJSValueList{QString(reply->readAll())}); + } else if (reply->error() != QNetworkReply::ConnectionRefusedError && reply->error() != QNetworkReply::HostNotFoundError && reply->error() != QNetworkReply::TimeoutError && reply->error() != QNetworkReply::UnknownNetworkError) { + QJsonObject error; + error.insert("code", reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt()); + error.insert("message", reply->errorString()); + error.insert("data", QString(reply->readAll())); + promise->callError(QJSValueList{QString(QJsonDocument(error).toJson())}); + } }); + + connect(reply, &QNetworkReply::errorOccurred, promise, [=](QNetworkReply::NetworkError error) + { + if (error == QNetworkReply::ConnectionRefusedError || error == QNetworkReply::HostNotFoundError || error == QNetworkReply::TimeoutError || error == QNetworkReply::UnknownNetworkError) + { + QJsonObject errorJson; + errorJson.insert("code", 0); + errorJson.insert("message", reply->errorString()); + promise->callError(QJSValueList{QString(QJsonDocument(errorJson).toJson())}); + } }); + + connect( + reply, &QNetworkReply::uploadProgress, + promise, [promise](qint64 bytesSent, qint64 bytesTotal) + { promise->callProgress(QJSValueList{QString::number(bytesSent).toInt(), QString::number(bytesTotal).toInt()}); }); + + return promise; +} + +PocketBaseCollectionPromise *PocketRequest::get(QString url, QJSValue headers) +{ + QNetworkRequest request; + request.setUrl(QUrl(url)); + const QJsonObject &header = PocketUtility::jsvalueToJsonObject(headers); + request.setRawHeader("Accept", "application/json"); + request.setRawHeader("Content-Type", "application/json"); + request.setRawHeader("Authorization", header.value("Authorization").toString().toUtf8()); + + return makeRequest(request, HttpMethod::GET); +} + +PocketBaseCollectionPromise *PocketRequest::post(QString url, QJSValue data, QJSValue headers) +{ + const QJsonObject &obj = PocketUtility::jsvalueToJsonObject(data); + QNetworkRequest request = getRequest(QUrlQuery(), true, url, true, true); + const QJsonObject &header = PocketUtility::jsvalueToJsonObject(headers); + request.setRawHeader("Accept", "application/json"); + request.setRawHeader("Content-Type", "application/json"); + request.setRawHeader("Authorization", header.value("Authorization").toString().toUtf8()); + return makeRequest(request, HttpMethod::POST, QJsonDocument(obj).toJson()); +} + +PocketBaseCollectionPromise *PocketRequest::put(QString url, QJSValue data, QJSValue headers) +{ + const QJsonObject &obj = PocketUtility::jsvalueToJsonObject(data); + return makeRequest(getRequest(QUrlQuery(), true, url, true, true), HttpMethod::PUT, QJsonDocument(obj).toJson()); +} + +PocketBaseCollectionPromise *PocketRequest::postFile(QString url, QJSValue data, QJSValue files, QJSValue headers) +{ + QJsonObject obj = PocketUtility::jsvalueToJsonObject(data); + QJsonObject fobj = files.toVariant().toJsonObject(); + const QJsonObject &header = PocketUtility::jsvalueToJsonObject(headers); + + QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType); + + PocketUtility::jsonToFormData(multiPart, obj); + PocketUtility::jsonFilesToFormData(multiPart, fobj); + + QNetworkRequest request; + request.setUrl(QUrl(url)); + request.setRawHeader("Accept", "application/json"); + request.setRawHeader("Authorization", header.value("Authorization").toString().toUtf8()); + return makeRequest(&request, HttpMethod::POST, multiPart); +} + +PocketBaseCollectionPromise *PocketRequest::putFile(QString url, QJSValue data, QJSValue files, QJSValue headers) +{ + QJsonObject obj = PocketUtility::jsvalueToJsonObject(data); + QJsonObject fobj = files.toVariant().toJsonObject(); + const QJsonObject &header = PocketUtility::jsvalueToJsonObject(headers); + + QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType); + + PocketUtility::jsonToFormData(multiPart, obj); + PocketUtility::jsonFilesToFormData(multiPart, fobj); + + QNetworkRequest request; + request.setUrl(QUrl(url)); + request.setRawHeader("Accept", "application/json"); + request.setRawHeader("Authorization", header.value("Authorization").toString().toUtf8()); + return makeRequest(&request, HttpMethod::PATCH, multiPart); +} + +PocketBaseCollectionPromise *PocketRequest::removeFile(QString url, QJSValue files, QJSValue headers) +{ + QJsonObject fobj = files.toVariant().toJsonObject(); + QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType); + PocketUtility::jsonFilesToFormData(multiPart, fobj, true); + const QJsonObject &header = PocketUtility::jsvalueToJsonObject(headers); + + QNetworkRequest request; + request.setUrl(QUrl(url)); + request.setRawHeader("Authorization", header.value("Authorization").toString().toUtf8()); + request.setRawHeader("Accept", "application/json"); + + return makeRequest(&request, HttpMethod::PATCH, multiPart); +} + +PocketBaseCollectionPromise *PocketRequest::patch(QString url, QJSValue data, QJSValue headers) +{ + const QJsonObject &obj = PocketUtility::jsvalueToJsonObject(data); + QNetworkRequest request; + request.setUrl(QUrl(url)); + const QJsonObject &header = PocketUtility::jsvalueToJsonObject(headers); + request.setRawHeader("Accept", "application/json"); + request.setRawHeader("Content-Type", "application/json"); + request.setRawHeader("Authorization", header.value("Authorization").toString().toUtf8()); + return makeRequest(request, HttpMethod::PATCH, QJsonDocument(obj).toJson()); +} + +PocketBaseCollectionPromise *PocketRequest::del(QString url, QJSValue headers) +{ + QNetworkRequest request; + request.setUrl(QUrl(url)); + request.setRawHeader("Accept", "application/json"); + return makeRequest(request, HttpMethod::DELETE); +} + +QNetworkRequest PocketRequest::getRequest(QUrlQuery query, bool contentType, QString path, bool full, bool other) +{ + QNetworkRequest request; + QUrl url; + QString _url; + if (other) + { + _url = path; + url = QUrl(_url); + } + + else + { + _url = PocketBaseSettings::getApiUrl(); + if (full == true) + url = QUrl(_url + path); + else + url = QUrl(_url + "/api" + route + path); + } + + url.setQuery(query); + request.setUrl(url); + if (contentType) + request.setRawHeader("Content-Type", "application/json"); + request.setRawHeader("Authorization", PocketBaseSettings::getToken().toUtf8()); + request.setRawHeader("Accept", "application/json"); + + return request; +} + +QUrlQuery PocketRequest::getRequestParams(QJsonObject obj) +{ + if (obj.isEmpty()) + return QUrlQuery(); + QUrlQuery params; + + QStringList keys = obj.keys(); + for (int i = 0; i < keys.size(); i++) + { + params.addQueryItem(keys[i], obj.value(keys[i]).toString()); + } + + return params; +} + +void PocketRequest::setRoute(const QString &newRoute) +{ + if (route == newRoute) + return; + route = newRoute; +} + +QString PocketRequest::getRoute() const +{ + return route; +} + +QByteArray PocketRequest::methodToString(HttpMethod method) +{ + switch (method) + { + case HttpMethod::GET: + return "GET"; + case HttpMethod::POST: + return "POST"; + case HttpMethod::PATCH: + return "PATCH"; + case HttpMethod::DELETE: + return "DELETE"; + case HttpMethod::PUT: + return "PUT"; + break; + } + return ""; +} + +PocketBaseCollectionPromise *PocketRequest::downloadFile(const QString &url, const QString &saveDir, QJSValue headers) +{ + PocketBaseCollectionPromise *promise = new PocketBaseCollectionPromise(this); + + const QJsonObject &header = PocketUtility::jsvalueToJsonObject(headers); + QNetworkRequest request; + request.setUrl(QUrl(url)); + request.setRawHeader("Authorization", header.value("Authorization").toString().toUtf8()); + + QNetworkReply *reply = manager->get(request); + + QString fileName = QFileInfo(QUrl(url).path()).fileName(); + if (fileName.isEmpty()) + { + fileName = "downloaded_file"; + } + + QString filePath = QDir(saveDir).filePath(fileName); + int counter = 1; + while (QFile::exists(filePath)) + { + QString newName = QString("%1_%2").arg(QFileInfo(fileName).baseName()).arg(counter); + if (QFileInfo(fileName).completeSuffix().isEmpty()) + { + filePath = QDir(saveDir).filePath(newName); + } + else + { + filePath = QDir(saveDir).filePath(newName + "." + QFileInfo(fileName).completeSuffix()); + } + counter++; + } + + QFile *file = new QFile(filePath); + if (!file->open(QIODevice::WriteOnly)) + { + delete file; + QJsonObject error; + error.insert("code", 0); + error.insert("message", "Impossible d'ouvrir le fichier pour l'écriture"); + promise->callError(QJSValueList{QString(QJsonDocument(error).toJson())}); + return promise; + } + + connect(reply, &QNetworkReply::readyRead, [=]() + { + if (file->isOpen()) { + file->write(reply->readAll()); + } }); + + connect(reply, &QNetworkReply::finished, promise, [=]() + { + if (file->isOpen()) { + file->close(); + } + + if (reply->error() == QNetworkReply::NoError) { + promise->callThen(QJSValueList{filePath}); + } else { + QJsonObject error; + error.insert("code", reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt()); + error.insert("message", reply->errorString()); + promise->callError(QJSValueList{QString(QJsonDocument(error).toJson())}); + } + + file->deleteLater(); + reply->deleteLater(); }); + + connect(reply, &QNetworkReply::downloadProgress, promise, [promise](qint64 bytesReceived, qint64 bytesTotal) + { promise->callProgress(QJSValueList{QString::number(bytesReceived).toInt(), QString::number(bytesTotal).toInt()}); }); + + return promise; +} From 34eb6ab9ff05f532a25ca8a027f88d733eecd67d Mon Sep 17 00:00:00 2001 From: 0xEnokas Date: Mon, 30 Jun 2025 14:33:57 +0200 Subject: [PATCH 2/2] Update QML imports for Qt 6.10 --- CMakeLists.txt | 2 +- Collection.qml | 4 +- README.md | 4 +- src/CollectionSubscriber.cpp | 6 +-- src/PocketBaseClient.cpp | 18 +++---- src/PocketBaseClient.h | 30 ++++++------ src/PocketBaseCollection.h | 34 +++++++------- src/PocketBaseCollectionPromise.h | 16 +++---- src/PocketBaseServer.cpp | 59 +++++++++++------------ src/PocketBaseServer.h | 37 ++++++++------- src/PocketBaseSettings.h | 4 +- src/PocketRequest.cpp | 14 +++--- src/PocketRequest.h | 78 +++++++++++++++---------------- src/PocketUtility.cpp | 78 +++++++++++++++---------------- src/PocketUtility.h | 2 +- 15 files changed, 195 insertions(+), 191 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d1c89e2..0649b09 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.14) project(PocketBase LANGUAGES CXX) set(CMAKE_AUTOMOC ON) -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(Qt6 COMPONENTS Network Core Quick REQUIRED) diff --git a/Collection.qml b/Collection.qml index 54f7470..397b17b 100755 --- a/Collection.qml +++ b/Collection.qml @@ -1,5 +1,5 @@ -import QtQuick -import PocketBase +import QtQuick 6.10 +import PocketBase 1.0 BaseCollection { id: collection diff --git a/README.md b/README.md index 640bfde..2629aa3 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ ![](https://camo.githubusercontent.com/45afc34faad79c9a4591c3ec02a3e98ec3e99b0e1c8a6fbbf11b6ea8f402fdf6/68747470733a2f2f692e696d6775722e636f6d2f3571696d6e6d352e706e67) # QtPocketBase -PocketBase Client for Qt/Qml +PocketBase client library for QML and C++. + +This version targets Qt 6.10 and requires a C++20 capable compiler. diff --git a/src/CollectionSubscriber.cpp b/src/CollectionSubscriber.cpp index 313ae6c..9cbee58 100755 --- a/src/CollectionSubscriber.cpp +++ b/src/CollectionSubscriber.cpp @@ -76,7 +76,7 @@ void CollectionSubscriber::connect() // manager->setTransferTimeout(2000); QNetworkReply *reply = manager->get(subscriptionRequest); - QObject::connect(reply, &QNetworkReply::readyRead, this, [=]() { + QObject::connect(reply, &QNetworkReply::readyRead, this, [reply, this]() { QString data = reply->readAll(); // If we see "clientId", parse out the ID if possible @@ -158,7 +158,7 @@ void CollectionSubscriber::connect() // qDebug() << "Error: " << data; }); - QObject::connect(reply, &QNetworkReply::finished, this, [=]() { + QObject::connect(reply, &QNetworkReply::finished, this, [reply, this]() { reply->deleteLater(); connect(); }); @@ -188,7 +188,7 @@ void CollectionSubscriber::sub(QString topic, bool all) QJsonDocument doc(json); // qDebug () << "Sending subscription request" << doc.toJson(); QNetworkReply *subReply = manager->post(request, doc.toJson()); - QObject::connect(subReply, &QNetworkReply::finished, this, [=]() + QObject::connect(subReply, &QNetworkReply::finished, this, [subReply, this]() { int statusCode = subReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); QString data = subReply->readAll(); diff --git a/src/PocketBaseClient.cpp b/src/PocketBaseClient.cpp index ae0e790..140d20f 100644 --- a/src/PocketBaseClient.cpp +++ b/src/PocketBaseClient.cpp @@ -12,9 +12,9 @@ PocketBaseClient::PocketBaseClient(QObject *parent) QObject::connect(subscriber, &CollectionSubscriber::connectedChanged, this, [this]() { setConnected(subscriber->connected()); }); - QTimer *timer = new QTimer(this); - QObject::connect(timer, &QTimer::timeout, this, [=]() - { isHealthy(); }); + QTimer *timer = new QTimer(this); + QObject::connect(timer, &QTimer::timeout, this, [this]() + { isHealthy(); }); timer->start(800); isHealthy(); @@ -120,8 +120,8 @@ PocketBaseCollectionPromise *PocketBaseClient::authAdminWithPassword(QString ide { request.setRoute("/admins/auth-with-password"); PocketBaseCollectionPromise *promise = request.authWithPassword(identity, password); - QObject::connect(promise, &PocketBaseCollectionPromise::onThen, this, [=](QJSValueList response) - { + QObject::connect(promise, &PocketBaseCollectionPromise::onThen, this, [this](QJSValueList response) + { QJsonObject data = QJsonDocument::fromJson(QByteArray::fromStdString(response.toList().at(0).toString().toStdString())).object(); setAuthToken(data.value("token").toString()); }); return promise; @@ -131,8 +131,8 @@ PocketBaseCollectionPromise *PocketBaseClient::authWithCollection(QString collec { request.setRoute("/collections/" + collectionName + "/auth-with-password"); PocketBaseCollectionPromise *promise = request.authWithPassword(identity, password); - QObject::connect(promise, &PocketBaseCollectionPromise::onThen, this, [=](QJSValueList response) - { + QObject::connect(promise, &PocketBaseCollectionPromise::onThen, this, [this](QJSValueList response) + { QJsonObject data = QJsonDocument::fromJson(QByteArray::fromStdString(response.toList().at(0).toString().toStdString())).object(); setAuthToken(data.value("token").toString()); }); return promise; @@ -142,8 +142,8 @@ PocketBaseCollectionPromise *PocketBaseClient::authRefreshCollection(QString col { request.setRoute("/collections/" + collectionName + "/auth-refresh"); PocketBaseCollectionPromise *promise = request.authRefresh(); - QObject::connect(promise, &PocketBaseCollectionPromise::onThen, this, [=](QJSValueList response) - { + QObject::connect(promise, &PocketBaseCollectionPromise::onThen, this, [this](QJSValueList response) + { QJsonObject data = QJsonDocument::fromJson(QByteArray::fromStdString(response.toList().at(0).toString().toStdString())).object(); setAuthToken(data.value("token").toString()); }); return promise; diff --git a/src/PocketBaseClient.h b/src/PocketBaseClient.h index d6964e7..38ed098 100755 --- a/src/PocketBaseClient.h +++ b/src/PocketBaseClient.h @@ -22,21 +22,21 @@ class PocketBaseClient : public QObject explicit PocketBaseClient(QObject *parent = nullptr); Q_INVOKABLE void addCollection(PocketBaseCollection *collection); - Q_INVOKABLE PocketBaseCollectionPromise *updateCollection(QString collectionId, PocketBaseCollection *updateCollection); - Q_INVOKABLE PocketBaseCollectionPromise *createCollection(QJSValue data); - Q_INVOKABLE PocketBaseCollectionPromise *deleteCollection(QString collectionId); - Q_INVOKABLE PocketBaseCollectionPromise *getCollection(QString collectionId); - Q_INVOKABLE PocketBaseCollectionPromise *importCollection(QJSValue json); - Q_INVOKABLE PocketBaseCollectionPromise *update(QString collectionName, QString id, QJSValue data, QJSValue options = {}); - Q_INVOKABLE PocketBaseCollectionPromise *getCollections(); - Q_INVOKABLE PocketBaseCollectionPromise *isHealthy(); - - Q_INVOKABLE PocketBaseCollection *collection(const QString &collectionName); - - Q_INVOKABLE PocketBaseCollectionPromise *authAdminWithPassword(QString identity, QString password); - Q_INVOKABLE PocketBaseCollectionPromise *authWithCollection(QString collectionName, QString identity, QString password); - Q_INVOKABLE PocketBaseCollectionPromise *authRefreshCollection(QString collectionName); - Q_INVOKABLE PocketBaseCollectionPromise *createNewAdmin(QString email, QString identity, QString password); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *updateCollection(QString collectionId, PocketBaseCollection *updateCollection); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *createCollection(QJSValue data); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *deleteCollection(QString collectionId); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *getCollection(QString collectionId); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *importCollection(QJSValue json); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *update(QString collectionName, QString id, QJSValue data, QJSValue options = {}); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *getCollections(); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *isHealthy(); + + [[nodiscard]] Q_INVOKABLE PocketBaseCollection *collection(const QString &collectionName); + + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *authAdminWithPassword(QString identity, QString password); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *authWithCollection(QString collectionName, QString identity, QString password); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *authRefreshCollection(QString collectionName); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *createNewAdmin(QString email, QString identity, QString password); // Q_INVOKABLE QString getFileUrl(QString fileId); diff --git a/src/PocketBaseCollection.h b/src/PocketBaseCollection.h index 4904b75..f85b49f 100755 --- a/src/PocketBaseCollection.h +++ b/src/PocketBaseCollection.h @@ -26,24 +26,24 @@ class PocketBaseCollection : public QObject public: explicit PocketBaseCollection(QObject *parent = nullptr); - Q_INVOKABLE PocketBaseCollectionPromise *getOne(QString id, QJSValue options = {}); - Q_INVOKABLE PocketBaseCollectionPromise *getList(int page = 1, int perPage = 15, QJSValue options = {}); - Q_INVOKABLE PocketBaseCollectionPromise *create(QJSValue data); - Q_INVOKABLE PocketBaseCollectionPromise *create(QString data); - Q_INVOKABLE PocketBaseCollectionPromise *createWithFile(QJSValue data, - QJSValue files); - Q_INVOKABLE PocketBaseCollectionPromise *update(QString id, QJSValue data, QJSValue options = {}); - Q_INVOKABLE PocketBaseCollectionPromise *updateWithFile(QString id, QJSValue data, - QJSValue files); - Q_INVOKABLE PocketBaseCollectionPromise *deleteFile(QString id, QJSValue files); - Q_INVOKABLE PocketBaseCollectionPromise *deleteOne(QString id); - - Q_INVOKABLE PocketBaseCollectionPromise *getViewList(QString view, int page = 1, int perPage = 15, QJSValue options = {}); - Q_INVOKABLE PocketBaseCollectionPromise *getViewOne(QString view, QString id, QJSValue options = {}); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *getOne(QString id, QJSValue options = {}); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *getList(int page = 1, int perPage = 15, QJSValue options = {}); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *create(QJSValue data); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *create(QString data); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *createWithFile(QJSValue data, + QJSValue files); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *update(QString id, QJSValue data, QJSValue options = {}); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *updateWithFile(QString id, QJSValue data, + QJSValue files); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *deleteFile(QString id, QJSValue files); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *deleteOne(QString id); + + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *getViewList(QString view, int page = 1, int perPage = 15, QJSValue options = {}); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *getViewOne(QString view, QString id, QJSValue options = {}); Q_INVOKABLE QString getFileUrl(QString fileId, QString fileName); - Q_INVOKABLE PocketBaseCollectionPromise *send(QString path, QString method, QJSValue data = {}, QJSValue options = {}); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *send(QString path, QString method, QJSValue data = {}, QJSValue options = {}); QJsonObject getOptions(QJSValue options = {}); Q_INVOKABLE void prepare(); @@ -57,9 +57,9 @@ class PocketBaseCollection : public QObject QString name() const; void setName(const QString &newName); - PocketRequest *getRequest() const; + [[nodiscard]] PocketRequest *getRequest() const; - QJsonObject toJson(); + QJsonObject toJson(); private: QString m_name; diff --git a/src/PocketBaseCollectionPromise.h b/src/PocketBaseCollectionPromise.h index 4324ab4..a90f684 100755 --- a/src/PocketBaseCollectionPromise.h +++ b/src/PocketBaseCollectionPromise.h @@ -11,16 +11,16 @@ class PocketBaseCollectionPromise : public QObject public: explicit PocketBaseCollectionPromise(QObject *parent = nullptr); - Q_INVOKABLE PocketBaseCollectionPromise * then(QJSValue callback); - Q_INVOKABLE PocketBaseCollectionPromise * error(QJSValue callback); - Q_INVOKABLE PocketBaseCollectionPromise * progress(QJSValue callback); - Q_INVOKABLE PocketBaseCollectionPromise * finally(QJSValue callback); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise * then(QJSValue callback); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise * error(QJSValue callback); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise * progress(QJSValue callback); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise * finally(QJSValue callback); - QJSValue getThen() const; - QJSValue getError() const; - QJSValue getProgress() const; - QJSValue getFinally() const; + [[nodiscard]] QJSValue getThen() const; + [[nodiscard]] QJSValue getError() const; + [[nodiscard]] QJSValue getProgress() const; + [[nodiscard]] QJSValue getFinally() const; void callThen(QJSValueList args); void callError(QJSValueList args); diff --git a/src/PocketBaseServer.cpp b/src/PocketBaseServer.cpp index 24a217a..206ed40 100644 --- a/src/PocketBaseServer.cpp +++ b/src/PocketBaseServer.cpp @@ -2,33 +2,34 @@ #include "qregularexpression.h" #include #include -#include +#include +#include PocketBaseServer::PocketBaseServer(QObject *parent) : QObject{parent} { #if defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(Q_OS_LINUX) - process = new QProcess(this); - - connect(process, &QProcess::started, this, [this](){ - setRunning(true); - }); - - connect(process, QOverload::of(&QProcess::finished), this, [this](int exitCode, QProcess::ExitStatus exitStatus){ - setRunning(false); - setReady(false); - }); - - connect(process, &QProcess::errorOccurred, this, [](QProcess::ProcessError error){ - qWarning() << "\033[31m" << "Error occurred:" << error << "\033[39m"; - }); - - connect(process, &QProcess::readyReadStandardOutput, this, [this](){ - QByteArray data = process->readAllStandardOutput(); - if (data.contains("Server started")) setReady(true); - qInfo() << "\033[33m" << data.toStdString().c_str() << "\033[39m"; - }); + m_process = std::make_unique(this); + + connect(m_process.get(), &QProcess::started, this, [this](){ + setRunning(true); + }); + + connect(m_process.get(), QOverload::of(&QProcess::finished), this, [this](int, QProcess::ExitStatus){ + setRunning(false); + setReady(false); + }); + + connect(m_process.get(), &QProcess::errorOccurred, this, [](QProcess::ProcessError error){ + qWarning() << "\033[31m" << "Error occurred:" << error << "\033[39m"; + }); + + connect(m_process.get(), &QProcess::readyReadStandardOutput, this, [this](){ + QByteArray data = m_process->readAllStandardOutput(); + if (data.contains("Server started")) setReady(true); + qInfo() << "\033[33m" << data.toStdString().c_str() << "\033[39m"; + }); #endif @@ -52,8 +53,8 @@ bool PocketBaseServer::start() qInfo() << "Starting server with args:" << m_binaryPath << args.join(" "); - process->start(m_binaryPath, args); - return process->waitForStarted(); + m_process->start(m_binaryPath, args); + return m_process->waitForStarted(); #elif defined(Q_OS_WASM) || defined(Q_OS_IOS) return false; @@ -66,12 +67,12 @@ bool PocketBaseServer::start() PocketBaseCollectionPromise * PocketBaseServer::stop() { #if defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(Q_OS_LINUX) - stopProcess(); - PocketBaseCollectionPromise * promise = new PocketBaseCollectionPromise(this); - process->terminate(); - process->waitForFinished(); - promise->callThen({}); - return promise; + stopProcess(); + auto * promise = new PocketBaseCollectionPromise(this); + m_process->terminate(); + m_process->waitForFinished(); + promise->callThen({}); + return promise; #elif defined(Q_OS_WASM) || defined(Q_OS_IOS) PocketBaseCollectionPromise * promise = new PocketBaseCollectionPromise(this); // Return promise without starting the process diff --git a/src/PocketBaseServer.h b/src/PocketBaseServer.h index 6d2fd20..a40f212 100755 --- a/src/PocketBaseServer.h +++ b/src/PocketBaseServer.h @@ -2,7 +2,8 @@ #define POCKETBASESERVER_H #include -#include +#include +#include #include "PocketBaseCollectionPromise.h" class PocketBaseServer : public QObject @@ -21,41 +22,41 @@ class PocketBaseServer : public QObject public: explicit PocketBaseServer(QObject *parent = nullptr); - Q_INVOKABLE bool start(); - Q_INVOKABLE PocketBaseCollectionPromise * stop(); - Q_INVOKABLE bool restart(); + [[nodiscard]] Q_INVOKABLE bool start(); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise * stop(); + [[nodiscard]] Q_INVOKABLE bool restart(); - qint64 isRunning(); + [[nodiscard]] qint64 isRunning(); void stopProcess(); - QString address() const; + [[nodiscard]] QString address() const; void setAddress(const QString &newAddress); - int port() const; + [[nodiscard]] int port() const; void setPort(int newPort); - bool running() const; + [[nodiscard]] bool running() const; void setRunning(bool newRunning); - QString hookFolder() const; + [[nodiscard]] QString hookFolder() const; void setHookFolder(const QString &newHookFolder); - QString publicFolder() const; + [[nodiscard]] QString publicFolder() const; void setPublicFolder(const QString &newPublicFolder); - QString dataFolder() const; + [[nodiscard]] QString dataFolder() const; void setDataFolder(const QString &newDataFolder); - QString binaryPath() const; + [[nodiscard]] QString binaryPath() const; void setBinaryPath(const QString &newBinaryPath); - bool ready() const; + [[nodiscard]] bool ready() const; void setReady(bool newReady); - bool devMode() const; + [[nodiscard]] bool devMode() const; void setDevMode(bool newDevMode); - QString migrationDir() const; + [[nodiscard]] QString migrationDir() const; void setMigrationDir(const QString &newMigrationDir); signals: @@ -80,9 +81,9 @@ class PocketBaseServer : public QObject private: QString m_address = "localhost"; - #if defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(Q_OS_LINUX) - QProcess *process; - #endif + #if defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(Q_OS_LINUX) + std::unique_ptr m_process; + #endif int m_port = 8090; bool m_running = false; QString m_hookFolder = ""; diff --git a/src/PocketBaseSettings.h b/src/PocketBaseSettings.h index dea38c8..3f12818 100755 --- a/src/PocketBaseSettings.h +++ b/src/PocketBaseSettings.h @@ -8,8 +8,8 @@ class PocketBaseSettings : public QSettings { public: explicit PocketBaseSettings(QObject *parent = nullptr); - static QString getToken(); - static QString getApiUrl(); + [[nodiscard]] static QString getToken(); + [[nodiscard]] static QString getApiUrl(); static void setToken(QString token); static void setApiUrl(QString apiUrl); diff --git a/src/PocketRequest.cpp b/src/PocketRequest.cpp index f85217a..5b3ac93 100644 --- a/src/PocketRequest.cpp +++ b/src/PocketRequest.cpp @@ -223,7 +223,7 @@ PocketBaseCollectionPromise *PocketRequest::makeRequest(QNetworkRequest request, reply = manager->sendCustomRequest(request, methodToString(method)); - connect(reply, &QNetworkReply::finished, promise, [=]() + connect(reply, &QNetworkReply::finished, promise, [reply, promise]() { if (reply->error() == QNetworkReply::NoError) { promise->callThen(QJSValueList{QString(reply->readAll())}); @@ -235,7 +235,7 @@ PocketBaseCollectionPromise *PocketRequest::makeRequest(QNetworkRequest request, promise->callError(QJSValueList{QString(QJsonDocument(error).toJson())}); } }); - connect(reply, &QNetworkReply::errorOccurred, promise, [=](QNetworkReply::NetworkError error) + connect(reply, &QNetworkReply::errorOccurred, promise, [reply, promise](QNetworkReply::NetworkError error) { if (error == QNetworkReply::ConnectionRefusedError || error == QNetworkReply::HostNotFoundError || error == QNetworkReply::TimeoutError || error == QNetworkReply::UnknownNetworkError) { QJsonObject errorJson; @@ -267,7 +267,7 @@ PocketBaseCollectionPromise *PocketRequest::makeRequest(QNetworkRequest request, promise->callError(QJSValueList{QString(QJsonDocument(error).toJson())}); } }); - connect(reply, &QNetworkReply::errorOccurred, promise, [=](QNetworkReply::NetworkError error) + connect(reply, &QNetworkReply::errorOccurred, promise, [reply, promise](QNetworkReply::NetworkError error) { if (error == QNetworkReply::ConnectionRefusedError || error == QNetworkReply::HostNotFoundError || error == QNetworkReply::TimeoutError || error == QNetworkReply::UnknownNetworkError) { QJsonObject errorJson; @@ -287,7 +287,7 @@ PocketBaseCollectionPromise *PocketRequest::makeRequest(QNetworkRequest *request reply = manager->sendCustomRequest(*request, methodToString(method), multipart); - connect(reply, &QNetworkReply::finished, promise, [=]() + connect(reply, &QNetworkReply::finished, promise, [reply, promise]() { if (reply->error() == QNetworkReply::NoError) { promise->callThen(QJSValueList{QString(reply->readAll())}); @@ -299,7 +299,7 @@ PocketBaseCollectionPromise *PocketRequest::makeRequest(QNetworkRequest *request promise->callError(QJSValueList{QString(QJsonDocument(error).toJson())}); } }); - connect(reply, &QNetworkReply::errorOccurred, promise, [=](QNetworkReply::NetworkError error) + connect(reply, &QNetworkReply::errorOccurred, promise, [reply, promise](QNetworkReply::NetworkError error) { if (error == QNetworkReply::ConnectionRefusedError || error == QNetworkReply::HostNotFoundError || error == QNetworkReply::TimeoutError || error == QNetworkReply::UnknownNetworkError) { @@ -537,13 +537,13 @@ PocketBaseCollectionPromise *PocketRequest::downloadFile(const QString &url, con return promise; } - connect(reply, &QNetworkReply::readyRead, [=]() + connect(reply, &QNetworkReply::readyRead, [reply, file]() { if (file->isOpen()) { file->write(reply->readAll()); } }); - connect(reply, &QNetworkReply::finished, promise, [=]() + connect(reply, &QNetworkReply::finished, promise, [reply, file, promise]() { if (file->isOpen()) { file->close(); diff --git a/src/PocketRequest.h b/src/PocketRequest.h index 56e7ed5..78d8821 100755 --- a/src/PocketRequest.h +++ b/src/PocketRequest.h @@ -23,45 +23,45 @@ class PocketRequest : public QObject }; - Q_INVOKABLE PocketBaseCollectionPromise *getOne(QString id, QJsonObject options = {}); - Q_INVOKABLE PocketBaseCollectionPromise *getList(int page = 1, int perPage = 15, QJsonObject options = {}); - Q_INVOKABLE PocketBaseCollectionPromise *create(QJSValue data, QJsonObject options = {}); - PocketBaseCollectionPromise *create(QJsonObject data, QJsonObject options = {}); - Q_INVOKABLE PocketBaseCollectionPromise *createWithFile(QJSValue data, - QJSValue files, QJsonObject options = {}); - Q_INVOKABLE PocketBaseCollectionPromise *update(QString id, QJSValue data, QJsonObject options = {}); - PocketBaseCollectionPromise *update(QString id, QJsonObject data, QJsonObject options = {}); - Q_INVOKABLE PocketBaseCollectionPromise *updateWithFile(QString id, QJSValue data, - QJSValue files, QJsonObject options = {}); - Q_INVOKABLE PocketBaseCollectionPromise *deleteFile(QString id, QJSValue files, QJsonObject options = {}); - Q_INVOKABLE PocketBaseCollectionPromise *deleteOne(QString id, QJsonObject options = {}); - - Q_INVOKABLE PocketBaseCollectionPromise *authWithPassword(QString identity, QString password); - Q_INVOKABLE PocketBaseCollectionPromise *authRefresh(); - - Q_INVOKABLE PocketBaseCollectionPromise *HttpGet(QString path, QJSValue options = {}, bool other = false); - Q_INVOKABLE PocketBaseCollectionPromise *HttpPostFile(QString path, QJSValue data, QJSValue files, QJSValue options = {}, bool other = false); - Q_INVOKABLE PocketBaseCollectionPromise *HttpPost(QString path, QJSValue data, QJSValue options = {}, bool other = false); - Q_INVOKABLE PocketBaseCollectionPromise *HttpPost(QString path, QJsonObject datas, QJsonObject obj); - Q_INVOKABLE PocketBaseCollectionPromise *HttpPut(QString path, QJSValue data, QJSValue options = {}); - PocketBaseCollectionPromise *HttpPut(QString path, QJsonObject datas); - Q_INVOKABLE PocketBaseCollectionPromise *HttpPatch(QString path, QJSValue data, QJSValue options = {}); - Q_INVOKABLE PocketBaseCollectionPromise *HttpDelete(QString path, QJSValue options = {}); - - Q_INVOKABLE PocketBaseCollectionPromise *makeRequest(QNetworkRequest request, HttpMethod method = HttpMethod::GET); - Q_INVOKABLE PocketBaseCollectionPromise *makeRequest(QNetworkRequest request, HttpMethod method, QByteArray data); - Q_INVOKABLE PocketBaseCollectionPromise *makeRequest(QNetworkRequest *request, HttpMethod method, QHttpMultiPart *multiPart); - - - Q_INVOKABLE PocketBaseCollectionPromise *get(QString url, QJSValue headers = {}); - Q_INVOKABLE PocketBaseCollectionPromise *post(QString url, QJSValue data, QJSValue headers = {}); - Q_INVOKABLE PocketBaseCollectionPromise *put(QString url, QJSValue data, QJSValue headers = {}); - Q_INVOKABLE PocketBaseCollectionPromise *postFile(QString url, QJSValue data, QJSValue files, QJSValue headers = {}); - Q_INVOKABLE PocketBaseCollectionPromise *putFile(QString url, QJSValue data, QJSValue files, QJSValue headers = {}); - Q_INVOKABLE PocketBaseCollectionPromise *removeFile(QString url, QJSValue files, QJSValue headers = {}); - Q_INVOKABLE PocketBaseCollectionPromise *patch(QString url, QJSValue data, QJSValue headers = {}); - Q_INVOKABLE PocketBaseCollectionPromise *del(QString url, QJSValue headers = {}); - Q_INVOKABLE PocketBaseCollectionPromise *downloadFile(const QString &url, const QString &saveDir, QJSValue headers = {}); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *getOne(QString id, QJsonObject options = {}); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *getList(int page = 1, int perPage = 15, QJsonObject options = {}); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *create(QJSValue data, QJsonObject options = {}); + [[nodiscard]] PocketBaseCollectionPromise *create(QJsonObject data, QJsonObject options = {}); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *createWithFile(QJSValue data, + QJSValue files, QJsonObject options = {}); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *update(QString id, QJSValue data, QJsonObject options = {}); + [[nodiscard]] PocketBaseCollectionPromise *update(QString id, QJsonObject data, QJsonObject options = {}); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *updateWithFile(QString id, QJSValue data, + QJSValue files, QJsonObject options = {}); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *deleteFile(QString id, QJSValue files, QJsonObject options = {}); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *deleteOne(QString id, QJsonObject options = {}); + + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *authWithPassword(QString identity, QString password); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *authRefresh(); + + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *HttpGet(QString path, QJSValue options = {}, bool other = false); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *HttpPostFile(QString path, QJSValue data, QJSValue files, QJSValue options = {}, bool other = false); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *HttpPost(QString path, QJSValue data, QJSValue options = {}, bool other = false); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *HttpPost(QString path, QJsonObject datas, QJsonObject obj); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *HttpPut(QString path, QJSValue data, QJSValue options = {}); + [[nodiscard]] PocketBaseCollectionPromise *HttpPut(QString path, QJsonObject datas); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *HttpPatch(QString path, QJSValue data, QJSValue options = {}); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *HttpDelete(QString path, QJSValue options = {}); + + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *makeRequest(QNetworkRequest request, HttpMethod method = HttpMethod::GET); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *makeRequest(QNetworkRequest request, HttpMethod method, QByteArray data); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *makeRequest(QNetworkRequest *request, HttpMethod method, QHttpMultiPart *multiPart); + + + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *get(QString url, QJSValue headers = {}); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *post(QString url, QJSValue data, QJSValue headers = {}); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *put(QString url, QJSValue data, QJSValue headers = {}); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *postFile(QString url, QJSValue data, QJSValue files, QJSValue headers = {}); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *putFile(QString url, QJSValue data, QJSValue files, QJSValue headers = {}); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *removeFile(QString url, QJSValue files, QJSValue headers = {}); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *patch(QString url, QJSValue data, QJSValue headers = {}); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *del(QString url, QJSValue headers = {}); + [[nodiscard]] Q_INVOKABLE PocketBaseCollectionPromise *downloadFile(const QString &url, const QString &saveDir, QJSValue headers = {}); diff --git a/src/PocketUtility.cpp b/src/PocketUtility.cpp index fa42793..64ef1e9 100755 --- a/src/PocketUtility.cpp +++ b/src/PocketUtility.cpp @@ -4,7 +4,8 @@ #include #include #include -#include +#include +#include #include #include @@ -30,17 +31,19 @@ QJsonObject PocketUtility::jsvalueToJsonObject(QJSValue value) void PocketUtility::jsonToFormData(QHttpMultiPart *multiPart, QJsonObject &dataObject) { - for (QString key : dataObject.keys()) { - QHttpPart jsonPart; - jsonPart.setHeader(QNetworkRequest::ContentDispositionHeader, - QVariant("form-data; name=\"" + key + "\"")); - - QJsonValue value = dataObject.value(key); - if (value.isObject() || value.isArray()) { - jsonPart.setBody(value.toVariant().toJsonDocument().toJson()); - } else { - jsonPart.setBody(value.toString().toUtf8()); - } + for (const auto &key : dataObject.keys()) { + QHttpPart jsonPart; + jsonPart.setHeader(QNetworkRequest::ContentDispositionHeader, + QVariant("form-data; name=\"" + key + "\"")); + + QJsonValue value = dataObject.value(key); + if (value.isObject()) { + jsonPart.setBody(QJsonDocument(value.toObject()).toJson()); + } else if (value.isArray()) { + jsonPart.setBody(QJsonDocument(value.toArray()).toJson()); + } else { + jsonPart.setBody(value.toString().toUtf8()); + } multiPart->append(jsonPart); } @@ -48,30 +51,28 @@ void PocketUtility::jsonToFormData(QHttpMultiPart *multiPart, QJsonObject &dataO void PocketUtility::jsonFilesToFormData(QHttpMultiPart *multiPart, QJsonObject &filesObject, bool removing) { - QStringList keys = filesObject.keys(); - for (int i = 0; i < keys.size(); i++) { - QHttpPart filePart; - - QJsonArray filePaths = filesObject[keys[i]].toArray(); - - for(const QJsonValue &jsonfilePath : filePaths) { - QString filePath = jsonfilePath.toString(); - QFile *file = new QFile(filePath); + const QStringList keys = filesObject.keys(); + for (const auto &key : keys) { + QHttpPart filePart; + + const QJsonArray filePaths = filesObject[key].toArray(); + + for (const QJsonValue &jsonfilePath : filePaths) { + const QString filePath = jsonfilePath.toString(); + auto file = std::make_unique(filePath); QMimeDatabase mimeDb; - QMimeType mimeType = mimeDb.mimeTypeForFile(filePath); - QString contentDispositionValue; - - bool ok = file->open(QIODevice::ReadOnly); - if (removing) { - contentDispositionValue = "form-data; name=\"photo." + filePath + - "\""; - } else { - contentDispositionValue = "form-data; name=\"" + keys[i] + - "\"; filename=\"" + file->fileName() + "\""; - } + QMimeType mimeType = mimeDb.mimeTypeForFile(filePath); + QString contentDispositionValue; + + const bool ok = file->open(QIODevice::ReadOnly); + if (removing) { + contentDispositionValue = "form-data; name=\"photo." + filePath + "\""; + } else { + contentDispositionValue = "form-data; name=\"" + key + "\"; filename=\"" + file->fileName() + "\""; + } if (ok) qDebug() << "File opened" << mimeType.name() << contentDispositionValue; @@ -86,13 +87,12 @@ void PocketUtility::jsonFilesToFormData(QHttpMultiPart *multiPart, QJsonObject & QVariant(mimeType.name())); filePart.setHeader(QNetworkRequest::ContentDispositionHeader, contentDisposition); - if (ok) - { - filePart.setBodyDevice(file); - file->setParent(multiPart); - } else { - delete file; - } + if (ok) + { + auto *f = file.release(); + filePart.setBodyDevice(f); + f->setParent(multiPart); + } multiPart->append(filePart); } diff --git a/src/PocketUtility.h b/src/PocketUtility.h index c2343e6..b57dfdc 100755 --- a/src/PocketUtility.h +++ b/src/PocketUtility.h @@ -13,7 +13,7 @@ class PocketUtility : public QObject explicit PocketUtility(QObject *parent = nullptr); - static QJsonObject jsvalueToJsonObject(QJSValue value); + [[nodiscard]] static QJsonObject jsvalueToJsonObject(QJSValue value); static void jsonToFormData(QHttpMultiPart *multiPart, QJsonObject &dataObject); static void jsonFilesToFormData(QHttpMultiPart *multiPart, QJsonObject &filesObject, bool removing = false);