7#include "reviewboardjobs.h"
11#include <QJsonDocument>
12#include <QMimeDatabase>
14#include <QNetworkReply>
15#include <QNetworkRequest>
18#include <KLocalizedString>
21using namespace ReviewBoard;
44QByteArray multipartFormData(
const QList<QPair<QString, QVariant>> &values)
47 for (
const auto &val : values) {
51 hstr +=
"Content-Disposition: form-data; name=\"";
52 hstr += val.
first.toLatin1();
58 hstr +=
"; filename=\"" +
path.fileName().
toLatin1() +
"\"";
60 if (!mime.
name().isEmpty()) {
61 hstr +=
"\r\nContent-Type: ";
62 hstr += mime.
name().toLatin1();
72 form_data += urlToData(val.second.toUrl());
74 form_data += val.second.toByteArray();
80 form_data +=
QByteArray(
"--" + m_boundary +
"--\r\n");
85QByteArray multipartFormData(
const QVariantMap &values)
88 for (QVariantMap::const_iterator it = values.constBegin(), itEnd = values.constEnd(); it != itEnd; ++it) {
89 vals += qMakePair<QString, QVariant>(
QString(it.key()),
QVariant(it.value()));
91 return multipartFormData(vals);
96HttpCall::HttpCall(
const QUrl &s,
98 const QList<QPair<QString, QString>> &queryParameters,
106 , m_multipart(multipart)
112 for (
QList<QPair<QString, QString>>::const_iterator i = queryParameters.
begin(); i < queryParameters.end(); i++) {
113 query.addQueryItem(i->first, i->second);
115 m_requrl.setQuery(query);
118void HttpCall::start()
120 QNetworkRequest r(m_requrl);
122 if (!m_requrl.userName().isEmpty()) {
123 QByteArray head =
"Basic " + m_requrl.userInfo().toLatin1().toBase64();
124 r.setRawHeader(
"Authorization", head);
130 r.setRawHeader(
"Content-Type",
"multipart/form-data; boundary=" + m_boundary);
135 m_reply = m_manager.get(r);
138 m_reply = m_manager.post(r, m_post);
141 m_reply = m_manager.put(r, m_post);
149QVariant HttpCall::result()
const
151 Q_ASSERT(m_reply->isFinished());
155void HttpCall::onFinished()
157 const QByteArray receivedData = m_reply->readAll();
158 QJsonParseError
error;
160 const QVariant output = parser.
toVariant();
162 if (
error.error == 0) {
169 if (output.
toMap().value(QStringLiteral(
"stat")).
toString() != QLatin1String(
"ok")) {
174 if (receivedData.
size() > 10000) {
175 qCDebug(PLUGIN_REVIEWBOARD) <<
"parsing..." << receivedData.
size();
177 qCDebug(PLUGIN_REVIEWBOARD) <<
"parsing..." << receivedData;
182NewRequest::NewRequest(
const QUrl &server,
const QString &projectPath, QObject *parent)
183 : ReviewRequest(server, QString(), parent)
184 , m_project(projectPath)
186 m_newreq =
new HttpCall(this->server(), QStringLiteral(
"/api/review-requests/"), {}, HttpCall::Post,
"repository=" + projectPath.
toLatin1(),
false,
this);
190void NewRequest::start()
195void NewRequest::done()
197 if (m_newreq->error()) {
198 qCDebug(PLUGIN_REVIEWBOARD) <<
"Could not create the new request" << m_newreq->errorString();
200 setErrorText(
i18n(
"Could not create the new request:\n%1", m_newreq->errorString()));
202 QVariant res = m_newreq->result();
203 setRequestId(res.
toMap()[QStringLiteral(
"review_request")].
toMap()[QStringLiteral(
"id")].
toString());
204 Q_ASSERT(!requestId().isEmpty());
210SubmitPatchRequest::SubmitPatchRequest(
const QUrl &server,
const QUrl &patch,
const QString &basedir,
const QString &
id, QObject *parent)
211 : ReviewRequest(server, id, parent)
216 vals += QPair<QString, QVariant>(QStringLiteral(
"basedir"), m_basedir);
219 m_uploadpatch =
new HttpCall(this->server(),
220 QStringLiteral(
"/api/review-requests/") + requestId() + QStringLiteral(
"/diffs/"),
223 multipartFormData(vals),
229void SubmitPatchRequest::start()
231 m_uploadpatch->start();
234void SubmitPatchRequest::done()
236 if (m_uploadpatch->error()) {
237 qCWarning(PLUGIN_REVIEWBOARD) <<
"Could not upload the patch" << m_uploadpatch->errorString();
245ProjectsListRequest::ProjectsListRequest(
const QUrl &server, QObject *parent)
251void ProjectsListRequest::start()
253 requestRepositoryList(0);
256QVariantList ProjectsListRequest::repositories()
const
258 return m_repositories;
261void ProjectsListRequest::requestRepositoryList(
int startIndex)
263 QList<QPair<QString, QString>> repositoriesParameters;
266 repositoriesParameters << qMakePair(QStringLiteral(
"max-results"), QStringLiteral(
"200"));
267 repositoriesParameters << qMakePair(QStringLiteral(
"start"),
QString::number(startIndex));
269 HttpCall *repositoriesCall =
new HttpCall(m_server, QStringLiteral(
"/api/repositories/"), repositoriesParameters, HttpCall::Get, QByteArray(),
false,
this);
272 repositoriesCall->start();
275void ProjectsListRequest::done(KJob *job)
280 const QMap<QString, QVariant> resultMap = repositoriesCall->result().
toMap();
281 const int totalResults = resultMap[QStringLiteral(
"total_results")].toInt();
282 m_repositories << resultMap[QStringLiteral(
"repositories")].toList();
284 if (m_repositories.count() < totalResults) {
285 requestRepositoryList(m_repositories.count());
291ReviewListRequest::ReviewListRequest(
const QUrl &server,
const QString &user,
const QString &reviewStatus, QObject *parent)
295 , m_reviewStatus(reviewStatus)
299void ReviewListRequest::start()
301 requestReviewList(0);
304QVariantList ReviewListRequest::reviews()
const
309void ReviewListRequest::requestReviewList(
int startIndex)
311 QList<QPair<QString, QString>> reviewParameters;
314 reviewParameters << qMakePair(QStringLiteral(
"max-results"), QStringLiteral(
"200"));
315 reviewParameters << qMakePair(QStringLiteral(
"start"),
QString::number(startIndex));
316 reviewParameters << qMakePair(QStringLiteral(
"from-user"), m_user);
317 reviewParameters << qMakePair(QStringLiteral(
"status"), m_reviewStatus);
319 HttpCall *reviewsCall =
new HttpCall(m_server, QStringLiteral(
"/api/review-requests/"), reviewParameters, HttpCall::Get, QByteArray(),
false,
this);
322 reviewsCall->start();
325void ReviewListRequest::done(KJob *job)
330 qCDebug(PLUGIN_REVIEWBOARD) <<
"Could not get reviews list" << job->
errorString();
337 QMap<QString, QVariant> resultMap = reviewsCall->result().
toMap();
338 const int totalResults = resultMap[QStringLiteral(
"total_results")].toInt();
340 m_reviews << resultMap[QStringLiteral(
"review_requests")].toList();
342 if (m_reviews.count() < totalResults) {
343 requestReviewList(m_reviews.count());
349UpdateRequest::UpdateRequest(
const QUrl &server,
const QString &
id,
const QVariantMap &newValues, QObject *parent)
350 : ReviewRequest(server, id, parent)
352 m_req =
new HttpCall(this->server(),
353 QStringLiteral(
"/api/review-requests/") +
id + QStringLiteral(
"/draft/"),
356 multipartFormData(newValues),
362void UpdateRequest::start()
367void UpdateRequest::done()
369 if (m_req->error()) {
370 qCWarning(PLUGIN_REVIEWBOARD) <<
"Could not set all metadata to the review" << m_req->errorString() << m_req->property(
"result");
378#include "moc_reviewboardjobs.cpp"
void setErrorText(const QString &errorText)
virtual QString errorString() const
void setError(int errorCode)
Http call to the specified service.
QString i18n(const char *text, const TYPE &arg...)
char * toString(const EngineQuery &query)
const QVariantMap toMap(const MODEL &model)
KSERVICE_EXPORT KService::List query(FilterFunc filterFunc)
QString path(const QString &relativePath)
KCOREADDONS_EXPORT QString randomString(int length)
QByteArray & append(QByteArrayView data)
QByteArray first(qsizetype n) const const
qsizetype size() const const
QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error)
QVariant toVariant() const const
QMimeType mimeTypeForUrl(const QUrl &url) const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
T qobject_cast(QObject *object)
QString number(double n, char format, int precision)
QByteArray toLatin1() const const
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
bool isLocalFile() const const
void setPath(const QString &path, ParsingMode mode)
QString toLocalFile() const const
QVariant fromValue(T &&value)
QMap< QString, QVariant > toMap() const const