diff options
author | Christian Stenger <christian.stenger@qt.io> | 2022-05-12 13:54:00 +0200 |
---|---|---|
committer | Christian Stenger <christian.stenger@qt.io> | 2022-05-31 10:47:11 +0000 |
commit | dd27901759e3f03edfb7926fbd63fc821d509760 (patch) | |
tree | 22bd4bb11e05997f4c75ec4cdc9fd30b7e249a53 /src/plugins/gitlab/gitlabplugin.cpp | |
parent | cd1af2864bf79c4cc8c7b79c4dae0d1ca51402c0 (diff) | |
download | qt-creator-dd27901759e3f03edfb7926fbd63fc821d509760.tar.gz |
GitLab: Allow fetching events
Projects that are linked to a GitLab instance will now fetch
notifications for this project and print them to the vcs output pane.
Change-Id: Ifb960e64b30a260327efb28a3dfd26f6457503a0
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: David Schulz <david.schulz@qt.io>
Diffstat (limited to 'src/plugins/gitlab/gitlabplugin.cpp')
-rw-r--r-- | src/plugins/gitlab/gitlabplugin.cpp | 181 |
1 files changed, 180 insertions, 1 deletions
diff --git a/src/plugins/gitlab/gitlabplugin.cpp b/src/plugins/gitlab/gitlabplugin.cpp index 2a4dd7c69d..5df45c8e68 100644 --- a/src/plugins/gitlab/gitlabplugin.cpp +++ b/src/plugins/gitlab/gitlabplugin.cpp @@ -29,6 +29,8 @@ #include "gitlaboptionspage.h" #include "gitlabparameters.h" #include "gitlabprojectsettings.h" +#include "queryrunner.h" +#include "resultparser.h" #include <coreplugin/actionmanager/actioncontainer.h> #include <coreplugin/actionmanager/actionmanager.h> @@ -36,24 +38,39 @@ #include <git/gitplugin.h> #include <projectexplorer/project.h> #include <projectexplorer/projectpanelfactory.h> +#include <projectexplorer/session.h> #include <utils/qtcassert.h> +#include <vcsbase/vcsoutputwindow.h> #include <QAction> #include <QMessageBox> #include <QPointer> +#include <QTimer> namespace GitLab { namespace Constants { const char GITLAB_OPEN_VIEW[] = "GitLab.OpenView"; } // namespace Constants -class GitLabPluginPrivate +class GitLabPluginPrivate : public QObject { public: GitLabParameters parameters; GitLabOptionsPage optionsPage{¶meters}; QHash<ProjectExplorer::Project *, GitLabProjectSettings *> projectSettings; QPointer<GitLabDialog> dialog; + + QTimer notificationTimer; + QString projectName; + Utils::Id serverId; + bool runningQuery = false; + + void setupNotificationTimer(); + void fetchEvents(); + void fetchUser(); + void createAndSendEventsRequest(const QDateTime timeStamp, int page = -1); + void handleUser(const User &user); + void handleEvents(const Events &events, const QDateTime &timeStamp); }; static GitLabPluginPrivate *dd = nullptr; @@ -93,6 +110,9 @@ bool GitLabPlugin::initialize(const QStringList & /*arguments*/, QString * /*err if (dd->dialog) dd->dialog->updateRemotes(); }); + connect(ProjectExplorer::SessionManager::instance(), + &ProjectExplorer::SessionManager::startupProjectChanged, + this, &GitLabPlugin::onStartupProjectChanged); return true; } @@ -119,6 +139,141 @@ void GitLabPlugin::openView() dd->dialog->raise(); } +void GitLabPlugin::onStartupProjectChanged() +{ + QTC_ASSERT(dd, return); + disconnect(&dd->notificationTimer); + ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject(); + if (!project) { + dd->notificationTimer.stop(); + return; + } + + const GitLabProjectSettings *projSettings = projectSettings(project); + if (!projSettings->isLinked()) { + dd->notificationTimer.stop(); + return; + } + + dd->fetchEvents(); + dd->setupNotificationTimer(); +} + +void GitLabPluginPrivate::setupNotificationTimer() +{ + // make interval configurable? + notificationTimer.setInterval(15 * 60 * 1000); + QObject::connect(¬ificationTimer, &QTimer::timeout, this, &GitLabPluginPrivate::fetchEvents); + notificationTimer.start(); +} + +void GitLabPluginPrivate::fetchEvents() +{ + ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject(); + QTC_ASSERT(project, return); + + if (runningQuery) + return; + + const GitLabProjectSettings *projSettings = GitLabPlugin::projectSettings(project); + projectName = projSettings->currentProject(); + serverId = projSettings->currentServer(); + + const QDateTime lastRequest = projSettings->lastRequest(); + if (!lastRequest.isValid()) { // we haven't queried events for this project yet + fetchUser(); + return; + } + createAndSendEventsRequest(lastRequest); +} + +void GitLabPluginPrivate::fetchUser() +{ + if (runningQuery) + return; + + const Query query(Query::User); + QueryRunner *runner = new QueryRunner(query, serverId, this); + QObject::connect(runner, &QueryRunner::resultRetrieved, this, [this](const QByteArray &result) { + handleUser(ResultParser::parseUser(result)); + }); + QObject::connect(runner, &QueryRunner::finished, [runner]() { runner->deleteLater(); }); + runningQuery = true; + runner->start(); +} + +void GitLabPluginPrivate::createAndSendEventsRequest(const QDateTime timeStamp, int page) +{ + if (runningQuery) + return; + + Query query(Query::Events, {projectName}); + QStringList additional = {"sort=asc"}; + + QDateTime after = timeStamp.addDays(-1); + additional.append(QLatin1String("after=%1").arg(after.toString("yyyy-MM-dd"))); + query.setAdditionalParameters(additional); + + if (page > 1) + query.setPageParameter(page); + + QueryRunner *runner = new QueryRunner(query, serverId, this); + QObject::connect(runner, &QueryRunner::resultRetrieved, this, + [this, timeStamp](const QByteArray &result) { + handleEvents(ResultParser::parseEvents(result), timeStamp); + }); + QObject::connect(runner, &QueryRunner::finished, [runner]() { runner->deleteLater(); }); + runningQuery = true; + runner->start(); +} + +void GitLabPluginPrivate::handleUser(const User &user) +{ + runningQuery = false; + + QTC_ASSERT(user.error.message.isEmpty(), return); + const QDateTime timeStamp = QDateTime::fromString(user.lastLogin, Qt::ISODateWithMs); + createAndSendEventsRequest(timeStamp); +} + +void GitLabPluginPrivate::handleEvents(const Events &events, const QDateTime &timeStamp) +{ + runningQuery = false; + + ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject(); + QTC_ASSERT(project, return); + + GitLabProjectSettings *projSettings = GitLabPlugin::projectSettings(project); + QTC_ASSERT(projSettings->currentProject() == projectName, return); + + if (!projSettings->isLinked()) // link state has changed meanwhile - ignore the request + return; + + if (!events.error.message.isEmpty()) { + VcsBase::VcsOutputWindow::appendError("GitLab: Error while fetching events. " + + events.error.message + '\n'); + return; + } + + QDateTime lastTimeStamp; + for (const Event &event : events.events) { + const QDateTime eventTimeStamp = QDateTime::fromString(event.timeStamp, Qt::ISODateWithMs); + if (!timeStamp.isValid() || timeStamp < eventTimeStamp) { + VcsBase::VcsOutputWindow::appendMessage("GitLab: " + event.toMessage()); + if (!lastTimeStamp.isValid() || lastTimeStamp < eventTimeStamp) + lastTimeStamp = eventTimeStamp; + } + } + if (lastTimeStamp.isValid()) { + if (auto outputWindow = VcsBase::VcsOutputWindow::instance()) + outputWindow->flash(); + projSettings->setLastRequest(lastTimeStamp); + } + + if (events.pageInfo.currentPage < events.pageInfo.totalPages) + createAndSendEventsRequest(timeStamp, events.pageInfo.currentPage + 1); +} + QList<GitLabServer> GitLabPlugin::allGitLabServers() { QTC_ASSERT(dd, return {}); @@ -152,4 +307,28 @@ GitLabOptionsPage *GitLabPlugin::optionsPage() return &dd->optionsPage; } +void GitLabPlugin::linkedStateChanged(bool enabled) +{ + QTC_ASSERT(dd, return); + + ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject(); + if (project) { + const GitLabProjectSettings *pSettings = projectSettings(project); + dd->serverId = pSettings->currentServer(); + dd->projectName = pSettings->currentProject(); + } else { + dd->serverId = Utils::Id(); + dd->projectName = QString(); + } + + if (enabled) { + dd->fetchEvents(); + dd->setupNotificationTimer(); + } else { + QObject::disconnect(&dd->notificationTimer, &QTimer::timeout, + dd, &GitLabPluginPrivate::fetchEvents); + dd->notificationTimer.stop(); + } +} + } // namespace GitLab |