compatdb: Use a seperate endpoint for testcase submission

This commit is contained in:
fearlessTobi 2018-10-26 16:21:45 +02:00
parent 5b7d21c3cd
commit b7117bf050
7 changed files with 65 additions and 7 deletions

View file

@ -5,6 +5,7 @@
#include <QButtonGroup> #include <QButtonGroup>
#include <QMessageBox> #include <QMessageBox>
#include <QPushButton> #include <QPushButton>
#include <QtConcurrent/qtconcurrentrun.h>
#include "citra_qt/compatdb.h" #include "citra_qt/compatdb.h"
#include "common/telemetry.h" #include "common/telemetry.h"
#include "core/core.h" #include "core/core.h"
@ -21,6 +22,8 @@ CompatDB::CompatDB(QWidget* parent)
connect(ui->radioButton_IntroMenu, &QRadioButton::clicked, this, &CompatDB::EnableNext); connect(ui->radioButton_IntroMenu, &QRadioButton::clicked, this, &CompatDB::EnableNext);
connect(ui->radioButton_WontBoot, &QRadioButton::clicked, this, &CompatDB::EnableNext); connect(ui->radioButton_WontBoot, &QRadioButton::clicked, this, &CompatDB::EnableNext);
connect(button(NextButton), &QPushButton::clicked, this, &CompatDB::Submit); connect(button(NextButton), &QPushButton::clicked, this, &CompatDB::Submit);
connect(&testcase_watcher, &QFutureWatcher<bool>::finished, this,
&CompatDB::OnTestcaseSubmitted);
} }
CompatDB::~CompatDB() = default; CompatDB::~CompatDB() = default;
@ -46,18 +49,38 @@ void CompatDB::Submit() {
} }
break; break;
case CompatDBPage::Final: case CompatDBPage::Final:
back();
LOG_DEBUG(Frontend, "Compatibility Rating: {}", compatibility->checkedId()); LOG_DEBUG(Frontend, "Compatibility Rating: {}", compatibility->checkedId());
Core::Telemetry().AddField(Telemetry::FieldType::UserFeedback, "Compatibility", Core::Telemetry().AddField(Telemetry::FieldType::UserFeedback, "Compatibility",
compatibility->checkedId()); compatibility->checkedId());
// older versions of QT don't support the "NoCancelButtonOnLastPage" option, this is a
// workaround button(NextButton)->setEnabled(false);
button(NextButton)->setText(tr("Submitting"));
button(QWizard::CancelButton)->setVisible(false); button(QWizard::CancelButton)->setVisible(false);
testcase_watcher.setFuture(QtConcurrent::run(
[this]() { return Core::System::GetInstance().TelemetrySession().SubmitTestcase(); }));
break; break;
default: default:
LOG_ERROR(Frontend, "Unexpected page: {}", currentId()); LOG_ERROR(Frontend, "Unexpected page: {}", currentId());
} }
} }
void CompatDB::OnTestcaseSubmitted() {
if (!testcase_watcher.result()) {
QMessageBox::critical(this, tr("Communication error"),
tr("An error occured while sending the Testcase"));
button(NextButton)->setEnabled(true);
button(NextButton)->setText(tr("Next"));
button(QWizard::CancelButton)->setVisible(true);
} else {
next();
// older versions of QT don't support the "NoCancelButtonOnLastPage" option, this is a
// workaround
button(QWizard::CancelButton)->setVisible(false);
}
}
void CompatDB::EnableNext() { void CompatDB::EnableNext() {
button(NextButton)->setEnabled(true); button(NextButton)->setEnabled(true);
} }

View file

@ -5,6 +5,7 @@
#pragma once #pragma once
#include <memory> #include <memory>
#include <QFutureWatcher>
#include <QWizard> #include <QWizard>
namespace Ui { namespace Ui {
@ -19,8 +20,11 @@ public:
~CompatDB(); ~CompatDB();
private: private:
QFutureWatcher<bool> testcase_watcher;
std::unique_ptr<Ui::CompatDB> ui; std::unique_ptr<Ui::CompatDB> ui;
void Submit(); void Submit();
void OnTestcaseSubmitted();
void EnableNext(); void EnableNext();
}; };

View file

@ -153,6 +153,7 @@ struct VisitorInterface : NonCopyable {
/// Completion method, called once all fields have been visited /// Completion method, called once all fields have been visited
virtual void Complete() = 0; virtual void Complete() = 0;
virtual bool SubmitTestcase() = 0;
}; };
/** /**
@ -178,6 +179,9 @@ struct NullVisitor : public VisitorInterface {
void Visit(const Field<std::chrono::microseconds>& /*field*/) override {} void Visit(const Field<std::chrono::microseconds>& /*field*/) override {}
void Complete() override {} void Complete() override {}
bool SubmitTestcase() override {
return false;
}
}; };
} // namespace Telemetry } // namespace Telemetry

View file

@ -203,4 +203,13 @@ TelemetrySession::~TelemetrySession() {
backend = nullptr; backend = nullptr;
} }
bool TelemetrySession::SubmitTestcase() {
#ifdef ENABLE_WEB_SERVICE
field_collection.Accept(*backend);
return backend->SubmitTestcase();
#else
return false;
#endif
}
} // namespace Core } // namespace Core

View file

@ -31,6 +31,12 @@ public:
field_collection.AddField(type, name, std::move(value)); field_collection.AddField(type, name, std::move(value));
} }
/**
* Submits a Testcase.
* @returns A bool indicating whether the submission succeeded
*/
bool SubmitTestcase();
private: private:
Telemetry::FieldCollection field_collection; ///< Tracks all added fields for the session Telemetry::FieldCollection field_collection; ///< Tracks all added fields for the session
std::unique_ptr<Telemetry::VisitorInterface> backend; ///< Backend interface that logs fields std::unique_ptr<Telemetry::VisitorInterface> backend; ///< Backend interface that logs fields

View file

@ -102,16 +102,27 @@ void TelemetryJson::Complete() {
impl->SerializeSection(Telemetry::FieldType::App, "App"); impl->SerializeSection(Telemetry::FieldType::App, "App");
impl->SerializeSection(Telemetry::FieldType::Session, "Session"); impl->SerializeSection(Telemetry::FieldType::Session, "Session");
impl->SerializeSection(Telemetry::FieldType::Performance, "Performance"); impl->SerializeSection(Telemetry::FieldType::Performance, "Performance");
impl->SerializeSection(Telemetry::FieldType::UserFeedback, "UserFeedback");
impl->SerializeSection(Telemetry::FieldType::UserConfig, "UserConfig"); impl->SerializeSection(Telemetry::FieldType::UserConfig, "UserConfig");
impl->SerializeSection(Telemetry::FieldType::UserSystem, "UserSystem"); impl->SerializeSection(Telemetry::FieldType::UserSystem, "UserSystem");
auto content = impl->TopSection().dump(); auto content = impl->TopSection().dump();
// Send the telemetry async but don't handle the errors since they were written to the log // Send the telemetry async but don't handle the errors since they were written to the log
Common::DetachedTasks::AddTask( Common::DetachedTasks::AddTask([host{impl->host}, content]() {
[host{impl->host}, username{impl->username}, token{impl->token}, content]() { Client{host, "", ""}.PostJson("/telemetry", content, true);
Client{host, username, token}.PostJson("/telemetry", content, true); });
}); }
bool TelemetryJson::SubmitTestcase() {
impl->SerializeSection(Telemetry::FieldType::App, "App");
impl->SerializeSection(Telemetry::FieldType::Session, "Session");
impl->SerializeSection(Telemetry::FieldType::UserFeedback, "UserFeedback");
impl->SerializeSection(Telemetry::FieldType::UserSystem, "UserSystem");
auto content = impl->TopSection().dump();
Client client(impl->host, impl->username, impl->token);
auto value = client.PostJson("/gamedb/testcase", content, false);
return value.result_code == Common::WebResult::Code::Success;
} }
} // namespace WebService } // namespace WebService

View file

@ -36,6 +36,7 @@ public:
void Visit(const Telemetry::Field<std::chrono::microseconds>& field) override; void Visit(const Telemetry::Field<std::chrono::microseconds>& field) override;
void Complete() override; void Complete() override;
bool SubmitTestcase() override;
private: private:
struct Impl; struct Impl;