1#include <GitServerCache.h>
2
3#include <GitQlientSettings.h>
4#include <GitConfig.h>
5#include <GitHubRestApi.h>
6#include <GitLabRestApi.h>
7
8#include <Label.h>
9#include <Milestone.h>
10
11using namespace GitServer;
12
13GitServerCache::GitServerCache(QObject *parent)
14 : QObject(parent)
15{
16}
17
18GitServerCache::~GitServerCache() { }
19
20bool GitServerCache::init(const QString &serverUrl, const QPair<QString, QString> &repoInfo)
21{
22 mInit = true;
23
24 GitQlientSettings settings;
25 const auto userName = settings.globalValue(QString("%1/user").arg(serverUrl)).toString();
26 const auto userToken = settings.globalValue(QString("%1/token").arg(serverUrl)).toString();
27 const auto endpoint = settings.globalValue(QString("%1/endpoint").arg(serverUrl)).toString();
28
29 if (serverUrl.contains("github"))
30 mApi.reset(new GitHubRestApi(repoInfo.first, repoInfo.second, { userName, userToken, endpoint }));
31 else if (serverUrl.contains("gitlab"))
32 mApi.reset(new GitLabRestApi(userName, repoInfo.second, serverUrl, { userName, userToken, endpoint }));
33 else
34 {
35 mInit = false;
36 return mInit;
37 }
38
39 connect(getApi(), &IRestApi::labelsReceived, this, &GitServerCache::initLabels);
40 connect(getApi(), &IRestApi::milestonesReceived, this, &GitServerCache::initMilestones);
41 connect(getApi(), &IRestApi::issuesReceived, this, &GitServerCache::initIssues);
42 connect(getApi(), &IRestApi::pullRequestsReceived, this, &GitServerCache::initPullRequests);
43 connect(getApi(), &IRestApi::commentsReceived, this, &GitServerCache::onCommentsReceived);
44 connect(getApi(), &IRestApi::codeReviewsReceived, this, &GitServerCache::onCodeReviewsReceived);
45 connect(getApi(), &IRestApi::commentReviewsReceived, this, &GitServerCache::onCommentReviewsReceived);
46 connect(getApi(), &IRestApi::commitsReceived, this, &GitServerCache::onCommitsReceived);
47 connect(getApi(), &IRestApi::issueUpdated, this, &GitServerCache::onIssueUpdated);
48 connect(getApi(), &IRestApi::pullRequestUpdated, this, &GitServerCache::onPRUpdated);
49 connect(getApi(), &IRestApi::errorOccurred, this, &GitServerCache::errorOccurred);
50 connect(getApi(), &IRestApi::connectionTested, this, &GitServerCache::onConnectionTested);
51
52 mApi->testConnection();
53
54 mWaitingConfirmation = true;
55
56 return mInit;
57}
58
59QString GitServerCache::getUserName() const
60{
61 return mApi->getUserName();
62}
63
64QVector<PullRequest> GitServerCache::getPullRequests() const
65{
66 auto pullRequests = mPullRequests.values();
67
68 std::sort(pullRequests.begin(), pullRequests.end(),
69 [](const PullRequest &p1, const PullRequest &p2) { return p1.creation > p2.creation; });
70
71 return pullRequests.toVector();
72}
73
74void GitServerCache::onConnectionTested()
75{
76 mPreSteps = 3;
77
78 mApi->requestLabels();
79 mApi->requestMilestones();
80 mApi->requestIssues();
81 mApi->requestPullRequests();
82
83 /*
84 connect(mApi.get(), &IRestApi::milestonesReceived, this, [](){});
85 connect(mApi.get(), &IRestApi::milestonesReceived, this, [](){});
86 */
87}
88
89void GitServerCache::onIssueUpdated(const Issue &issue)
90{
91 mIssues[issue.number] = issue;
92
93 emit issueUpdated(issue);
94}
95
96void GitServerCache::onPRUpdated(const PullRequest &pr)
97{
98 mPullRequests[pr.number] = pr;
99
100 emit prUpdated(pr);
101}
102
103void GitServerCache::onCommentsReceived(int number, const QVector<Comment> &comments)
104{
105 if (mIssues.contains(number))
106 {
107 mIssues[number].comments = comments;
108 emit issueUpdated(mIssues[number]);
109 }
110 else if (mPullRequests.contains(number))
111 {
112 mPullRequests[number].comments = comments;
113 emit prReviewsReceived();
114 }
115}
116
117void GitServerCache::onCodeReviewsReceived(int number, const QVector<GitServer::CodeReview> &codeReviews)
118{
119 if (mPullRequests.contains(number))
120 {
121 for (auto &cReview : codeReviews)
122 {
123 if (!mPullRequests[number].reviewComment.contains(cReview))
124 mPullRequests[number].reviewComment.append(cReview);
125 }
126 }
127
128 emit prReviewsReceived();
129}
130
131void GitServerCache::onCommentReviewsReceived(int number, const QMap<int, GitServer::Review> &commentReviews)
132{
133 if (mPullRequests.contains(number))
134 {
135 const auto end = commentReviews.cend();
136
137 for (auto iter = commentReviews.cbegin(); iter != end; ++iter)
138 mPullRequests[number].reviews.insert(iter.key(), iter.value());
139
140 emit prReviewsReceived();
141 }
142}
143
144void GitServerCache::onCommitsReceived(int number, const QVector<GitServer::Commit> &commits, int currentPage,
145 int lastPage)
146{
147 if (mPullRequests.contains(number))
148 {
149 if (currentPage == 1)
150 mPullRequests[number].commits.clear();
151
152 for (auto &commit : commits)
153 {
154 if (!mPullRequests[number].commits.contains(commit))
155 mPullRequests[number].commits.append(commit);
156 }
157 }
158
159 if (currentPage == lastPage)
160 emit prUpdated(mPullRequests[number]);
161}
162
163PullRequest GitServerCache::getPullRequest(const QString &sha) const
164{
165 const auto iter = std::find_if(mPullRequests.constBegin(), mPullRequests.constEnd(),
166 [sha](const GitServer::PullRequest &pr) { return pr.state.sha == sha; });
167
168 if (iter != mPullRequests.constEnd())
169 return *iter;
170
171 return PullRequest();
172}
173
174QVector<Issue> GitServerCache::getIssues() const
175{
176 auto issues = mIssues.values();
177
178 std::sort(issues.begin(), issues.end(), [](const Issue &i1, const Issue &i2) { return i1.creation > i2.creation; });
179
180 return issues.toVector();
181}
182
183GitServer::Platform GitServerCache::getPlatform() const
184{
185 if (dynamic_cast<GitHubRestApi *>(getApi()))
186 return Platform::GitHub;
187
188 return Platform::GitLab;
189}
190
191IRestApi *GitServerCache::getApi() const
192{
193 return mApi.get();
194}
195
196void GitServerCache::initLabels(const QVector<Label> &labels)
197{
198 mLabels = labels;
199
200 triggerSignalConditionally();
201}
202
203void GitServerCache::initMilestones(const QVector<Milestone> &milestones)
204{
205 mMilestones = milestones;
206
207 triggerSignalConditionally();
208}
209
210void GitServerCache::initIssues(const QVector<Issue> &issues)
211{
212 for (auto &issue : issues)
213 mIssues.insert(issue.number, issue);
214
215 triggerSignalConditionally();
216
217 emit issuesReceived();
218}
219
220void GitServerCache::initPullRequests(const QVector<PullRequest> &prs)
221{
222 for (auto &pr : prs)
223 mPullRequests.insert(pr.number, pr);
224
225 triggerSignalConditionally();
226
227 emit prReceived();
228}
229
230void GitServerCache::triggerSignalConditionally()
231{
232 --mPreSteps;
233
234 if (mWaitingConfirmation && mPreSteps == 0)
235 {
236 mWaitingConfirmation = false;
237 mPreSteps = -1;
238 emit connectionTested();
239 }
240}
241