Skip to content

Commit

Permalink
Merge pull request #790 from otahirs/oresutlsService
Browse files Browse the repository at this point in the history
feat: OResults service
  • Loading branch information
fvacek authored Aug 26, 2022
2 parents 83c0dc4 + c403f7a commit a372c4c
Show file tree
Hide file tree
Showing 10 changed files with 493 additions and 31 deletions.
4 changes: 4 additions & 0 deletions quickevent/app/quickevent/plugins/Event/src/eventplugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <qf/core/sql/connection.h>
#include <qf/core/sql/transaction.h>
#include <qf/core/utils/fileutils.h>
#include <plugins/Event/src/services/oresultsclient.h>

#include <QInputDialog>
#include <QSqlDatabase>
Expand Down Expand Up @@ -363,6 +364,9 @@ void EventPlugin::onInstalled()
}
fwk->menuBar()->actionForPath("view/toolbar")->addActionInto(tb->toggleViewAction());

services::OResultsClient *oresults_client = new services::OResultsClient(this);
services::Service::addService(oresults_client);

services::EmmaClient *emma_client = new services::EmmaClient(this);
services::Service::addService(emma_client);

Expand Down
32 changes: 16 additions & 16 deletions quickevent/app/quickevent/plugins/Event/src/services/emmaclient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,14 +190,14 @@ void EmmaClient::exportResultsIofXml3()
QString file_name = export_dir + '/' + ss.fileNameBase() + ".results.xml";
int current_stage = getPlugin<EventPlugin>()->currentStageId();
bool is_relays = getPlugin<EventPlugin>()->eventConfig()->isRelays();
if (is_relays) {
QFile f(file_name);
if(f.open(QFile::WriteOnly)) {
f.write(getPlugin<RelaysPlugin>()->resultsIofXml30().toUtf8());
}
}
else {
getPlugin<RunsPlugin>()->exportResultsIofXml30Stage(current_stage, file_name);

QString str = is_relays
? getPlugin<RelaysPlugin>()->resultsIofXml30()
: getPlugin<RunsPlugin>()->resultsIofXml30Stage(current_stage);

QFile f(file_name);
if(f.open(QFile::WriteOnly)) {
f.write(str.toUtf8());
}
}

Expand All @@ -210,14 +210,14 @@ void EmmaClient::exportStartListIofXml3()
QString file_name = export_dir + '/' + ss.fileNameBase() + ".startlist.xml";
int current_stage = getPlugin<EventPlugin>()->currentStageId();
bool is_relays = getPlugin<EventPlugin>()->eventConfig()->isRelays();
if (is_relays) {
QFile f(file_name);
if(f.open(QFile::WriteOnly)) {
f.write(getPlugin<RelaysPlugin>()->startListIofXml30().toUtf8());
}
}
else {
getPlugin<RunsPlugin>()->exportStartListStageIofXml30(current_stage, file_name);

QString str = is_relays
? getPlugin<RelaysPlugin>()->startListIofXml30()
: getPlugin<RunsPlugin>()->startListStageIofXml30(current_stage);

QFile f(file_name);
if(f.open(QFile::WriteOnly)) {
f.write(str.toUtf8());
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
#include "oresultsclient.h"
#include "oresultsclientwidget.h"

#include "../eventplugin.h"

#include <qf/qmlwidgets/framework/mainwindow.h>
#include <qf/qmlwidgets/dialogs/dialog.h>

#include <qf/core/log.h>
#include <plugins/Runs/src/runsplugin.h>
#include <plugins/Relays/src/relaysplugin.h>

#include <QDir>
#include <QFile>
#include <QHttpPart>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QSettings>
#include <QStandardPaths>
#include <QTextStream>
#include <QTimer>

namespace qfc = qf::core;
namespace qfw = qf::qmlwidgets;
namespace qfd = qf::qmlwidgets::dialogs;
namespace qfs = qf::core::sql;
using qf::qmlwidgets::framework::getPlugin;
using Event::EventPlugin;
using Relays::RelaysPlugin;
using Runs::RunsPlugin;

namespace Event {
namespace services {

OResultsClient::OResultsClient(QObject *parent)
: Super(OResultsClient::serviceName(), parent)
{
m_networkManager = new QNetworkAccessManager(this);
m_exportTimer = new QTimer(this);
connect(m_exportTimer, &QTimer::timeout, this, &OResultsClient::onExportTimerTimeOut);
connect(this, &OResultsClient::statusChanged, [this](Status status) {
if(status == Status::Running) {
onExportTimerTimeOut();
m_exportTimer->start();
}
else {
m_exportTimer->stop();
}
});
connect(this, &OResultsClient::settingsChanged, this, &OResultsClient::init, Qt::QueuedConnection);

}

QString OResultsClient::serviceName()
{
return QStringLiteral("OResults");
}

void OResultsClient::exportResultsIofXml3()
{
int current_stage = getPlugin<EventPlugin>()->currentStageId();
bool is_relays = getPlugin<EventPlugin>()->eventConfig()->isRelays();

QString str = is_relays
? getPlugin<RelaysPlugin>()->resultsIofXml30()
: getPlugin<RunsPlugin>()->resultsIofXml30Stage(current_stage);

sendFile("results upload", "/results", str);
}

void OResultsClient::exportStartListIofXml3()
{

int current_stage = getPlugin<EventPlugin>()->currentStageId();
bool is_relays = getPlugin<EventPlugin>()->eventConfig()->isRelays();

QString str = is_relays
? getPlugin<RelaysPlugin>()->startListIofXml30()
: getPlugin<RunsPlugin>()->startListStageIofXml30(current_stage);

sendFile("start list upload", "/start-lists?format=xml", str);
}

qf::qmlwidgets::framework::DialogWidget *OResultsClient::createDetailWidget()
{
auto *w = new OResultsClientWidget();
return w;
}

void OResultsClient::init()
{
OResultsClientSettings ss = settings();
m_exportTimer->setInterval(ss.exportIntervalSec() * 1000);
}

void OResultsClient::onExportTimerTimeOut()
{
if(status() != Status::Running)
return;

exportResultsIofXml3();
}

void OResultsClient::loadSettings()
{
Super::loadSettings();
init();
}

void OResultsClient::sendFile(QString name, QString request_path, QString file) {

QHttpMultiPart *multi_part = new QHttpMultiPart(QHttpMultiPart::FormDataType);

QHttpPart api_key_part;
auto api_key = settings().apiKey();
api_key_part.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"apiKey\""));
api_key_part.setBody(api_key.toUtf8());

QHttpPart file_part;
file_part.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/xml"));
file_part.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"file\""));
file_part.setBody(file.toUtf8());

multi_part->append(api_key_part);
multi_part->append(file_part);

QUrl url(API_URL + request_path);
QNetworkRequest request(url);
QNetworkReply *reply = m_networkManager->post(request, multi_part);

connect(reply, &QNetworkReply::finished, [reply, name]()
{
if(reply->error())
{
qfError() << "OReuslts.eu [" + name + "]: " + QString(reply->readAll());
}
else
{
qfInfo() << "OReuslts.eu [" + name + "]: success";
}
reply->deleteLater();
});
}

}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#ifndef ORESULTSCLIENT_H
#define ORESULTSCLIENT_H

#pragma once

#include "service.h"

class QTimer;
class QNetworkAccessManager;

namespace Event {
namespace services {

class OResultsClientSettings : public ServiceSettings
{
using Super = ServiceSettings;

QF_VARIANTMAP_FIELD(QString, a, setA, piKey)
QF_VARIANTMAP_FIELD2(int, e, setE, xportIntervalSec, 15)
public:
OResultsClientSettings(const QVariantMap &o = QVariantMap()) : Super(o) {}
};

class OResultsClient : public Service
{
Q_OBJECT

using Super = Service;
public:
OResultsClient(QObject *parent);

//void run() override;
//void stop() override;
OResultsClientSettings settings() const {return OResultsClientSettings(m_settings);}

static QString serviceName();

void exportResultsIofXml3();
void exportStartListIofXml3();
void loadSettings() override;
private:
qf::qmlwidgets::framework::DialogWidget *createDetailWidget() override;
void onExportTimerTimeOut();
void init();
QTimer *m_exportTimer = nullptr;
QNetworkAccessManager *m_networkManager = nullptr;
void sendFile(QString name, QString request_path, QString file);
const QString API_URL = "https://api.oresults.eu";
};

}}

#endif // ORESULTSCLIENT_H
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#include "oresultsclientwidget.h"
#include "ui_oresultsclientwidget.h"
#include "oresultsclient.h"
#include "../eventplugin.h"
#include <qf/qmlwidgets/framework/mainwindow.h>

#include <qf/qmlwidgets/dialogs/messagebox.h>

#include <qf/core/assert.h>

#include <QFileDialog>
using qf::qmlwidgets::framework::getPlugin;

namespace Event {
namespace services {

OResultsClientWidget::OResultsClientWidget(QWidget *parent)
: Super(parent)
, ui(new Ui::OResultsClientWidget)
{
setPersistentSettingsId("OResultsClientWidget");
ui->setupUi(this);

OResultsClient *svc = service();
if(svc) {
OResultsClientSettings ss = svc->settings();
ui->edExportInterval->setValue(ss.exportIntervalSec());
ui->edApiKey->setText(ss.apiKey());
}

connect(ui->btExportResultsXml30, &QPushButton::clicked, this, &OResultsClientWidget::onBtExportResultsXml30Clicked);
connect(ui->btExportStartListXml30, &QPushButton::clicked, this, &OResultsClientWidget::onBtExportStartListXml30Clicked);
}

OResultsClientWidget::~OResultsClientWidget()
{
delete ui;
}

bool OResultsClientWidget::acceptDialogDone(int result)
{
if(result == QDialog::Accepted) {
if(!saveSettings()) {
return false;
}
}
return true;
}

OResultsClient *OResultsClientWidget::service()
{
OResultsClient *svc = qobject_cast<OResultsClient*>(Service::serviceByName(OResultsClient::serviceName()));
QF_ASSERT(svc, OResultsClient::serviceName() + " doesn't exist", return nullptr);
return svc;
}

bool OResultsClientWidget::saveSettings()
{
OResultsClient *svc = service();
if(svc) {
OResultsClientSettings ss = svc->settings();
ss.setExportIntervalSec(ui->edExportInterval->value());
ss.setApiKey(ui->edApiKey->text().trimmed());

svc->setSettings(ss);
}
return true;
}

void OResultsClientWidget::onBtExportResultsXml30Clicked()
{
OResultsClient *svc = service();
if(svc) {
saveSettings();
svc->exportResultsIofXml3();
}
}

void OResultsClientWidget::onBtExportStartListXml30Clicked()
{
OResultsClient *svc = service();
if(svc) {
saveSettings();
svc->exportStartListIofXml3();
}
}
}}

Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#pragma once

#include <qf/qmlwidgets/framework/dialogwidget.h>

namespace Event {
namespace services {

namespace Ui {
class OResultsClientWidget;
}

class OResultsClient;

class OResultsClientWidget : public qf::qmlwidgets::framework::DialogWidget
{
Q_OBJECT

using Super = qf::qmlwidgets::framework::DialogWidget;
public:
explicit OResultsClientWidget(QWidget *parent = nullptr);
~OResultsClientWidget();
private:
void onBtExportResultsXml30Clicked();
void onBtExportStartListXml30Clicked();
OResultsClient* service();
bool saveSettings();
private:
Ui::OResultsClientWidget *ui;
bool acceptDialogDone(int result);
};

}}

Loading

0 comments on commit a372c4c

Please sign in to comment.