show server tasks (basic)

This commit is contained in:
Pierre Ducroquet 2023-06-23 13:48:56 +02:00
parent c4ebd0a6a5
commit f0a1e50a95
7 changed files with 224 additions and 28 deletions

View File

@ -34,6 +34,9 @@ set(PROJECT_SOURCES
ovhwebauthentication.ui
ovhapi.cpp
ovhapi.h
pendingtasks.h
pendingtasks.cpp
pendingtasks.ui
resources.qrc
servicesview.h
servicesview.cpp

View File

@ -360,120 +360,119 @@
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainwindow.cpp" line="94"/>
<location filename="mainwindow.cpp" line="95"/>
<source>Expired token</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainwindow.cpp" line="94"/>
<location filename="mainwindow.cpp" line="95"/>
<source>It seems this token is expired. Please login again to continue.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainwindow.cpp" line="153"/>
<location filename="mainwindow.cpp" line="154"/>
<source>Validate credential</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainwindow.cpp" line="153"/>
<location filename="mainwindow.cpp" line="154"/>
<source>Have you validated the OVH credential request?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainwindow.cpp" line="209"/>
<location filename="mainwindow.cpp" line="210"/>
<source>Group %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainwindow.cpp" line="225"/>
<location filename="mainwindow.cpp" line="226"/>
<source>Info %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainwindow.cpp" line="240"/>
<location filename="mainwindow.cpp" line="241"/>
<source>IPMI not activated</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainwindow.cpp" line="240"/>
<location filename="mainwindow.cpp" line="241"/>
<source>IPMI is not activated on this server</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainwindow.cpp" line="249"/>
<location filename="mainwindow.cpp" line="250"/>
<source>IPMI KVM not available</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainwindow.cpp" line="249"/>
<location filename="mainwindow.cpp" line="250"/>
<source>IPMI KVM is not available on this server</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainwindow.cpp" line="273"/>
<source>Waiting for task... %1</source>
<oldsource>Waiting for task...</oldsource>
<location filename="mainwindow.cpp" line="269"/>
<source>Tasks for server %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainwindow.cpp" line="293"/>
<location filename="mainwindow.cpp" line="298"/>
<source>KVM %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainwindow.cpp" line="302"/>
<location filename="mainwindow.cpp" line="304"/>
<location filename="mainwindow.cpp" line="307"/>
<location filename="mainwindow.cpp" line="309"/>
<source>JNLP KVM</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainwindow.cpp" line="302"/>
<location filename="mainwindow.cpp" line="307"/>
<source>This server only supports a Java WebStart KVM, it will thus not be embedded in this window.
Java WebStart should be starting right now, wait until it finishes loading to close this dialog.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainwindow.cpp" line="304"/>
<location filename="mainwindow.cpp" line="309"/>
<source>Failed to launch javaws. Make sure it is properly installed.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainwindow.cpp" line="403"/>
<location filename="mainwindow.cpp" line="408"/>
<source>Target archive</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainwindow.cpp" line="403"/>
<location filename="mainwindow.cpp" line="408"/>
<source>Zip files (*.zip)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainwindow.cpp" line="407"/>
<location filename="mainwindow.cpp" line="412"/>
<source>OVH...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainwindow.cpp" line="407"/>
<location filename="mainwindow.cpp" line="412"/>
<source>OVH decided that getting a bill require a &apos;true&apos; login. I&apos;m going to show you a web browser for that.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainwindow.cpp" line="418"/>
<location filename="mainwindow.cpp" line="423"/>
<source>Failed to open archive</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainwindow.cpp" line="418"/>
<location filename="mainwindow.cpp" line="423"/>
<source>Failed to open archive...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="mainwindow.cpp" line="510"/>
<location filename="mainwindow.cpp" line="515"/>
<source>Logins cleaned up</source>
<translation type="unfinished"></translation>
</message>
<message numerus="yes">
<location filename="mainwindow.cpp" line="510"/>
<location filename="mainwindow.cpp" line="515"/>
<source>%n login(s) purged</source>
<translation type="unfinished">
<numerusform></numerusform>
@ -494,6 +493,45 @@ Java WebStart should be starting right now, wait until it finishes loading to cl
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>PendingTasks</name>
<message>
<location filename="pendingtasks.ui" line="14"/>
<source>Dialog</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="pendingtasks.ui" line="21"/>
<source>ID</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="pendingtasks.ui" line="26"/>
<source>Type</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="pendingtasks.ui" line="31"/>
<source>Start date</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="pendingtasks.ui" line="36"/>
<source>Status</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="pendingtasks.ui" line="44"/>
<source>Refreshed on %1</source>
<oldsource>Refreshing...</oldsource>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="pendingtasks.cpp" line="55"/>
<source>Done on %1</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ServicesView</name>
<message>

View File

@ -26,7 +26,7 @@ What I plan to add:
- [x] a better interface to get the KVM,
- [x] hardware information
- [x] server monthly cost
- [ ] view of pending tasks on a given server,
- [~] view of pending tasks on a given server (in progress),
- [ ] support for vrack on dedicated servers,
- [ ] a dedicated **searchable** bill view, because it's an ugly mess on OVH side.
- [ ] switch to KDDockWidgets for a nicer interface, maybe

View File

@ -27,6 +27,7 @@
#include "dedicatedservergroupwidget.h"
#include "dedicatedserverinfowidget.h"
#include "ovhwebauthentication.h"
#include "pendingtasks.h"
using namespace std::chrono_literals;
@ -263,6 +264,11 @@ QCoro::Task<> MainWindow::startKVMRequest(const QString &serverName)
qDebug() << "Initial task:" << kvmAccess; // This is a silly task object, have to wait on it... because the api will not wait for us, ho no, the heresy...
int kvmTaskId = kvmAccess["taskId"].toInt();
qDebug() << "Task is " << kvmTaskId;
auto taskView = new PendingTasks(api, QString{"/dedicated/server/%1/task"}.arg(serverName), this);
taskView->setWindowTitle(tr("Tasks for server %1").arg(serverReverse));
taskView->showNormal();
auto taskUrlString = QString{"/dedicated/server/%1/task/%2"}.arg(serverName).arg(kvmTaskId);
int progress = 1;
while (kvmAccess["status"].toString() != "done") {
@ -270,7 +276,6 @@ QCoro::Task<> MainWindow::startKVMRequest(const QString &serverName)
QTimer timer;
timer.start(1s);
co_await timer;
ui->statusbar->showMessage(tr("Waiting for task... %1").arg(progress));
qDebug() << "Going to request an update on the task...";
kvmAccess = (co_await api->get(taskUrlString));
qDebug() << "task progress:" << kvmAccess;

61
pendingtasks.cpp Normal file
View File

@ -0,0 +1,61 @@
#include "pendingtasks.h"
#include "ui_pendingtasks.h"
#include "ovhapi.h"
#include <QTimer>
#include <QDebug>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
PendingTasks::PendingTasks(OvhApi *api, const QString &path, QWidget *parent) :
QDialog(parent),
ui(new Ui::PendingTasks),
api(api),
apiPath(path)
{
ui->setupUi(this);
setAttribute(Qt::WA_DeleteOnClose);
baseRefreshText = ui->refreshLabel->text();
refreshTimer = new QTimer{this};
refreshTimer->setInterval(1000);
refreshTimer->setSingleShot(false);
refreshTimer->start();
connect(refreshTimer, &QTimer::timeout, this, &PendingTasks::refresh);
QTimer::singleShot(0, this, &PendingTasks::refresh);
}
PendingTasks::~PendingTasks()
{
delete ui;
}
QCoro::Task<> PendingTasks::refresh() {
auto tasks = co_await api->get(apiPath);
qDebug() << tasks;
auto tasksArray = tasks.array();
ui->tableWidget->setRowCount(tasksArray.count());
int i = 0;
for (auto &&taskIdJson: tasksArray) {
int c = 0;
auto taskId = taskIdJson.toInt();
QString taskPath = QString("%1/%2").arg(apiPath).arg(taskId);
qDebug() << "Fetching on " << taskPath;
auto taskData = (co_await api->get(taskPath)).object();
qDebug() << taskData;
// ID ; Type ; start date ; status
auto tableItem = new QTableWidgetItem(QString::number(taskId));
ui->tableWidget->setItem(i, c++, tableItem);
tableItem = new QTableWidgetItem(taskData["function"].toString());
ui->tableWidget->setItem(i, c++, tableItem);
tableItem = new QTableWidgetItem(taskData["startDate"].toString());
ui->tableWidget->setItem(i, c++, tableItem);
tableItem = new QTableWidgetItem(taskData["status"].toString());
if (taskData["status"].toString() == "done")
tableItem->setToolTip(tr("Done on %1").arg(taskData["doneDate"].toString()));
ui->tableWidget->setItem(i, c++, tableItem);
ui->tableWidget->resizeColumnsToContents();
i++;
}
ui->refreshLabel->setText(baseRefreshText.arg(QDateTime::currentDateTime().time().toString()));
}

34
pendingtasks.h Normal file
View File

@ -0,0 +1,34 @@
#ifndef PENDINGTASKS_H
#define PENDINGTASKS_H
#include <QDialog>
#include <QCoroTask>
namespace Ui {
class PendingTasks;
}
class OvhApi;
class QTimer;
class PendingTasks : public QDialog
{
Q_OBJECT
public:
explicit PendingTasks(OvhApi *api, const QString &path, QWidget *parent = nullptr);
~PendingTasks();
private slots:
QCoro::Task<> refresh();
private:
Ui::PendingTasks *ui;
OvhApi *api;
QTimer *refreshTimer;
QString apiPath;
QString baseRefreshText;
};
#endif // PENDINGTASKS_H

55
pendingtasks.ui Normal file
View File

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PendingTasks</class>
<widget class="QDialog" name="PendingTasks">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>606</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QTableWidget" name="tableWidget">
<column>
<property name="text">
<string>ID</string>
</property>
</column>
<column>
<property name="text">
<string>Type</string>
</property>
</column>
<column>
<property name="text">
<string>Start date</string>
</property>
</column>
<column>
<property name="text">
<string>Status</string>
</property>
</column>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="refreshLabel">
<property name="text">
<string>Refreshed on %1</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>