diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/CMakeLists.txt | 3 | ||||
| -rw-r--r-- | src/apiuseraccount.cpp | 67 | ||||
| -rw-r--r-- | src/apiuseraccount.h | 129 | ||||
| -rw-r--r-- | src/mainwindow.cpp | 13 | ||||
| -rw-r--r-- | src/nexusinterface.cpp | 78 | ||||
| -rw-r--r-- | src/nexusinterface.h | 131 | ||||
| -rw-r--r-- | src/nxmaccessmanager.cpp | 17 | ||||
| -rw-r--r-- | src/nxmaccessmanager.h | 7 | ||||
| -rw-r--r-- | src/settingsdialog.cpp | 6 | ||||
| -rw-r--r-- | src/statusbar.cpp | 34 |
10 files changed, 263 insertions, 222 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 71f87a8a..5623a851 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -117,6 +117,7 @@ SET(organizer_SRCS forcedloaddialogwidget.cpp filterwidget.cpp statusbar.cpp + apiuseraccount.cpp shared/windows_error.cpp shared/error_report.cpp @@ -215,6 +216,7 @@ SET(organizer_HDRS forcedloaddialogwidget.h filterwidget.h statusbar.h + apiuseraccount.h shared/windows_error.h shared/error_report.h @@ -299,6 +301,7 @@ set(core nxmaccessmanager organizercore organizerproxy + apiuseraccount ) set(dialogs diff --git a/src/apiuseraccount.cpp b/src/apiuseraccount.cpp new file mode 100644 index 00000000..b901e41a --- /dev/null +++ b/src/apiuseraccount.cpp @@ -0,0 +1,67 @@ +#include "apiuseraccount.h" + +APIUserAccount::APIUserAccount() + : m_type(APIUserAccountTypes::None) +{ +} + +const QString& APIUserAccount::id() const +{ + return m_id; +} + +const QString& APIUserAccount::name() const +{ + return m_name; +} + +APIUserAccountTypes APIUserAccount::type() const +{ + return m_type; +} + +const APILimits& APIUserAccount::limits() const +{ + return m_limits; +} + +APIUserAccount& APIUserAccount::id(const QString& id) +{ + m_id = id; + return *this; +} + +APIUserAccount& APIUserAccount::name(const QString& name) +{ + m_name = name; + return *this; +} + +APIUserAccount& APIUserAccount::type(APIUserAccountTypes type) +{ + m_type = type; + return *this; +} + +APIUserAccount& APIUserAccount::limits(const APILimits& limits) +{ + m_limits = limits; + return *this; +} + +int APIUserAccount::remainingRequests() const +{ + return std::max( + m_limits.remainingDailyRequests, + m_limits.remainingHourlyRequests); +} + +bool APIUserAccount::shouldThrottle() const +{ + return (remainingRequests() < ThrottleThreshold); +} + +bool APIUserAccount::exhausted() const +{ + return (remainingRequests() <= 0); +} diff --git a/src/apiuseraccount.h b/src/apiuseraccount.h new file mode 100644 index 00000000..8a238d71 --- /dev/null +++ b/src/apiuseraccount.h @@ -0,0 +1,129 @@ +#ifndef APIUSERACCOUNT_H +#define APIUSERACCOUNT_H + +#include <QString> + +/** +* represents user account types on a mod provider website such as nexus +*/ +enum class APIUserAccountTypes +{ + // not logged in + None = 0, + + // regular account + Regular, + + // premium account + Premium +}; + + +/** +* current limits imposed on the user account +**/ +struct APILimits +{ + // maximum number of requests per day + int maxDailyRequests = 0; + + // remaining number of requests today + int remainingDailyRequests = 0; + + // maximum number of requests per hour + int maxHourlyRequests = 0; + + // remaining number of requests this hour + int remainingHourlyRequests = 0; +}; + + +/** +* API statistics +*/ +struct APIStats +{ + // number of API requests currently queued + int requestsQueued = 0; +}; + + +/** +* represents a user account on the mod provier website +*/ +class APIUserAccount +{ +public: + // when the number of remanining requests is under this number, further + // requests will be throttled by avoiding non-critical ones + static const int ThrottleThreshold = 200; + + APIUserAccount(); + + /** + * user id + */ + const QString& id() const; + + /** + * user name + */ + const QString& name() const; + + /** + * account type + */ + APIUserAccountTypes type() const; + + /** + * current API limits + */ + const APILimits& limits() const; + + + /** + * sets the user id + */ + APIUserAccount& id(const QString& id); + + /** + * sets the user name + **/ + APIUserAccount& name(const QString& name); + + /** + * sets the acount type + */ + APIUserAccount& type(APIUserAccountTypes type); + + /** + * sets the current limits + */ + APIUserAccount& limits(const APILimits& limits); + + + /** + * returns the number of remaining requests + */ + int remainingRequests() const; + + /** + * whether the number of remaining requests is low enough that further + * requests should be throttled + */ + bool shouldThrottle() const; + + /** + * true if all the remaining requests have been used and the API will refuse + * further requests + */ + bool exhausted() const; + +private: + QString m_id, m_name; + APIUserAccountTypes m_type; + APILimits m_limits; + APIStats m_stats; +}; + +#endif // APIUSERACCOUNT_H diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index c255759b..5018479d 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -225,8 +225,17 @@ MainWindow::MainWindow(QSettings &initSettings QWebEngineProfile::defaultProfile()->setHttpCacheMaximumSize(52428800); QWebEngineProfile::defaultProfile()->setCachePath(m_OrganizerCore.settings().getCacheDirectory()); QWebEngineProfile::defaultProfile()->setPersistentStoragePath(m_OrganizerCore.settings().getCacheDirectory()); + ui->setupUi(this); - updateWindowTitle({}); + + { + auto* ni = NexusInterface::instance(&m_PluginContainer); + + updateWindowTitle(ni->getAPIUserAccount()); + + m_statusBar.reset(new StatusBar(statusBar(), ui)); + m_statusBar->setAPI(ni->getAPIStats(), ni->getAPIUserAccount()); + } languageChange(m_OrganizerCore.settings().language()); @@ -244,8 +253,6 @@ MainWindow::MainWindow(QSettings &initSettings connect(ui->logList->model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)), ui->logList, SLOT(scrollToBottom())); - m_statusBar.reset(new StatusBar(statusBar(), ui)); - updateProblemsButton(); setupToolbar(); diff --git a/src/nexusinterface.cpp b/src/nexusinterface.cpp index 8362143a..ee9acf2c 100644 --- a/src/nexusinterface.cpp +++ b/src/nexusinterface.cpp @@ -49,71 +49,6 @@ void throttledWarning(const APIUserAccount& user) } -APIUserAccount::APIUserAccount() - : m_type(APIUserAccountTypes::None) -{ -} - -const QString& APIUserAccount::id() const -{ - return m_id; -} - -const QString& APIUserAccount::name() const -{ - return m_name; -} - -APIUserAccountTypes APIUserAccount::type() const -{ - return m_type; -} - -const APILimits& APIUserAccount::limits() const -{ - return m_limits; -} - -APIUserAccount& APIUserAccount::id(const QString& id) -{ - m_id = id; - return *this; -} - -APIUserAccount& APIUserAccount::name(const QString& name) -{ - m_name = name; - return *this; -} - -APIUserAccount& APIUserAccount::type(APIUserAccountTypes type) -{ - m_type = type; - return *this; -} - -APIUserAccount& APIUserAccount::limits(const APILimits& limits) -{ - m_limits = limits; - return *this; -} - -int APIUserAccount::remainingRequests() const -{ - return m_limits.remainingDailyRequests + m_limits.remainingHourlyRequests; -} - -bool APIUserAccount::shouldThrottle() const -{ - return (remainingRequests() < ThrottleThreshold); -} - -bool APIUserAccount::exhausted() const -{ - return (remainingRequests() <= 0); -} - - NexusBridge::NexusBridge(PluginContainer *pluginContainer, const QString &subModule) : m_Interface(NexusInterface::instance(pluginContainer)) , m_SubModule(subModule) @@ -325,7 +260,7 @@ void NexusInterface::loginCompleted() void NexusInterface::setUserAccount(const APIUserAccount& user) { m_User = user; - emit requestsChanged(stats(), m_User); + emit requestsChanged(getAPIStats(), m_User); } void NexusInterface::interpretNexusFileName(const QString &fileName, QString &modName, int &modID, bool query) @@ -884,7 +819,7 @@ void NexusInterface::requestFinished(std::list<NXMRequestInfo>::iterator iter) qWarning("All API requests have been consumed and are now being denied."); } - emit requestsChanged(stats(), m_User); + emit requestsChanged(getAPIStats(), m_User); qWarning("Error: %s", reply->errorString().toUtf8().constData()); } else { qWarning("request failed: %s", reply->errorString().toUtf8().constData()); @@ -960,7 +895,7 @@ void NexusInterface::requestFinished(std::list<NXMRequestInfo>::iterator iter) } m_User.limits(parseLimits(reply)); - emit requestsChanged(stats(), m_User); + emit requestsChanged(getAPIStats(), m_User); } else { emit nxmRequestFailed(iter->m_GameName, iter->m_ModID, iter->m_FileID, iter->m_UserData, iter->m_ID, reply->error(), tr("invalid response")); } @@ -1017,7 +952,12 @@ void NexusInterface::requestTimeout() } } -APIStats NexusInterface::stats() const +APIUserAccount NexusInterface::getAPIUserAccount() const +{ + return m_User; +} + +APIStats NexusInterface::getAPIStats() const { APIStats stats; stats.requestsQueued = m_RequestQueue.size(); diff --git a/src/nexusinterface.h b/src/nexusinterface.h index 6c4e8d11..6e768149 100644 --- a/src/nexusinterface.h +++ b/src/nexusinterface.h @@ -20,6 +20,8 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. #ifndef NEXUSINTERFACE_H #define NEXUSINTERFACE_H +#include "apiuseraccount.h" + #include <utility.h> #include <versioninfo.h> #include <imodrepositorybridge.h> @@ -41,130 +43,6 @@ class NXMAccessManager; /** - * represents user account types on a mod provider website such as nexus - */ -enum class APIUserAccountTypes -{ - // not logged in - None = 0, - - // regular account - Regular, - - // premium account - Premium -}; - - -/** - * current limits imposed on the user account - **/ -struct APILimits -{ - // maximum number of requests per day - int maxDailyRequests = 0; - - // remaining number of requests today - int remainingDailyRequests = 0; - - // maximum number of requests per hour - int maxHourlyRequests = 0; - - // remaining number of requests this hour - int remainingHourlyRequests = 0; -}; - - -/** - * API statistics - */ -struct APIStats -{ - // number of API requests currently queued - int requestsQueued = 0; -}; - - -/** - * represents a user account on the mod provier website - */ -class APIUserAccount -{ -public: - // when the number of remanining requests is under this number, further - // requests will be throttled by avoiding non-critical ones - static const int ThrottleThreshold = 300; - - APIUserAccount(); - - /** - * user id - */ - const QString& id() const; - - /** - * user name - */ - const QString& name() const; - - /** - * account type - */ - APIUserAccountTypes type() const; - - /** - * current API limits - */ - const APILimits& limits() const; - - - /** - * sets the user id - */ - APIUserAccount& id(const QString& id); - - /** - * sets the user name - **/ - APIUserAccount& name(const QString& name); - - /** - * sets the acount type - */ - APIUserAccount& type(APIUserAccountTypes type); - - /** - * sets the current limits - */ - APIUserAccount& limits(const APILimits& limits); - - - /** - * returns the number of remaining requests - */ - int remainingRequests() const; - - /** - * whether the number of remaining requests is low enough that further - * requests should be throttled - */ - bool shouldThrottle() const; - - /** - * true if all the remaining requests have been used and the API will refuse - * further requests - */ - bool exhausted() const; - -private: - QString m_id, m_name; - APIUserAccountTypes m_type; - APILimits m_limits; - APIStats m_stats; -}; - - -/** * @brief convenience class to make nxm requests easier * usually, all objects that started a nxm request will be signaled if one finished. * Therefore, the objects need to store the id of the requests they started and then filter @@ -521,6 +399,9 @@ public: std::vector<std::pair<QString, QString>> getGameChoices(const MOBase::IPluginGame *game); + APIUserAccount getAPIUserAccount() const; + APIStats getAPIStats() const; + public: /** @@ -667,8 +548,6 @@ private: MOBase::VersionInfo m_MOVersion; PluginContainer *m_PluginContainer; APIUserAccount m_User; - - APIStats stats() const; }; #endif // NEXUSINTERFACE_H diff --git a/src/nxmaccessmanager.cpp b/src/nxmaccessmanager.cpp index 5886d3ee..ee6c03f1 100644 --- a/src/nxmaccessmanager.cpp +++ b/src/nxmaccessmanager.cpp @@ -190,6 +190,7 @@ void NXMAccessManager::apiCheck(const QString &apiKey, bool force) emit validateSuccessful(false); return; } + m_ApiKey = apiKey; startValidationCheck(); } @@ -218,6 +219,13 @@ QString NXMAccessManager::apiKey() const return m_ApiKey; } +void NXMAccessManager::clearApiKey() +{ + m_ApiKey = ""; + m_ValidateState = VALIDATE_NOT_VALID; + + emit credentialsReceived(APIUserAccount()); +} void NXMAccessManager::validateTimeout() { @@ -233,7 +241,6 @@ void NXMAccessManager::validateTimeout() if (m_ValidateReply != nullptr) { m_ValidateReply->deleteLater(); m_ValidateReply = nullptr; - m_ValidateAttempted = false; // this usually means we might have success later } emit validateFailed(tr("There was a timeout during the request")); @@ -280,17 +287,21 @@ void NXMAccessManager::validateFinished() QString name = credentialsData.value("name").toString(); bool premium = credentialsData.value("is_premium").toBool(); - emit credentialsReceived(APIUserAccount() + const auto user = APIUserAccount() .id(QString("%1").arg(id)) .name(name) .type(premium ? APIUserAccountTypes::Premium : APIUserAccountTypes::Regular) - .limits(NexusInterface::parseLimits(m_ValidateReply))); + .limits(NexusInterface::parseLimits(m_ValidateReply)); + + + emit credentialsReceived(user); m_ValidateReply->deleteLater(); m_ValidateReply = nullptr; m_ValidateState = VALIDATE_VALID; emit validateSuccessful(true); + } else { m_ApiKey.clear(); m_ValidateState = VALIDATE_NOT_VALID; diff --git a/src/nxmaccessmanager.h b/src/nxmaccessmanager.h index 1d23faf9..1bdeae40 100644 --- a/src/nxmaccessmanager.h +++ b/src/nxmaccessmanager.h @@ -20,6 +20,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. #ifndef NXMACCESSMANAGER_H #define NXMACCESSMANAGER_H +#include "apiuseraccount.h" #include <QNetworkAccessManager> #include <QTimer> #include <QNetworkReply> @@ -28,8 +29,6 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. namespace MOBase { class IPluginGame; } -class APIUserAccount; - /** * @brief access manager extended to handle nxm links **/ @@ -56,6 +55,7 @@ public: QString userAgent(const QString &subModule = QString()) const; QString apiKey() const; + void clearApiKey(); void startValidationCheck(); @@ -94,7 +94,6 @@ protected: QIODevice *device); private: - QTimer m_ValidateTimeout; QNetworkReply *m_ValidateReply; QProgressDialog *m_ProgressDialog { nullptr }; @@ -103,7 +102,6 @@ private: QString m_ApiKey; - bool m_ValidateAttempted; enum { VALIDATE_NOT_CHECKED, VALIDATE_CHECKING, @@ -112,7 +110,6 @@ private: VALIDATE_REFUSED, VALIDATE_VALID } m_ValidateState = VALIDATE_NOT_CHECKED; - }; #endif // NXMACCESSMANAGER_H diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index b3e8c8a7..95e4ceb0 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -511,6 +511,9 @@ bool SettingsDialog::clearKey() m_KeyCleared = true; const auto ret = m_settings->clearNexusApiKey(); updateNexusButtons(); + + NexusInterface::instance(m_PluginContainer)->getAccessManager()->clearApiKey(); + return ret; } @@ -522,8 +525,7 @@ void SettingsDialog::testApiKey() return; } - auto* am = NexusInterface::instance(m_PluginContainer)->getAccessManager(); - am->apiCheck(key, true); + NexusInterface::instance(m_PluginContainer)->getAccessManager()->apiCheck(key, true); } void SettingsDialog::updateNexusButtons() diff --git a/src/statusbar.cpp b/src/statusbar.cpp index 4effa6a3..712eb005 100644 --- a/src/statusbar.cpp +++ b/src/statusbar.cpp @@ -48,28 +48,34 @@ void StatusBar::setNotifications(bool hasNotifications) void StatusBar::setAPI(const APIStats& stats, const APIUserAccount& user) { - m_api->setText( - QString("API: Q: %1 | D: %2 | H: %3") - .arg(stats.requestsQueued) - .arg(user.limits().remainingDailyRequests) - .arg(user.limits().remainingHourlyRequests)); - + QString text; QString textColor; QString backgroundColor; if (user.type() == APIUserAccountTypes::None) { - backgroundColor = "transparent"; - } else if (user.remainingRequests() > 300) { + text = "API: not logged in"; textColor = "white"; - backgroundColor = "darkgreen"; - } else if (user.remainingRequests() < 150) { - textColor = "white"; - backgroundColor = "darkred"; + backgroundColor = "transparent"; } else { - textColor = "black"; - backgroundColor = "rgb(226, 192, 0)"; // yellow + text = QString("API: Queued: %1 | Daily: %2 | Hourly: %3") + .arg(stats.requestsQueued) + .arg(user.limits().remainingDailyRequests) + .arg(user.limits().remainingHourlyRequests); + + if (user.remainingRequests() > 500) { + textColor = "white"; + backgroundColor = "darkgreen"; + } else if (user.remainingRequests() > 200) { + textColor = "black"; + backgroundColor = "rgb(226, 192, 0)"; // yellow + } else { + textColor = "white"; + backgroundColor = "darkred"; + } } + m_api->setText(text); + m_api->setStyleSheet(QString(R"( QLabel { |
