//SPDX-FileCopyrightText: 2023 Yury Gubich //SPDX-License-Identifier: GPL-3.0-or-later #include "api.h" #include #include #include #include #include "requests/test.h" #include "requests/register.h" #include "requests/login.h" #include "requests/poll.h" #include "requests/assets.h" #include "requests/currencies.h" #include "requests/addasset.h" #include "requests/deleteasset.h" #include "requests/updateasset.h" API::API (Models::Magpie& magpie, QObject* parent): QObject(parent), idCounter(0), magpie(magpie), network(), requests() {} void API::cancelRequest (RequestId id) { requests.erase(id); } void API::onRequestDone (RequestId id) { requests.erase(id); } API::RequestId API::test (const QString& path, const QJSValue& finished) { qDebug() << "Testing" << path; if (magpie.getState() == Models::Magpie::Offline) callCallback(finished, "Need to be online to test"), 0; std::unique_ptr test = std::make_unique(path); connect( test.get(), &Request::Test::success, this, [this, &path, &finished] (const QVariantMap& data) { callCallback(finished, QString(), {QJSValue(true)}); magpie.forceAddress(path); } ); connect(test.get(), &Request::Test::error, std::bind(&API::callCallback, this, finished, std::placeholders::_1, QJSValueList(false))); return registerAndSend(std::move(test)); } API::RequestId API::sendRegister (const QString& login, const QString& password, const QJSValue& finished) { qDebug() << "Registering..."; if (magpie.getState() != Models::Magpie::NotAuthenticated) return callCallback(finished, "Can not register in current state"), 0; std::unique_ptr reg = std::make_unique(login, password, magpie.getAddress()); connect(reg.get(), &Request::Register::success, std::bind(&API::callCallback, this, finished, QString(), QJSValueList{QJSValue(true)})); connect(reg.get(), &Request::Register::error, std::bind(&API::callCallback, this, finished, std::placeholders::_1, QJSValueList{QJSValue(false)})); return registerAndSend(std::move(reg)); } API::RequestId API::sendLogin (const QString& login, const QString& password, const QJSValue& finished) { qDebug() << "Logging in..."; if (magpie.getState() != Models::Magpie::NotAuthenticated) return callCallback(finished, "Can not register in current state"), 0; std::unique_ptr log = std::make_unique(login, password, magpie.getAddress()); connect( log.get(), &Request::Login::success, this, [this, &finished] (const QVariantMap& data) { callCallback(finished, QString(), {QJSValue(true)}); magpie.setTokens(data.value("accessToken").toString(), data.value("renewToken").toString()); } ); connect( log.get(), &Request::Login::error, this, [this, &finished] (const QString& error) { callCallback(finished, error, {QJSValue(false)}); magpie.setState(Models::Magpie::NotAuthenticated); } ); magpie.setState(Models::Magpie::Authenticating); return registerAndSend(std::move(log)); } API::RequestId API::requestAssets (const SuccessListHandler& success, const ErrorHandler& error) { qDebug() << "Requesting assets..."; auto list = std::make_unique(magpie.getAddress()); list->setAuthorizationToken(magpie.getAccessToken()); connect(list.get(), &Request::Assets::success, success); connect(list.get(), &Request::Assets::error, error); return registerAndSend(std::move(list)); } API::RequestId API::requestCurrencies (const SuccessListHandler& success, const ErrorHandler& error) { qDebug() << "Requesting currencies..."; auto list = std::make_unique(magpie.getAddress()); list->setAuthorizationToken(magpie.getAccessToken()); connect(list.get(), &Request::Currencies::success, success); connect(list.get(), &Request::Currencies::error, error); return registerAndSend(std::move(list)); } API::RequestId API::addAsset ( const QString& title, const QString& icon, const QColor& color, Models::Currency::ID currency, const QJSValue& finished ) { qDebug() << "Adding asset..."; if (magpie.getState() != Models::Magpie::Authenticated) return callCallback(finished, "Can not add assets in current state"), 0; auto add = std::make_unique(title, icon, color, currency, magpie.getAddress()); add->setAuthorizationToken(magpie.getAccessToken()); connect(add.get(), &Request::AddAsset::success, std::bind(&API::callCallback, this, finished, QString(), QJSValueList{QJSValue(true)})); connect(add.get(), &Request::AddAsset::error, std::bind(&API::callCallback, this, finished, std::placeholders::_1, QJSValueList{QJSValue(false)})); return registerAndSend(std::move(add)); } API::RequestId API::updateAsset ( Models::Asset::ID id, const QString& title, const QString& icon, const QColor& color, Models::Currency::ID currency, const QJSValue& finished ) { qDebug() << "Updating asset..."; if (magpie.getState() != Models::Magpie::Authenticated) return callCallback(finished, "Can not update assets in current state"), 0; auto update = std::make_unique(id, title, icon, color, currency, magpie.getAddress()); update->setAuthorizationToken(magpie.getAccessToken()); connect(update.get(), &Request::UpdateAsset::success, std::bind(&API::callCallback, this, finished, QString(), QJSValueList{QJSValue(true)})); connect(update.get(), &Request::UpdateAsset::error, std::bind(&API::callCallback, this, finished, std::placeholders::_1, QJSValueList{QJSValue(false)})); return registerAndSend(std::move(update)); } API::RequestId API::deleteAsset (unsigned int id, const QJSValue& finished) { qDebug() << "Deleting asset..."; if (magpie.getState() != Models::Magpie::Authenticated) return callCallback(finished, "Can not delete assets in current state"), 0; auto del = std::make_unique(id, magpie.getAddress()); del->setAuthorizationToken(magpie.getAccessToken()); connect(del.get(), &Request::DeleteAsset::success, std::bind(&API::callCallback, this, finished, QString(), QJSValueList{QJSValue(true)})); connect(del.get(), &Request::DeleteAsset::error, std::bind(&API::callCallback, this, finished, std::placeholders::_1, QJSValueList{QJSValue(false)})); return registerAndSend(std::move(del)); } API::RequestId API::poll (const SuccessMapHandler& success, const ErrorHandler& error, bool clear) { auto poll = std::make_unique(magpie.getAddress(), clear); poll->setAuthorizationToken(magpie.getAccessToken()); connect(poll.get(), &Request::Poll::success, success); connect(poll.get(), &Request::Poll::error, error); return registerAndSend(std::move(poll)); } API::RequestId API::registerAndSend (std::unique_ptr request) { Request::Request* req = request.get(); requests.emplace(++idCounter, std::move(request)); connect(req, &Request::Request::done, std::bind(&API::onRequestDone, this, idCounter)); req->send(network); return idCounter; } void API::callCallback (const QJSValue& callback, const QString& error, const QJSValueList& arguments) const { if (callback.isCallable()) { if (error.isEmpty()) callback.call(QJSValueList({QJSValue(QJSValue::NullValue)}) + arguments); else callback.call({QJSValue(error)}); } }