1 #include "confluence-agent.h"
6 #include <iostream> // FIXME-2 for debugging...
8 #include "branchitem.h"
9 #include "confluence-user.h"
11 #include "mainwindow.h"
14 #include "warningdialog.h"
16 extern Main *mainWindow;
17 extern QDir vymBaseDir;
18 extern QString confluencePassword;
19 extern Settings settings;
22 bool ConfluenceAgent::available()
24 if (!QSslSocket::supportsSsl())
26 if ( settings.value("/atlassian/confluence/username", "").toString().isEmpty())
29 if ( settings.value("/atlassian/confluence/url", "").toString().isEmpty())
35 ConfluenceAgent::ConfluenceAgent() {
36 //qDebug() << "Constr. ConfluenceAgent jobType=";
40 ConfluenceAgent::ConfluenceAgent(BranchItem *bi)
42 //qDebug() << "Constr. ConfluenceAgent selbi = " << bi;
45 qWarning("Const ConfluenceAgent: bi == nullptr");
46 // This will leave the agent hanging around undeleted...
55 ConfluenceAgent::~ConfluenceAgent()
57 // qDebug() << "Destr ConfluenceAgent." << jobType;
62 void ConfluenceAgent::init()
70 networkManager = new QNetworkAccessManager(this);
72 modelID = 0; // invalid ID
74 killTimer = new QTimer(this);
75 killTimer->setInterval(15000);
76 killTimer->setSingleShot(true);
78 QObject::connect(killTimer, SIGNAL(timeout()), this, SLOT(timeout()));
80 apiURL = baseURL + "/rest/api";
81 baseURL = settings.value("/atlassian/confluence/url", "baseURL").toString();
84 attachmentsAgent = nullptr;
85 currentUploadAttachmentIndex = -1;
89 settings.value("/atlassian/confluence/authUsingPAT", true).toBool();
92 settings.value("/atlassian/confluence/PAT", "undefined").toString();
95 settings.value("/atlassian/confluence/username", "user_johnDoe").toString();
96 if (!confluencePassword.isEmpty())
97 password = confluencePassword;
100 settings.value("/atlassian/confluence/password", "").toString();
103 if (!authUsingPAT && password.isEmpty()) {
104 // Set global password
105 if (!mainWindow->settingsConfluence())
110 void ConfluenceAgent::setJobType(JobType jt)
115 void ConfluenceAgent::setBranch(BranchItem *bi)
118 qWarning() << "ConfluenceAgent::setBranch bi == nullptr";
121 branchID = bi->getID();
122 VymModel *model = bi->getModel();
123 modelID = model->getModelID();
127 void ConfluenceAgent::setModelID(uint id)
132 void ConfluenceAgent::setPageURL(const QString &u)
137 void ConfluenceAgent::setNewPageName(const QString &t)
142 void ConfluenceAgent::setUploadPagePath(const QString &fp)
147 void ConfluenceAgent::addUploadAttachmentPath(const QString &fp)
149 uploadAttachmentPaths << fp;
152 void ConfluenceAgent::startJob()
155 unknownStepWarningFinishJob();
162 void ConfluenceAgent::continueJob(int nextStep)
176 // qDebug() << "CA::contJob " << jobType << " Step: " << jobStep;
179 case CopyPagenameToHeading:
181 startGetPageSourceRequest(pageURL);
185 startGetPageDetailsRequest();
189 model = mainWindow->getModel(modelID);
191 BranchItem *bi = (BranchItem *)(model->findID(branchID));
194 QString h = spaceKey + ": " + pageObj["title"].toString();
195 model->setHeading(h, bi);
197 qWarning() << "CA::continueJob couldn't find branch "
200 qWarning() << "CA::continueJob couldn't find model " << modelID;
204 unknownStepWarningFinishJob();
209 if (pageURL.isEmpty()) {
210 qWarning() << "CA::contJob NewPage: pageURL is empty";
214 if (newPageName.isEmpty()) {
215 qWarning() << "CA::contJob NewPage: newPageName is empty";
220 mainWindow->statusMessage(
221 QString("Starting to create Confluence page %1").arg(pageURL));
223 // Check if parent page with url already exists and get pageID, spaceKey
224 startGetPageSourceRequest(pageURL);
228 // Create new page with parent url
229 startCreatePageRequest();
234 pageID = pageObj["id"].toString();
236 // Upload attachments?
237 if (uploadAttachmentPaths.count() > 0) {
238 attachmentsAgent = new ConfluenceAgent;
239 attachmentsAgent->setJobType(ConfluenceAgent::UploadAttachments);
240 attachmentsAgent->pageID = pageID;
241 attachmentsAgent->uploadAttachmentPaths = uploadAttachmentPaths;
243 connect(attachmentsAgent, &ConfluenceAgent::attachmentsSuccess,
244 this, &ConfluenceAgent::attachmentsUploadSuccess);
245 connect(attachmentsAgent, &ConfluenceAgent::attachmentsFailure,
246 this, &ConfluenceAgent::attachmentsUploadFailure);
247 attachmentsAgent->startJob();
250 // Proceed to next step
254 //qDebug() << "CA::finished Created page with ID: " << pageObj["id"].toString();
255 mainWindow->statusMessage(
256 QString("Created Confluence page %1").arg(pageURL));
260 unknownStepWarningFinishJob();
265 if (pageURL.isEmpty()) {
266 qWarning() << "CA::contJob UpdatePage: pageURL is empty";
271 mainWindow->statusMessage(
272 QString("Starting to update Confluence page %1").arg(pageURL));
274 // Check if page with url already exists and get pageID, spaceKey
275 startGetPageSourceRequest(pageURL);
279 // Get title, which is required by Confluence to update a page
280 startGetPageDetailsRequest();
284 // Upload attachments?
285 if (uploadAttachmentPaths.count() > 0) {
286 attachmentsAgent = new ConfluenceAgent;
287 attachmentsAgent->setJobType(ConfluenceAgent::UploadAttachments);
288 attachmentsAgent->pageID = pageID;
289 attachmentsAgent->uploadAttachmentPaths = uploadAttachmentPaths;
291 connect(attachmentsAgent, &ConfluenceAgent::attachmentsSuccess,
292 this, &ConfluenceAgent::attachmentsUploadSuccess);
293 connect(attachmentsAgent, &ConfluenceAgent::attachmentsFailure,
294 this, &ConfluenceAgent::attachmentsUploadFailure);
295 attachmentsAgent->startJob();
300 // Update page with parent url
301 if (newPageName.isEmpty())
302 newPageName = pageObj["title"].toString();
303 startUpdatePageRequest();
307 //qDebug() << "CA::finished Updated page with ID: " << pageObj["id"].toString();
308 mainWindow->statusMessage(
309 QString("Updated Confluence page %1").arg(pageURL));
313 unknownStepWarningFinishJob();
318 // qDebug() << "CA:: begin getting UserInfo";
319 startGetUserInfoRequest();
323 QJsonArray array = pageObj["results"].toArray();
328 for (int i = 0; i < array.size(); ++i) {
329 userObj = array[i].toObject();
331 u = userObj["user"].toObject();
332 user.setTitle( userObj["title"].toString());
333 user.setURL( "https://" + baseURL + "/"
334 + "display/~" + u["username"].toString());
335 user.setUserKey( u["userKey"].toString());
336 user.setUserName( u["username"].toString());
337 user.setDisplayName( u["displayName"].toString());
340 emit (foundUsers(userList));
344 unknownStepWarningFinishJob();
347 case UploadAttachments:
350 if (uploadAttachmentPaths.count() <= 0) {
351 qWarning() << "ConfluenceAgent: No attachments to upload!";
352 emit(attachmentsFailure());
357 // Prepare to upload first attachment in list
358 currentUploadAttachmentIndex = 0;
360 // Try to get info for attachments
361 startGetAttachmentsInfoRequest();
365 // Entry point for looping over list of attachments to upload
367 if (currentUploadAttachmentIndex >= uploadAttachmentPaths.count()) {
368 // All uploaded, let's finish uploading
369 emit(attachmentsSuccess());
372 currentAttachmentPath = uploadAttachmentPaths.at(currentUploadAttachmentIndex);
373 currentAttachmentTitle = basename(currentAttachmentPath);
375 // Create attachment with image of map, if required
376 if (attachmentsTitles.count() == 0 ||
377 !attachmentsTitles.contains(currentAttachmentTitle)) {
378 // Create new attachment
379 startCreateAttachmentRequest();
381 // Update existing attachment
382 startUpdateAttachmentRequest();
387 unknownStepWarningFinishJob();
391 qWarning() << "ConfluenceAgent::continueJob unknown jobType " << jobType;
395 void ConfluenceAgent::finishJob()
400 void ConfluenceAgent::unknownStepWarningFinishJob()
402 qWarning() << "CA::contJob unknow step in jobType = "
404 << "jobStep = " << jobStep;
408 void ConfluenceAgent::getUsers(const QString &usrQuery)
410 userQuery = usrQuery;
411 if (usrQuery.contains(QRegExp("\\W+"))) {
412 qWarning() << "ConfluenceAgent::getUsers Forbidden characters in " << usrQuery;
416 setJobType(GetUserInfo);
420 QNetworkRequest ConfluenceAgent::createRequest(const QUrl &url)
422 QNetworkRequest request = QNetworkRequest(url);
426 headerData = QString("Bearer %1").arg(personalAccessToken);
428 QString concatenated = username + ":" + password;
429 QByteArray data = concatenated.toLocal8Bit().toBase64();
430 headerData = "Basic " + data;
432 request.setRawHeader("Authorization", headerData.toLocal8Bit());
437 void ConfluenceAgent::startGetPageSourceRequest(QUrl requestedURL)
439 //qDebug() << "CA::startGetPageSourceRequest " << requestedURL;
440 if (!requestedURL.toString().startsWith("http"))
441 requestedURL.setPath("https://" + requestedURL.path());
443 QUrl url = requestedURL;
445 QNetworkRequest request = createRequest(url);
448 qDebug() << "CA::startGetPageSourceRequest: url = " + request.url().toString();
452 connect(networkManager, &QNetworkAccessManager::finished,
453 this, &ConfluenceAgent::pageSourceReceived);
455 networkManager->get(request);
458 void ConfluenceAgent::pageSourceReceived(QNetworkReply *reply)
460 if (debug) qDebug() << "CA::pageSourceReceived";
463 networkManager->disconnect();
464 reply->deleteLater();
466 QByteArray fullReply = reply->readAll();
467 if (!wasRequestSuccessful(reply, "receive page source", fullReply))
471 QRegExp rx("\\sname=\"ajs-page-id\"\\scontent=\"(\\d*)\"");
474 if (rx.indexIn(fullReply, 0) != -1) {
479 << "ConfluenceAgent::pageSourceReveived Couldn't find page ID";
480 //qWarning() << fullReply;
485 rx.setPattern("meta\\s*id=\"confluence-space-key\"\\s* "
486 "name=\"confluence-space-key\"\\s*content=\"(.*)\"");
487 if (rx.indexIn(fullReply, 0) != -1) {
488 spaceKey = rx.cap(1);
491 qWarning() << "ConfluenceAgent::pageSourceReveived Couldn't find "
492 "space key in response";
493 qWarning() << fullReply;
498 const QVariant redirectionTarget =
499 reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
504 void ConfluenceAgent::startGetPageDetailsRequest()
506 if (debug) qDebug() << "CA::startGetPageDetailsRequest" << pageID;
508 // Authentication in URL (only SSL!)
509 QString url = "https://"
511 + "/content/" + pageID + "?expand=metadata.labels,version";
513 QNetworkRequest request = createRequest(url);
515 connect(networkManager, &QNetworkAccessManager::finished,
516 this, &ConfluenceAgent::pageDetailsReceived);
520 networkManager->get(request);
523 void ConfluenceAgent::pageDetailsReceived(QNetworkReply *reply)
525 if (debug) qDebug() << "CA::pageDetailsReceived";
528 networkManager->disconnect();
529 reply->deleteLater();
531 QByteArray fullReply = reply->readAll();
532 if (!wasRequestSuccessful(reply, "receive page details", fullReply))
536 jsdoc = QJsonDocument::fromJson(fullReply);
538 pageObj = jsdoc.object();
539 // cout << jsdoc.toJson(QJsonDocument::Indented).toStdString();
544 void ConfluenceAgent::startCreatePageRequest()
546 // qDebug() << "CA::startCreatePageRequest";
548 QString url = "https://" + baseURL + apiURL + "/content";
550 QNetworkRequest request = createRequest(url);
551 request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
554 payload["type"] = "page";
555 payload["title"] = newPageName;
557 // Build array with ID of parent page
558 QJsonObject ancestorsID;
559 ancestorsID["id"] = pageID;
560 QJsonArray ancestorsArray;
561 ancestorsArray.append(ancestorsID);
562 payload["ancestors"] = ancestorsArray;
564 // Build object with space key
566 skey["key"] = spaceKey;
567 payload["space"] = skey;
571 if (!loadStringFromDisk(uploadPagePath, body))
573 qWarning() << "ConfluenceAgent: Couldn't read file to upload:" << uploadPagePath;
578 QJsonObject innerStorageObj
581 {"representation", "storage"}
583 QJsonObject outerStorageObj;
584 outerStorageObj["storage"] = innerStorageObj;
585 payload["body"] = outerStorageObj;
587 QJsonDocument doc(payload);
588 QByteArray data = doc.toJson();
590 connect(networkManager, &QNetworkAccessManager::finished,
591 this, &ConfluenceAgent::pageUploaded);
595 networkManager->post(request, data);
598 void ConfluenceAgent::startUpdatePageRequest()
600 if (debug) qDebug() << "CA::startUpdatePageRequest";
602 QString url = "https://" + baseURL + apiURL + "/content" + "/" + pageID;
604 QNetworkRequest request = createRequest(url);
607 QNetworkRequest::ContentTypeHeader,
608 "application/json; charset=utf-8");
611 payload["id"] = pageID;
612 payload["type"] = "page";
613 payload["title"] = newPageName;
615 // Build version object
616 QJsonObject newVersionObj;
617 QJsonObject oldVersionObj = pageObj["version"].toObject();
619 newVersionObj["number"] = oldVersionObj["number"].toInt() + 1;
620 payload["version"] = newVersionObj;
622 // Build object with space key
624 skey["key"] = spaceKey;
625 payload["space"] = skey;
629 if (!loadStringFromDisk(uploadPagePath, body))
631 qWarning() << "ConfluenceAgent: Couldn't read file to upload:" << uploadPagePath;
636 QJsonObject innerStorageObj
639 {"representation", "storage"}
641 QJsonObject outerStorageObj;
642 outerStorageObj["storage"] = innerStorageObj;
643 payload["body"] = outerStorageObj;
645 QJsonDocument doc(payload);
646 QByteArray data = doc.toJson();
648 connect(networkManager, &QNetworkAccessManager::finished,
649 this, &ConfluenceAgent::pageUploaded);
653 networkManager->put(request, data);
656 void ConfluenceAgent::pageUploaded(QNetworkReply *reply)
658 if (debug) qDebug() << "CA::pageUploaded";
661 networkManager->disconnect();
662 reply->deleteLater();
664 QByteArray fullReply = reply->readAll();
665 if (!wasRequestSuccessful(reply, "upload page", fullReply))
669 jsdoc = QJsonDocument::fromJson(fullReply);
670 pageObj = jsdoc.object();
671 //cout << jsdoc.toJson(QJsonDocument::Indented).toStdString();
675 void ConfluenceAgent::startGetUserInfoRequest()
677 if (debug) qDebug() << "CA::startGetInfoRequest for " << userQuery;
679 QString url = "https://" + baseURL + apiURL
680 + "/search?cql=user.fullname~" + userQuery;
682 networkManager->disconnect();
684 QNetworkRequest request = createRequest(url);
686 connect(networkManager, &QNetworkAccessManager::finished,
687 this, &ConfluenceAgent::userInfoReceived);
691 networkManager->get(request);
694 void ConfluenceAgent::userInfoReceived(QNetworkReply *reply)
696 if (debug) qDebug() << "CA::UserInfopageReceived";
699 networkManager->disconnect();
700 reply->deleteLater();
702 QByteArray fullReply = reply->readAll();
703 if (!wasRequestSuccessful(reply, "receive user info", fullReply))
707 jsdoc = QJsonDocument::fromJson(fullReply);
708 pageObj = jsdoc.object();
712 void ConfluenceAgent::startGetAttachmentsInfoRequest()
714 if (debug) qDebug() << "CA::startGetAttachmentIdRequest";
716 QString url = "https://" + baseURL + apiURL + "/content" + "/" + pageID + "/child/attachment";
718 QNetworkRequest request = createRequest(url);
719 request.setRawHeader("X-Atlassian-Token", "no-check");
721 connect(networkManager, &QNetworkAccessManager::finished,
722 this, &ConfluenceAgent::attachmentsInfoReceived);
726 QNetworkReply *reply = networkManager->get(request);
729 void ConfluenceAgent::attachmentsInfoReceived(QNetworkReply *reply)
731 if (debug) qDebug() << "CA::attachmentsInfoReceived";
734 networkManager->disconnect();
735 reply->deleteLater();
737 QByteArray fullReply = reply->readAll();
738 if (!wasRequestSuccessful(reply, "get attachment info", fullReply))
742 jsdoc = QJsonDocument::fromJson(fullReply);
744 attachmentObj = jsdoc.object();
745 int attachmentsCount = jsdoc["size"].toInt();
746 //cout << jsdoc.toJson(QJsonDocument::Indented).toStdString();
747 for (int i = 0; i < attachmentsCount; i++) {
748 attachmentsTitles << jsdoc["results"][i]["title"].toString();
749 attachmentsIds << jsdoc["results"][i]["id"].toString();
750 //qDebug() << " Title: " << attachmentsTitles.last() <<
751 // " Id: " << attachmentsIds.last();
757 void ConfluenceAgent::startCreateAttachmentRequest()
759 if (debug) qDebug() << "CA::startCreateAttachmentRequest";
761 QString url = "https://" + baseURL + apiURL + "/content" + "/" + pageID + "/child/attachment";
763 QNetworkRequest request = createRequest(url);
764 request.setRawHeader("X-Atlassian-Token", "no-check");
766 QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
771 QNetworkRequest::ContentDispositionHeader,
773 // Name must be "file"
775 QString("form-data; name=\"file\"; filename=\"%1\"")
776 .arg(currentAttachmentTitle)));
778 QNetworkRequest::ContentTypeHeader,
779 QVariant("image/jpeg"));
781 QFile *file = new QFile(currentAttachmentPath);
782 if (!file->open(QIODevice::ReadOnly)) {
783 qWarning() << "Problem opening attachment: " << currentAttachmentPath;
784 QMessageBox::warning(
785 nullptr, tr("Warning"),
786 QString("Could not open attachment file \"%1\" in page with ID: %2").arg(currentAttachmentTitle).arg(pageID));
790 imagePart.setBodyDevice(file);
792 qDebug() << " title=" << currentAttachmentTitle;
793 qDebug() << " path=" << currentAttachmentPath;
794 qDebug() << " url=" << url;
795 qDebug() << " file size=" << file->size();
797 multiPart->append(imagePart);
798 file->setParent(multiPart); // delete later with the multiPart
800 connect(networkManager, &QNetworkAccessManager::finished,
801 this, &ConfluenceAgent::attachmentCreated);
805 QNetworkReply *reply = networkManager->post(request, multiPart);
807 multiPart->setParent(reply);
810 void ConfluenceAgent::attachmentCreated(QNetworkReply *reply)
812 if (debug) qDebug() << "CA::attachmentCreated";
815 networkManager->disconnect();
816 reply->deleteLater();
818 QByteArray fullReply = reply->readAll();
819 if (reply->error() == QNetworkReply::ProtocolInvalidOperationError) {
820 if (fullReply.contains(
821 QString("Cannot add a new attachment with same file name as an existing attachment").toLatin1())) {
822 // Replace existing attachment
823 qWarning() << "Attachment with name " << currentAttachmentTitle << " already exists.";
824 qWarning() << "AttachmentID unknown, stopping now";
829 if (!wasRequestSuccessful(reply, "create attachment", fullReply))
834 jsdoc = QJsonDocument::fromJson(fullReply);
835 attachmentObj = jsdoc.object();
837 //qDebug() << "CA::attachmentCreated Successful:";
838 //cout << jsdoc.toJson(QJsonDocument::Indented).toStdString();
839 //cout << attachmentObj["results"].toArray().toStdString();
841 currentUploadAttachmentIndex++;
846 void ConfluenceAgent::startUpdateAttachmentRequest()
848 if (debug) qDebug() << "CA::startUpdateAttachmentRequest";
850 for (int i = 0; i < attachmentsTitles.count(); i++) {
851 // qDebug() << " - " << attachmentsTitles.at(i);
852 if (attachmentsTitles.at(i) == currentAttachmentTitle) {
853 currentAttachmentId = attachmentsIds.at(i);
858 if (currentAttachmentId.isEmpty()) {
859 QMessageBox::warning(
860 nullptr, tr("Warning"),
861 QString("Could not find existing attachment \"%1\" in page with ID: %2").arg(currentAttachmentTitle).arg(pageID));
866 QString url = "https://" + baseURL + apiURL + "/content" + "/" + pageID + "/child/attachment/" + currentAttachmentId + "/data";
868 QNetworkRequest request = createRequest(url);
869 request.setRawHeader("X-Atlassian-Token", "no-check");
871 QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
875 QNetworkRequest::ContentDispositionHeader,
877 // Name must be "file"
879 QString("form-data; name=\"file\"; filename=\"%1\"")
880 .arg(currentAttachmentTitle)));
882 QNetworkRequest::ContentTypeHeader,
883 QVariant("image/jpeg"));
885 QFile *file = new QFile(currentAttachmentPath);
886 if (!file->open(QIODevice::ReadOnly)) {
887 qWarning() << "Problem opening attachment: " << currentAttachmentPath;
888 QMessageBox::warning(
889 nullptr, tr("Warning"),
890 QString("Could not open attachment file \"%1\" in page with ID: %2").arg(currentAttachmentTitle).arg(pageID));
894 imagePart.setBodyDevice(file);
896 qDebug() << " title=" << currentAttachmentTitle;
897 qDebug() << " path=" << currentAttachmentPath;
898 qDebug() << " url=" << url;
899 qDebug() << " file size=" << file->size();
901 multiPart->append(imagePart);
902 file->setParent(multiPart);
904 connect(networkManager, &QNetworkAccessManager::finished,
905 this, &ConfluenceAgent::attachmentUpdated);
909 QNetworkReply *reply = networkManager->post(request, multiPart);
911 multiPart->setParent(reply);
914 void ConfluenceAgent::attachmentUpdated(QNetworkReply *reply)
916 if (debug) qDebug() << "CA::attachmentUpdated";
919 networkManager->disconnect();
920 reply->deleteLater();
922 QByteArray fullReply = reply->readAll();
923 if (!wasRequestSuccessful(reply, "update attachment", fullReply))
927 jsdoc = QJsonDocument::fromJson(fullReply);
928 attachmentObj = jsdoc.object();
930 //cout << jsdoc.toJson(QJsonDocument::Indented).toStdString();
932 currentUploadAttachmentIndex++;
937 void ConfluenceAgent::attachmentsUploadSuccess() // slot called from attachmentsAgent
942 void ConfluenceAgent::attachmentsUploadFailure() // slot called from attachmentsAgent
944 qWarning() << "CA::attachmentsUpload failed";
948 bool ConfluenceAgent::wasRequestSuccessful(QNetworkReply *reply, const QString &requestDesc, const QByteArray &fullReply)
950 if (reply->error()) {
952 // Additionally print full error on console
953 qWarning() << " Step: " << requestDesc;
954 qWarning() << " Error: " << reply->error();
955 qWarning() << " Errorstring: " << reply->errorString();
957 qDebug() << " Request Url: " << reply->url() ;
958 qDebug() << " Operation: " << reply->operation() ;
960 qDebug() << " readAll: ";
962 jsdoc = QJsonDocument::fromJson(fullReply);
963 QString fullReplyFormatted = QString(jsdoc.toJson(QJsonDocument::Indented));
964 cout << fullReplyFormatted.toStdString();
967 qDebug() << "Request headers: ";
968 QList<QByteArray> reqHeaders = reply->rawHeaderList();
969 foreach( QByteArray reqName, reqHeaders )
971 QByteArray reqValue = reply->rawHeader( reqName );
972 qDebug() << " " << reqName << ": " << reqValue;
976 if (reply->error() == QNetworkReply::AuthenticationRequiredError)
977 QMessageBox::warning(
978 nullptr, tr("Warning"),
979 tr("Authentication problem when contacting Confluence") + "\n\n" +
982 QString msg = QString("QNetworkReply error when trying to \"%1\"\n\n").arg(requestDesc);
984 warn.setText(msg + "\n\n" + fullReplyFormatted);
985 warn.showCancelButton(false);
995 void ConfluenceAgent::timeout()
997 qWarning() << "ConfluenceAgent timeout!! jobType = " << jobType;
1001 void ConfluenceAgent::sslErrors(QNetworkReply *reply, const QList<QSslError> &errors)
1003 QString errorString;
1004 foreach (const QSslError &error, errors) {
1005 if (!errorString.isEmpty())
1006 errorString += '\n';
1007 errorString += error.errorString();
1010 reply->ignoreSslErrors();
1011 qWarning() << "ConfluenceAgent: One or more SSL errors has occurred: " << errorString;
1012 qWarning() << "Errors ignored.";