diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6227335..37378e8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -103,10 +103,6 @@ endif()
target_include_directories(miraya PRIVATE
${FORMS_DIR}
${SOURCE_DIR}
- ${SOURCE_TWITCH_DIR}
- ${SOURCE_OSU_DIR}
- ${SOURCE_UTILS_DIR}
- ${SOURCE_SETUPWIZARD_DIR}
)
# =========================== linking libraries ===========================
target_link_libraries(miraya PRIVATE Qt6::Core Qt6::Widgets Qt6::WebSockets Qt6::Network)
diff --git a/forms/preferences.ui b/forms/preferences.ui
index c48027f..f595082 100644
--- a/forms/preferences.ui
+++ b/forms/preferences.ui
@@ -50,6 +50,15 @@
:/resources/images/logo_gosumemory.ico:/resources/images/logo_gosumemory.ico
+ -
+
+ osu! API
+
+
+
+ :/resources/images/logo_osu.png:/resources/images/logo_osu.png
+
+
-
Twitch
@@ -61,7 +70,7 @@
-
- Osu! IRC
+ osu! IRC
@@ -161,6 +170,64 @@
+
+
+ -
+
+
+ QLineEdit::Password
+
+
+
+ -
+
+
+ Qt::ImhDigitsOnly
+
+
+
+ -
+
+
+ Client ID
+
+
+
+ -
+
+
+ Client Secret
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
-
@@ -325,7 +392,7 @@
-
+
-
diff --git a/forms/setupwizard.ui b/forms/setupwizard.ui
index 03ce812..da2c40b 100644
--- a/forms/setupwizard.ui
+++ b/forms/setupwizard.ui
@@ -98,6 +98,64 @@
+
+
+ osu! API
+
+
+ This will help miraya to grab data from beatmaps when they are requested.
+
+
+ -
+
+
-
+
+
+ osu! Client ID
+
+
+
+ -
+
+
+ Qt::ImhDigitsOnly
+
+
+ 6
+
+
+
+ -
+
+
+ osu! Client Secret
+
+
+
+ -
+
+
+ Qt::ImhHiddenText|Qt::ImhNoAutoUppercase|Qt::ImhNoPredictiveText|Qt::ImhSensitiveData
+
+
+ QLineEdit::Password
+
+
+
+
+
+ -
+
+
+ <html><head/><body><p>Go to your <a href="https://osu.ppy.sh/home/account/edit"><span style=" text-decoration: underline; color:#4285f4;">osu! account settings</span></a> and create a new OAuth application (at the bottom of the page). </p><p>You can chose whatever name you want, and there is no need to put any application callback URL.</p></body></html>
+
+
+ true
+
+
+
+
+
Twitch Setup
diff --git a/src/backup/backup.h b/src/backup/backup.h
index abd08eb..84f3e50 100644
--- a/src/backup/backup.h
+++ b/src/backup/backup.h
@@ -10,12 +10,11 @@
#include
#include
-class Backup : public QObject
+class Backup
{
- Q_OBJECT
-public:
- static void backup(QString filePath, bool includeSensitiveInfo);
- static void restore(QString filePath);
+ public:
+ static void backup(QString filePath, bool includeSensitiveInfo);
+ static void restore(QString filePath);
};
#endif // BACKUP_H
diff --git a/src/main.cpp b/src/main.cpp
index cf32d49..48cac49 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -8,7 +8,7 @@ int main(int argc, char **argv) {
app.setOrganizationName("miraya");
app.setOrganizationDomain("github.com/MirayaProject");
app.setApplicationName("bot");
- app.setApplicationVersion("1.2.0");
+ app.setApplicationVersion("1.3.0-alpha.1");
#ifdef Q_OS_LINUX
app.setWindowIcon(QIcon(":/resources/logo/logo.png"));
#endif
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index e639ac0..4677e5e 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -18,6 +18,8 @@ MainWindow::MainWindow(QWidget *parent) :
updater = new Updater(this);
updater->checkVersion();
+ osuApi = new OsuApi();
+
setupSignals();
if(!settings.value("setup/completed").toBool()){
on_actionStart_Setup_triggered();
@@ -143,9 +145,18 @@ void MainWindow::onGosumemoryClientMessageReceived(GosuMemoryDataWrapper message
void MainWindow::onTwitchClientMessageReceived(TwitchDataWrapper message)
{
// TODO: this should not be here
- for (auto val : Utils().getOsuBeatmapUrls(message.getMessage())) {
- qDebug() << "[MainWindow] Osu beatmap url: " << val;
- osuIrcClient->sendMap(QUrl(val), message);
+ for (QString url : Utils::getOsuBeatmapUrls(message.getMessage())) {
+ qDebug() << "[MainWindow] Osu beatmap url: " << url;
+
+ int beatmapId = Utils::getBeatmapIdFromOsuBeatmapLink(url);
+ if (beatmapId > 0 && osuApi->isValid()) {
+ // TODO: also this should not be here
+ QJsonObject mapData = osuApi->getBeatmapInfo(beatmapId);
+ osuIrcClient->sendMap(mapData, message);
+ }
+ else {
+ osuIrcClient->sendMap(QUrl(url), message);
+ }
}
QLabel* label = getTwitchChatMessage(message.getUsername(), message.getMessage());
diff --git a/src/mainwindow.h b/src/mainwindow.h
index 20f6282..e958042 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -27,6 +27,7 @@
#include "twitchdatawrapper.h"
#include "updater.h"
#include "utils.h"
+#include "osu/api/osuapi.h"
namespace Ui {
@@ -41,7 +42,6 @@ class MainWindow : public QMainWindow
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
-
private slots:
void on_btnStart_clicked();
void on_actionStart_Setup_triggered();
@@ -78,6 +78,7 @@ class MainWindow : public QMainWindow
GosumemoryClient *gosumemoryClient;
OsuIrcClient *osuIrcClient;
Updater *updater;
+ OsuApi *osuApi;
QLabel *ircConnectionLabel;
QLabel *twitchConnectionLabel;
diff --git a/src/osu/api/auth/clientCredentialsFlow.cpp b/src/osu/api/auth/clientCredentialsFlow.cpp
new file mode 100644
index 0000000..1edcaa1
--- /dev/null
+++ b/src/osu/api/auth/clientCredentialsFlow.cpp
@@ -0,0 +1,42 @@
+#include "clientCredentialsFlow.h"
+
+QJsonObject ClientCredentialsFlow::getToken(QString clientId, QString clientSecret, QString oAuthUrl)
+{
+ qDebug() << "[ClientCredentialsFlow] getToken";
+ QNetworkAccessManager manager;
+ QNetworkRequest request((QUrl(oAuthUrl)));
+
+ request.setHeader(
+ QNetworkRequest::ContentTypeHeader,
+ "application/x-www-form-urlencoded"
+ );
+ request.setHeader(
+ QNetworkRequest::UserAgentHeader,
+ "Miraya"
+ );
+
+ QUrlQuery params;
+ params.addQueryItem("client_id", clientId);
+ params.addQueryItem("client_secret", clientSecret);
+ params.addQueryItem("grant_type", "client_credentials");
+ params.addQueryItem("scope", "public");
+
+ QNetworkReply *reply = manager.post(request, params.toString(QUrl::FullyEncoded).toUtf8());
+
+ QEventLoop loop;
+ QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
+ loop.exec();
+
+ int httpStatusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
+
+ qDebug() << "[ClientCredentialsFlow] HTTP Status code: " << httpStatusCode;
+ if (httpStatusCode == 200) {
+ QJsonDocument doc = QJsonDocument::fromJson(reply->readAll());
+ QJsonObject obj = doc.object();
+ return obj;
+ }
+ qDebug() << "[ClientCredentialsFlow] Failed to get token";
+ QJsonDocument doc = QJsonDocument::fromJson(reply->readAll());
+ qDebug() << QString(doc.toJson(QJsonDocument::Compact));
+ return doc.object();
+}
diff --git a/src/osu/api/auth/clientCredentialsFlow.h b/src/osu/api/auth/clientCredentialsFlow.h
new file mode 100644
index 0000000..ecbe07f
--- /dev/null
+++ b/src/osu/api/auth/clientCredentialsFlow.h
@@ -0,0 +1,24 @@
+#ifndef CLIENTCREDENTIALSFLOW_H
+#define CLIENTCREDENTIALSFLOW_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+class ClientCredentialsFlow
+{
+ public:
+ static QJsonObject getToken(
+ QString clientId,
+ QString clientSecret,
+ QString oAuthUrl = QString("https://osu.ppy.sh/oauth/token")
+ );
+};
+
+#endif // CLIENTCREDENTIALSFLOW_H
diff --git a/src/osu/api/osuapi.cpp b/src/osu/api/osuapi.cpp
new file mode 100644
index 0000000..7df38e5
--- /dev/null
+++ b/src/osu/api/osuapi.cpp
@@ -0,0 +1,58 @@
+#include "osuapi.h"
+
+OsuApi::OsuApi()
+{
+ qDebug() << "[OsuApi] Init";
+ QSettings settings;
+ clientId = settings.value("osuapi/clientId").toString();
+ clientSecret = settings.value("osuapi/clientSecret").toString();
+ oAuthUrl = "https://osu.ppy.sh/oauth/token";
+
+ if (!(clientId.isEmpty() || clientSecret.isEmpty())) {
+ token = ClientCredentialsFlow::getToken(clientId, clientSecret, oAuthUrl);
+ }
+ else {
+ qDebug() << "[OsuApi] Client ID or Client Secret are empty";
+ }
+}
+
+QJsonObject OsuApi::getBeatmapInfo(int beatmapId)
+{
+ // TODO: A lot can be split into smaller functions
+ // TODO: also, the QEventLoop is making everything synchronous, which is suboptimal to say the least.
+ qDebug() << "[OsuApi] getBeatmapInfo";
+ QNetworkAccessManager manager;
+ QUrl url(QString("https://osu.ppy.sh/api/v2/beatmaps/%1").arg(beatmapId));
+
+ QNetworkRequest request(url);
+
+ QString accessToken = token["access_token"].toString();
+
+ request.setRawHeader(
+ QByteArray("Authorization"),
+ (QString("Bearer %1").arg(accessToken)).toUtf8()
+ );
+
+ QNetworkReply *reply = manager.get(request);
+
+ QEventLoop loop;
+ QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
+ loop.exec();
+
+ qDebug() << "[OsuApi] get request done";
+ int httpStatusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
+ qDebug() << "[OsuApi] HTTP Status code: " << httpStatusCode;
+ if (httpStatusCode == 200) {
+ QJsonDocument doc = QJsonDocument::fromJson(reply->readAll());
+ QJsonObject obj = doc.object();
+ qDebug() << "[OsuApi] Beatmap info: " << obj;
+ return obj;
+ }
+ qDebug() << "[OsuApi] Error: " << reply->errorString();
+ return QJsonObject();
+}
+
+bool OsuApi::isValid()
+{
+ return !(clientId.isEmpty() || clientSecret.isEmpty());
+}
diff --git a/src/osu/api/osuapi.h b/src/osu/api/osuapi.h
new file mode 100644
index 0000000..a37578d
--- /dev/null
+++ b/src/osu/api/osuapi.h
@@ -0,0 +1,31 @@
+#ifndef OSUAPI_H
+#define OSUAPI_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "api/auth/clientCredentialsFlow.h"
+
+class OsuApi : public QObject
+{
+ public:
+ OsuApi();
+ QJsonObject getBeatmapInfo(int beatmapId);
+ bool isValid();
+
+ private:
+ QString clientId;
+ QString clientSecret;
+ QString oAuthUrl;
+ QJsonObject token;
+};
+
+#endif // OSUAPI_H
diff --git a/src/osu/irc/osuircclient.cpp b/src/osu/irc/osuircclient.cpp
index e6a2680..5bb0550 100644
--- a/src/osu/irc/osuircclient.cpp
+++ b/src/osu/irc/osuircclient.cpp
@@ -105,12 +105,30 @@ void OsuIrcClient::sendPrivmsg(QString message)
void OsuIrcClient::sendMap(QUrl url, TwitchDataWrapper message)
{
- // TODO: the map embed should have the map name.
- // Scraping is needed.
-
qDebug() << "[osu!IRC] Sending map-request: " << url.toString() << " by " << message.getUsername();
- QString msg = " [" + url.toString() + " Map request] " + "sent by " + message.getUsername() + "\r\n";
+ QString msg = QString("[%1 Map request] sent by %2").arg(url.toString()).arg(message.getUsername());
+ sendPrivmsg(msg);
+}
+
+void OsuIrcClient::sendMap(QJsonObject map, TwitchDataWrapper message)
+{
+ QString requestor = message.getUsername();
+ QString artist = map["beatmapset"].toObject()["artist"].toString();
+ QString title = map["beatmapset"].toObject()["title"].toString();
+ QString status = map["beatmapset"].toObject()["status"].toString();
+ int mapId = map["id"].toInt();
+ QString url = QString("https://osu.ppy.sh/b/%1").arg(mapId);
+
+ qDebug() << "[osu!IRC] Sending map-request: " << url << " by " << requestor << " (" << artist << " - " << title << " - " << status << ")";
+
+ QString msg = QString("(%1) [%2 %3 - %4] sent by %5")
+ .arg(status)
+ .arg(url)
+ .arg(artist)
+ .arg(title)
+ .arg(message.getUsername());
+
sendPrivmsg(msg);
}
@@ -128,4 +146,4 @@ void OsuIrcClient::onReadyRead()
handlePing(data.split(" ").last().toLocal8Bit());
}
emit readyRead();
-}
\ No newline at end of file
+}
diff --git a/src/osu/irc/osuircclient.h b/src/osu/irc/osuircclient.h
index c233c86..d20aaa6 100644
--- a/src/osu/irc/osuircclient.h
+++ b/src/osu/irc/osuircclient.h
@@ -2,6 +2,7 @@
#define OSUIRCCLIENT_H
#include
+#include
#include
#include
#include
@@ -29,6 +30,7 @@ class OsuIrcClient : public QObject {
void setPort(const int &port);
void sendPrivmsg(QString message);
void sendMap(QUrl url, TwitchDataWrapper message);
+ void sendMap(QJsonObject map, TwitchDataWrapper message);
private:
void handlePing(QString response);
diff --git a/src/preferences/preferences.cpp b/src/preferences/preferences.cpp
index 80da039..b77f656 100644
--- a/src/preferences/preferences.cpp
+++ b/src/preferences/preferences.cpp
@@ -2,23 +2,23 @@
#include "ui_preferences.h"
Preferences::Preferences(QWidget *parent) :
- QDialog(parent),
- ui(new Ui::Preferences)
+ QDialog(parent),
+ ui(new Ui::Preferences)
{
- ui->setupUi(this);
- connect(ui->listWidget, &QListWidget::currentItemChanged, this, &Preferences::on_listWidget_currentItemChanged);
- connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &Preferences::on_saveBtnClicked);
- connect(ui->backupBtn, &QPushButton::clicked, this, &Preferences::on_backupBtn_clicked);
- connect(ui->restoreBtn, &QPushButton::clicked, this, &Preferences::on_restoreBtn_clicked);
- ui->listWidget->setCurrentRow(0);
- loadSettings();
- setupUi();
+ ui->setupUi(this);
+ connect(ui->listWidget, &QListWidget::currentItemChanged, this, &Preferences::on_listWidget_currentItemChanged);
+ connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &Preferences::on_saveBtnClicked);
+ connect(ui->backupBtn, &QPushButton::clicked, this, &Preferences::on_backupBtn_clicked);
+ connect(ui->restoreBtn, &QPushButton::clicked, this, &Preferences::on_restoreBtn_clicked);
+ ui->listWidget->setCurrentRow(0);
+ loadSettings();
+ setupUi();
}
Preferences::~Preferences()
{
- delete ui;
+ delete ui;
}
@@ -45,121 +45,130 @@ void Preferences::setupUi()
void Preferences::loadSettings()
{
- loadGosuMemorySettings();
- loadTwitchSettings();
- loadOsuIrcSettings();
- loadThemeSettings();
+ loadGosuMemorySettings();
+ loadTwitchSettings();
+ loadOsuIrcSettings();
+ loadThemeSettings();
+ loadOsuApiSettings();
}
void Preferences::loadTwitchSettings()
{
- ui->twitchBotNickLineEdit->setText(settings.value("twitch/botNick").toString());
- ui->twitchBotOAuthLineEdit->setText(settings.value("twitch/oauth").toString());
- ui->twitchChannelLineEdit->setText(settings.value("twitch/channel").toString());
+ ui->twitchBotNickLineEdit->setText(settings.value("twitch/botNick").toString());
+ ui->twitchBotOAuthLineEdit->setText(settings.value("twitch/oauth").toString());
+ ui->twitchChannelLineEdit->setText(settings.value("twitch/channel").toString());
}
+void Preferences::loadOsuApiSettings()
+{
+ ui->osuapiClientIdLineEdit->setText(settings.value("osuapi/clientId").toString());
+ ui->osuapiClientSecretLineEdit->setText(settings.value("osuapi/clientSecret").toString());
+}
void Preferences::loadGosuMemorySettings()
{
- ui->gosumemoryIpLineEdit->setText(settings.value("gosumemory/ip").toString());
- ui->gosumemoryPortLineEdit->setText(settings.value("gosumemory/port").toString());
+ ui->gosumemoryIpLineEdit->setText(settings.value("gosumemory/ip").toString());
+ ui->gosumemoryPortLineEdit->setText(settings.value("gosumemory/port").toString());
}
void Preferences::loadOsuIrcSettings()
{
- ui->osuIrcNicknameLineEdit->setText(settings.value("osuirc/nick").toString());
- ui->osuIrcPasswordLineEdit->setText(settings.value("osuirc/password").toString());
- ui->osuIrcServerLineEdit->setText(settings.value("osuirc/server").toString());
- ui->osuIrcPortLineEdit->setText(settings.value("osuirc/port").toString());
+ ui->osuIrcNicknameLineEdit->setText(settings.value("osuirc/nick").toString());
+ ui->osuIrcPasswordLineEdit->setText(settings.value("osuirc/password").toString());
+ ui->osuIrcServerLineEdit->setText(settings.value("osuirc/server").toString());
+ ui->osuIrcPortLineEdit->setText(settings.value("osuirc/port").toString());
}
void Preferences::loadThemeSettings()
{
- auto darkModeSetting = settings.value("theme/darkMode");
-
- if(darkModeSetting.isNull()){
- ui->themesDefaultRadio->setChecked(true);
- }
- else {
- bool isDarkMode = darkModeSetting.toBool();
- ui->themesLightRadio->setChecked(!isDarkMode);
- ui->themesDarkRadio->setChecked(isDarkMode);
- }
+ auto darkModeSetting = settings.value("theme/darkMode");
+
+ if(darkModeSetting.isNull()){
+ ui->themesDefaultRadio->setChecked(true);
+ }
+ else {
+ bool isDarkMode = darkModeSetting.toBool();
+ ui->themesLightRadio->setChecked(!isDarkMode);
+ ui->themesDarkRadio->setChecked(isDarkMode);
+ }
}
void Preferences::on_saveBtnClicked()
{
- saveSettings();
- QMessageBox().information(this, "Saved", "Settings saved");
- emit themeChanged();
- accept();
+ saveSettings();
+ QMessageBox().information(this, "Saved", "Settings saved");
+ emit themeChanged();
+ accept();
}
void Preferences::saveSettings()
{
- settings.setValue("twitch/botNick", ui->twitchBotNickLineEdit->text().toLower());
- settings.setValue("twitch/oauth", ui->twitchBotOAuthLineEdit->text());
- settings.setValue("twitch/channel", ui->twitchChannelLineEdit->text().toLower());
+ settings.setValue("twitch/botNick", ui->twitchBotNickLineEdit->text().toLower());
+ settings.setValue("twitch/oauth", ui->twitchBotOAuthLineEdit->text());
+ settings.setValue("twitch/channel", ui->twitchChannelLineEdit->text().toLower());
+
+ settings.setValue("gosumemory/ip", ui->gosumemoryIpLineEdit->text());
+ settings.setValue("gosumemory/port", ui->gosumemoryPortLineEdit->text());
- settings.setValue("gosumemory/ip", ui->gosumemoryIpLineEdit->text());
- settings.setValue("gosumemory/port", ui->gosumemoryPortLineEdit->text());
+ settings.setValue("osuapi/clientId", ui->osuapiClientIdLineEdit->text());
+ settings.setValue("osuapi/clientSecret", ui->osuapiClientSecretLineEdit->text());
// Spaces need to be replaced by underscores.
// https://osu.ppy.sh/wiki/en/Community/Internet_Relay_Chat#connection
- settings.setValue("osuirc/nick", ui->osuIrcNicknameLineEdit->text().replace(' ', '_'));
- settings.setValue("osuirc/password", ui->osuIrcPasswordLineEdit->text());
- settings.setValue("osuirc/server", ui->osuIrcServerLineEdit->text());
- settings.setValue("osuirc/port", ui->osuIrcPortLineEdit->text());
-
- if (ui->themesDefaultRadio->isChecked() && settings.contains("theme/darkMode")) {
- settings.remove("theme/darkMode");
- }
- else {
- settings.setValue("theme/darkMode", ui->themesDarkRadio->isChecked());
- }
+ settings.setValue("osuirc/nick", ui->osuIrcNicknameLineEdit->text().replace(' ', '_'));
+ settings.setValue("osuirc/password", ui->osuIrcPasswordLineEdit->text());
+ settings.setValue("osuirc/server", ui->osuIrcServerLineEdit->text());
+ settings.setValue("osuirc/port", ui->osuIrcPortLineEdit->text());
+
+ if (ui->themesDefaultRadio->isChecked() && settings.contains("theme/darkMode")) {
+ settings.remove("theme/darkMode");
+ }
+ else {
+ settings.setValue("theme/darkMode", ui->themesDarkRadio->isChecked());
+ }
}
void Preferences::on_backupBtn_clicked()
{
- QString message = QString("%1
%2").arg(
- "Would you like to include sensitive informations in your backup file?",
- "Anyone that has this information will be able to access your accounts!"
- );
-
- auto buttonAnswer = QMessageBox().question(
- this,
- "Sensitive information",
- message,
- QMessageBox::No | QMessageBox::Yes,
- QMessageBox::No
- );
- bool includeSensitiveInfo = buttonAnswer == QMessageBox::Yes;
-
- QString filePath = QFileDialog::getSaveFileName(nullptr, "Export Settings", QString(), "JSON Files (*.json)");
- Backup::backup(filePath, includeSensitiveInfo);
+ QString message = QString("%1
%2").arg(
+ "Would you like to include sensitive informations in your backup file?",
+ "Anyone that has this information will be able to access your accounts!"
+ );
+
+ auto buttonAnswer = QMessageBox().question(
+ this,
+ "Sensitive information",
+ message,
+ QMessageBox::No | QMessageBox::Yes,
+ QMessageBox::No
+ );
+ bool includeSensitiveInfo = buttonAnswer == QMessageBox::Yes;
+
+ QString filePath = QFileDialog::getSaveFileName(nullptr, "Export Settings", QString(), "JSON Files (*.json)");
+ Backup::backup(filePath, includeSensitiveInfo);
}
void Preferences::on_restoreBtn_clicked()
{
- QString filePath = QFileDialog::getOpenFileName(nullptr, "Import Settings", QString(), "JSON Files (*.json)");
- Backup::restore(filePath);
- // reloading
- loadSettings();
- QMessageBox().information(this, "Backup Restored", "Backup restored successfully");
+ QString filePath = QFileDialog::getOpenFileName(nullptr, "Import Settings", QString(), "JSON Files (*.json)");
+ Backup::restore(filePath);
+ // reloading
+ loadSettings();
+ QMessageBox().information(this, "Backup Restored", "Backup restored successfully");
}
void Preferences::on_listWidget_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)
{
- if (current == nullptr)
- return;
- auto index = ui->listWidget->currentRow();
- ui->stackedWidget->setCurrentIndex(index);
+ if (current == nullptr)
+ return;
+ auto index = ui->listWidget->currentRow();
+ ui->stackedWidget->setCurrentIndex(index);
}
diff --git a/src/preferences/preferences.h b/src/preferences/preferences.h
index 4a76de6..0868591 100644
--- a/src/preferences/preferences.h
+++ b/src/preferences/preferences.h
@@ -32,6 +32,7 @@ class Preferences : public QDialog
void loadSettings();
void loadTwitchSettings();
void loadGosuMemorySettings();
+ void loadOsuApiSettings();
void loadOsuIrcSettings();
void loadThemeSettings();
void setupUi();
diff --git a/src/setupwizard/setupwizard.cpp b/src/setupwizard/setupwizard.cpp
index 0f1de0d..0b3adf7 100644
--- a/src/setupwizard/setupwizard.cpp
+++ b/src/setupwizard/setupwizard.cpp
@@ -53,8 +53,8 @@ void SetupWizard::on_SetupWizard_finished(int result)
QJsonObject SetupWizard::gatherData()
{
QJsonObject data;
-
data["gosumemory"] = getGosumemoryData();
+ data["osuapi"] = getOsuApiData();
data["twitch"] = getTwitchData();
data["osuirc"] = getOsuircData();
@@ -75,6 +75,18 @@ QJsonObject SetupWizard::getGosumemoryData()
return gosumemoryData;
}
+QJsonObject SetupWizard::getOsuApiData()
+{
+ int osuapiClientId = ui->osuapiClientIdLineEdit->text().toInt();
+ QString osuapiClientSecret = ui->osuapiClientSecretLineEdit->text();
+
+ QJsonObject osuapiClientData = QJsonObject{
+ {"clientId", osuapiClientId},
+ {"clientSecret", osuapiClientSecret}
+ };
+
+ return osuapiClientData;
+}
QJsonObject SetupWizard::getTwitchData()
{
@@ -117,6 +129,7 @@ QJsonObject SetupWizard::getOsuircData()
void SetupWizard::saveData(QJsonObject data)
{
QSettings settings;
+ QJsonObject osuapiData = data["osuapi"].toObject();
QJsonObject gosumemoryData = data["gosumemory"].toObject();
QJsonObject twitchData = data["twitch"].toObject();
QJsonObject osuircData = data["osuirc"].toObject();
@@ -124,6 +137,9 @@ void SetupWizard::saveData(QJsonObject data)
settings.setValue("gosumemory/ip", gosumemoryData["ip"].toString());
settings.setValue("gosumemory/port", gosumemoryData["port"].toInt());
+ settings.setValue("osuapi/clientId", osuapiData["clientId"].toInt());
+ settings.setValue("osuapi/clientSecret", osuapiData["clientSecret"].toString());
+
settings.setValue("twitch/botNick", twitchData["botNick"].toString());
settings.setValue("twitch/oauth", twitchData["oauth"].toString());
settings.setValue("twitch/channel", twitchData["channel"].toString());
diff --git a/src/setupwizard/setupwizard.h b/src/setupwizard/setupwizard.h
index 2ec9bfc..ac6016e 100644
--- a/src/setupwizard/setupwizard.h
+++ b/src/setupwizard/setupwizard.h
@@ -29,6 +29,7 @@ private slots:
QJsonObject gatherData();
QJsonObject getGosumemoryData();
+ QJsonObject getOsuApiData();
QJsonObject getTwitchData();
QJsonObject getOsuircData();
void saveData(QJsonObject data);
diff --git a/src/utils/utils.cpp b/src/utils/utils.cpp
index 815c7bb..16656e7 100644
--- a/src/utils/utils.cpp
+++ b/src/utils/utils.cpp
@@ -29,3 +29,18 @@ QStringList Utils::getUrls(QString message)
}
return list;
}
+
+int Utils::getBeatmapIdFromOsuBeatmapLink(QString link)
+{
+ qDebug() << "getBeatmapIdFromOsuBeatmapLink: " << link;
+
+ // https://osu.ppy.sh/beatmapsets/2055856#taiko/4295990
+ QRegularExpression rx("(b=|b/|beatmapsets/\\d+#osu/|beatmapsets/\\d+#taiko/|beatmapsets/\\d+#fruits/|beatmapsets/\\d+#mania/)(\\d+)");
+ QRegularExpressionMatch match = rx.match(link);
+ if (match.hasMatch()) {
+ int id = match.captured(2).toInt();
+ qDebug() << "found beatmap id: " << id;
+ return id;
+ }
+ return -1;
+}
diff --git a/src/utils/utils.h b/src/utils/utils.h
index d660bb2..2feab9f 100644
--- a/src/utils/utils.h
+++ b/src/utils/utils.h
@@ -10,6 +10,7 @@ class Utils
public:
static QStringList getOsuBeatmapUrls(QString message);
static QStringList getUrls(QString message);
+ static int getBeatmapIdFromOsuBeatmapLink(QString link);
};
#endif // UTILS_H