From d423636b0319e144e5a9d834d48c656bf97bc983 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lie=20DELHAIE?= Date: Sat, 13 Sep 2025 15:34:27 +0200 Subject: [PATCH] first commit --- .gitignore | 74 +++++++++++++++ backup.cpp | 3 + backup.h | 10 ++ client.cpp | 71 ++++++++++++++ client.h | 35 +++++++ cloudsave-gui.pro | 35 +++++++ information.cpp | 18 ++++ information.h | 21 +++++ main.cpp | 11 +++ mainwindow.cpp | 14 +++ mainwindow.h | 23 +++++ mainwindow.ui | 108 ++++++++++++++++++++++ metadata.cpp | 19 ++++ metadata.h | 23 +++++ resources.qrc | 7 ++ resources/arrows-rotate-solid-full.svg | 1 + resources/magnifying-glass-solid-full.svg | 1 + resources/plus-solid-full.svg | 1 + 18 files changed, 475 insertions(+) create mode 100644 .gitignore create mode 100644 backup.cpp create mode 100644 backup.h create mode 100644 client.cpp create mode 100644 client.h create mode 100644 cloudsave-gui.pro create mode 100644 information.cpp create mode 100644 information.h create mode 100644 main.cpp create mode 100644 mainwindow.cpp create mode 100644 mainwindow.h create mode 100644 mainwindow.ui create mode 100644 metadata.cpp create mode 100644 metadata.h create mode 100644 resources.qrc create mode 100644 resources/arrows-rotate-solid-full.svg create mode 100644 resources/magnifying-glass-solid-full.svg create mode 100644 resources/plus-solid-full.svg diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4a0b530 --- /dev/null +++ b/.gitignore @@ -0,0 +1,74 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* +CMakeLists.txt.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/backup.cpp b/backup.cpp new file mode 100644 index 0000000..f8630e1 --- /dev/null +++ b/backup.cpp @@ -0,0 +1,3 @@ +#include "backup.h" + +Backup::Backup() {} diff --git a/backup.h b/backup.h new file mode 100644 index 0000000..132eabd --- /dev/null +++ b/backup.h @@ -0,0 +1,10 @@ +#ifndef BACKUP_H +#define BACKUP_H + +class Backup +{ +public: + Backup(); +}; + +#endif // BACKUP_H diff --git a/client.cpp b/client.cpp new file mode 100644 index 0000000..02e8433 --- /dev/null +++ b/client.cpp @@ -0,0 +1,71 @@ +#include "client.h" +#include +#include +#include +#include +#include + +Client::Client(QString url, QString username, QString password) { + this->url = url; + this->username = username; + this->password = password; +} + +void Client::version(std::function callback, std::function errorCallback) +{ + QNetworkAccessManager manager; + QUrl url(this->url); + url = url.resolved(QUrl("/api/v1/version/")); + QNetworkRequest request(url); + QNetworkReply *reply = manager.get(request); + QObject::connect(reply, &QNetworkReply::finished, [&]() { + if (reply->error() == QNetworkReply::NoError) { + QByteArray response = reply->readAll(); + QJsonDocument doc = QJsonDocument::fromJson(response); + Information info(doc.object()); + callback(info); + } else { + errorCallback(reply->errorString()); + } + reply->deleteLater(); + }); +} + +void Client::hash(QString gameID, std::function callback, std::function errorCallback) +{ + QNetworkAccessManager manager; + QUrl url(this->url); + url = url.resolved("/api/v1/games/"+gameID+"/metadata"); + QNetworkRequest request(url); + QNetworkReply *reply = manager.get(request); + QObject::connect(reply, &QNetworkReply::finished, [&]() { + if (reply->error() == QNetworkReply::NoError) { + QByteArray response = reply->readAll(); + QJsonDocument doc = QJsonDocument::fromJson(response); + callback(doc.object()["md5"].toString()); + } else { + errorCallback(reply->errorString()); + } + reply->deleteLater(); + }); +} + +void Client::metadata(QString gameID, std::function callback, std::function errorCallback) +{ + QNetworkAccessManager manager; + QUrl url(this->url); + url = url.resolved("/api/v1/games/"+gameID+"/metadata"); + QNetworkRequest request(url); + QNetworkReply *reply = manager.get(request); + QObject::connect(reply, &QNetworkReply::finished, [&]() { + if (reply->error() == QNetworkReply::NoError) { + QByteArray response = reply->readAll(); + QJsonDocument doc = QJsonDocument::fromJson(response); + Metadata m(doc.object()); + callback(m); + } else { + errorCallback(reply->errorString()); + } + reply->deleteLater(); + }); +} diff --git a/client.h b/client.h new file mode 100644 index 0000000..e7b4178 --- /dev/null +++ b/client.h @@ -0,0 +1,35 @@ +#ifndef CLIENT_H +#define CLIENT_H + +#include +#include "information.h" +#include "metadata.h" +#include "backup.h" + +class Client +{ +public: + Client(QString url, QString username, QString password); + + bool exists(QString gameID, std::function callback, std::function errorCallback); + void version(std::function callback, std::function errorCallback); + void hash(QString gameID, std::function callback, std::function errorCallback); + void metadata(QString gameID, std::function callback, std::function errorCallback); + void pushSave(QString archivePath, Metadata game, std::function callback, std::function errorCallback); + void pushBackup(QString archivePath, Metadata game, std::function callback, std::function errorCallback); + void listArchives(QString gameID, std::function)> callback, std::function errorCallback); + void archiveInfo(QString gameID, QString backupID, std::function callback, std::function errorCallback); + void pull(QString gameID, QString archivePath, std::function callback, std::function errorCallback); + void pullBackup(QString gameID, QString backupID, QString archivePath, std::function callback, std::function errorCallback); + bool ping(std::function callback, std::function errorCallback); + void all(std::function)> callback, std::function errorCallback); + QString baseURL(); + +private: + QString url; + QString username; + QString password; + +}; + +#endif // CLIENT_H diff --git a/cloudsave-gui.pro b/cloudsave-gui.pro new file mode 100644 index 0000000..2304bfb --- /dev/null +++ b/cloudsave-gui.pro @@ -0,0 +1,35 @@ +QT += core gui network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++17 + +# You can make your code fail to compile if it uses deprecated APIs. +# In order to do so, uncomment the following line. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +SOURCES += \ + backup.cpp \ + client.cpp \ + information.cpp \ + main.cpp \ + mainwindow.cpp \ + metadata.cpp + +HEADERS += \ + backup.h \ + client.h \ + information.h \ + mainwindow.h \ + metadata.h + +FORMS += \ + mainwindow.ui + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +RESOURCES += \ + resources.qrc diff --git a/information.cpp b/information.cpp new file mode 100644 index 0000000..1c6bb7d --- /dev/null +++ b/information.cpp @@ -0,0 +1,18 @@ +#include "information.h" + +Information::Information(QString version, QString apiVersion, QString goVersion, QString osName, QString osArchitecture) { + this->_version = version; + this->_apiVersion = apiVersion; + this->_goVersion = goVersion; + this->_osName = osName; + this->_osArchitecture = osArchitecture; +} + +Information::Information(QJsonObject obj) +{ + this->_version = obj["version"].toString(); + this->_apiVersion = obj["api_version"].toString(); + this->_goVersion = obj["go_version"].toString(); + this->_osName = obj["os_name"].toString(); + this->_osArchitecture = obj["os_architecture"].toString(); +} diff --git a/information.h b/information.h new file mode 100644 index 0000000..9c42a6b --- /dev/null +++ b/information.h @@ -0,0 +1,21 @@ +#ifndef INFORMATION_H +#define INFORMATION_H + +#include +#include + +class Information +{ +public: + Information(QString version, QString apiVersion, QString goVersion, QString osName, QString osArchitecture); + Information(QJsonObject obj); + +private: + QString _version; + QString _apiVersion; + QString _goVersion; + QString _osName; + QString _osArchitecture; +}; + +#endif // INFORMATION_H diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..fd3e533 --- /dev/null +++ b/main.cpp @@ -0,0 +1,11 @@ +#include "mainwindow.h" + +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + MainWindow w; + w.show(); + return a.exec(); +} diff --git a/mainwindow.cpp b/mainwindow.cpp new file mode 100644 index 0000000..2740a6e --- /dev/null +++ b/mainwindow.cpp @@ -0,0 +1,14 @@ +#include "mainwindow.h" +#include "ui_mainwindow.h" + +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent) + , ui(new Ui::MainWindow) +{ + ui->setupUi(this); +} + +MainWindow::~MainWindow() +{ + delete ui; +} diff --git a/mainwindow.h b/mainwindow.h new file mode 100644 index 0000000..f7a3da3 --- /dev/null +++ b/mainwindow.h @@ -0,0 +1,23 @@ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { +class MainWindow; +} +QT_END_NAMESPACE + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(QWidget *parent = nullptr); + ~MainWindow(); + +private: + Ui::MainWindow *ui; +}; +#endif // MAINWINDOW_H diff --git a/mainwindow.ui b/mainwindow.ui new file mode 100644 index 0000000..f3a0be1 --- /dev/null +++ b/mainwindow.ui @@ -0,0 +1,108 @@ + + + MainWindow + + + + 0 + 0 + 1002 + 594 + + + + + 1002 + 594 + + + + CloudSave + + + + + + + + + + + + + + + + + 0 + 0 + + + + + 16777215 + 90 + + + + toolBar + + + false + + + + 70 + 37 + + + + Qt::ToolButtonTextUnderIcon + + + false + + + TopToolBarArea + + + false + + + + + + + + + + :/icon/resources/plus-solid-full.svg:/icon/resources/plus-solid-full.svg + + + Add + + + + + + :/icon/resources/magnifying-glass-solid-full.svg:/icon/resources/magnifying-glass-solid-full.svg + + + Scan + + + + + + :/icon/resources/arrows-rotate-solid-full.svg:/icon/resources/arrows-rotate-solid-full.svg + + + Sync + + + + + + + + diff --git a/metadata.cpp b/metadata.cpp new file mode 100644 index 0000000..d74ada3 --- /dev/null +++ b/metadata.cpp @@ -0,0 +1,19 @@ +#include "metadata.h" + +Metadata::Metadata(QString name) { + this->_name = name; +} + +Metadata::Metadata(QJsonObject obj) +{ + this->_id = obj["id"].toString(); + this->_name = obj["name"].toString(); + this->_version = obj["version"].toInt(); + this->_date = QDateTime::fromString(obj["date"].toString()); + this->_md5 = obj["md5"].toString(); +} + +QString Metadata::md5() +{ + return this->_md5; +} diff --git a/metadata.h b/metadata.h new file mode 100644 index 0000000..206507d --- /dev/null +++ b/metadata.h @@ -0,0 +1,23 @@ +#ifndef METADATA_H +#define METADATA_H + +#include +#include +#include + +class Metadata +{ +public: + Metadata(QString name); + Metadata(QJsonObject obj); + + QString md5(); +private: + QString _id; + QString _name; + uint64_t _version; + QDateTime _date; + QString _md5; +}; + +#endif // METADATA_H diff --git a/resources.qrc b/resources.qrc new file mode 100644 index 0000000..af66d60 --- /dev/null +++ b/resources.qrc @@ -0,0 +1,7 @@ + + + resources/plus-solid-full.svg + resources/arrows-rotate-solid-full.svg + resources/magnifying-glass-solid-full.svg + + diff --git a/resources/arrows-rotate-solid-full.svg b/resources/arrows-rotate-solid-full.svg new file mode 100644 index 0000000..42c1b5c --- /dev/null +++ b/resources/arrows-rotate-solid-full.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/magnifying-glass-solid-full.svg b/resources/magnifying-glass-solid-full.svg new file mode 100644 index 0000000..f8554f5 --- /dev/null +++ b/resources/magnifying-glass-solid-full.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/plus-solid-full.svg b/resources/plus-solid-full.svg new file mode 100644 index 0000000..658ea9a --- /dev/null +++ b/resources/plus-solid-full.svg @@ -0,0 +1 @@ + \ No newline at end of file