summaryrefslogtreecommitdiff
path: root/src/plugins/gitlab/gitlabplugin.cpp
diff options
context:
space:
mode:
authorChristian Stenger <christian.stenger@qt.io>2022-05-12 13:54:00 +0200
committerChristian Stenger <christian.stenger@qt.io>2022-05-31 10:47:11 +0000
commitdd27901759e3f03edfb7926fbd63fc821d509760 (patch)
tree22bd4bb11e05997f4c75ec4cdc9fd30b7e249a53 /src/plugins/gitlab/gitlabplugin.cpp
parentcd1af2864bf79c4cc8c7b79c4dae0d1ca51402c0 (diff)
downloadqt-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.cpp181
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{&parameters};
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(&notificationTimer, &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