diff --git a/core/dplugins/generic/webservices/pinterest/pplugin.h b/core/dplugins/generic/webservices/pinterest/pplugin.h index 68c94760c4..52ab67b1a0 100644 --- a/core/dplugins/generic/webservices/pinterest/pplugin.h +++ b/core/dplugins/generic/webservices/pinterest/pplugin.h @@ -1,71 +1,71 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2018-07-30 * Description : a plugin to export to Pinterest web-service. * * Copyright (C) 2018-2019 by Gilles Caulier * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ #ifndef DIGIKAM_P_PLUGIN_H #define DIGIKAM_P_PLUGIN_H // Local includes #include "dplugingeneric.h" #define DPLUGIN_IID "org.kde.digikam.plugin.generic.Pinterest" using namespace Digikam; namespace DigikamGenericPinterestPlugin { class PWindow; class PPlugin : public DPluginGeneric { Q_OBJECT Q_PLUGIN_METADATA(IID DPLUGIN_IID) Q_INTERFACES(Digikam::DPluginGeneric) public: explicit PPlugin(QObject* const parent = nullptr); ~PPlugin(); QString name() const override; QString iid() const override; QIcon icon() const override; QString details() const override; QString description() const override; QList authors() const override; - void setup(QObject* const) override; - void cleanUp() override; + void setup(QObject* const) override; + void cleanUp() override; private Q_SLOTS: void slotPinterest(); private: QPointer m_toolDlg; }; } // namespace DigikamGenericPinterestPlugin #endif // DIGIKAM_P_PLUGIN_H diff --git a/core/dplugins/generic/webservices/pinterest/ptalker.cpp b/core/dplugins/generic/webservices/pinterest/ptalker.cpp index 441e43483f..dcfc3add40 100644 --- a/core/dplugins/generic/webservices/pinterest/ptalker.cpp +++ b/core/dplugins/generic/webservices/pinterest/ptalker.cpp @@ -1,619 +1,645 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2018-05-20 * Description : a tool to export images to Pinterest web service * * Copyright (C) 2018 by Tarek Talaat * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ #include "ptalker.h" // Qt includes #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // KDE includes #include #include // Local includes #include "digikam_config.h" #include "digikam_debug.h" #include "digikam_version.h" #include "wstoolutils.h" #include "pwindow.h" #include "pitem.h" #include "previewloadthread.h" #ifdef HAVE_QWEBENGINE # include "webwidget_qwebengine.h" #else # include "webwidget.h" #endif namespace DigikamGenericPinterestPlugin { class Q_DECL_HIDDEN PTalker::Private { public: enum State { P_USERNAME = 0, P_LISTBOARDS, P_CREATEBOARD, P_ADDPIN, P_ACCESSTOKEN }; public: explicit Private() { clientId = QLatin1String("4983380570301022071"); clientSecret = QLatin1String("2a698db679125930d922a2dfb897e16b668a67c6f614593636e83fc3d8d9b47d"); authUrl = QLatin1String("https://api.pinterest.com/oauth/"); tokenUrl = QLatin1String("https://api.pinterest.com/v1/oauth/token"); redirectUrl = QLatin1String("https://login.live.com/oauth20_desktop.srf"); scope = QLatin1String("read_public,write_public"); serviceName = QLatin1String("Pinterest"); serviceKey = QLatin1String("access_token"); state = P_USERNAME; parent = nullptr; netMngr = nullptr; reply = nullptr; settings = nullptr; view = nullptr; } public: QString clientId; QString clientSecret; QString authUrl; QString tokenUrl; QString redirectUrl; QString accessToken; QString scope; QString userName; QString serviceName; QString serviceKey; QWidget* parent; QNetworkAccessManager* netMngr; QNetworkReply* reply; QSettings* settings; State state; DMetadata meta; QMap urlParametersMap; WebWidget* view; }; PTalker::PTalker(QWidget* const parent) : d(new Private) { d->parent = parent; d->netMngr = new QNetworkAccessManager(this); d->view = new WebWidget(d->parent); d->view->resize(800, 600); d->settings = WSToolUtils::getOauthSettings(this); #ifndef HAVE_QWEBENGINE d->view->settings()->setAttribute(QWebSettings::LocalStorageEnabled, true); #endif connect(d->netMngr, SIGNAL(finished(QNetworkReply*)), this, SLOT(slotFinished(QNetworkReply*))); connect(this, SIGNAL(pinterestLinkingFailed()), this, SLOT(slotLinkingFailed())); connect(this, SIGNAL(pinterestLinkingSucceeded()), this, SLOT(slotLinkingSucceeded())); connect(d->view, SIGNAL(urlChanged(QUrl)), this, SLOT(slotCatchUrl(QUrl))); connect(d->view, SIGNAL(closeView(bool)), this, SIGNAL(signalBusy(bool))); } PTalker::~PTalker() { if (d->reply) { d->reply->abort(); } WSToolUtils::removeTemporaryDir("pinterest"); delete d; } void PTalker::link() { emit signalBusy(true); QUrl url(d->authUrl); QUrlQuery query(url); query.addQueryItem(QLatin1String("client_id"), d->clientId); query.addQueryItem(QLatin1String("scope"), d->scope); query.addQueryItem(QLatin1String("redirect_uri"), d->redirectUrl); query.addQueryItem(QLatin1String("response_type"), QLatin1String("code")); url.setQuery(query); d->view->setWindowFlags(Qt::Dialog); d->view->load(url); d->view->show(); } void PTalker::unLink() { d->accessToken = QString(); d->settings->beginGroup(d->serviceName); d->settings->remove(QString()); d->settings->endGroup(); #ifdef HAVE_QWEBENGINE d->view->page()->profile()->cookieStore()->deleteAllCookies(); #else d->view->page()->networkAccessManager()->setCookieJar(new QNetworkCookieJar()); #endif emit pinterestLinkingSucceeded(); } void PTalker::slotCatchUrl(const QUrl& url) { d->urlParametersMap = ParseUrlParameters(url.toString()); QString code = d->urlParametersMap.value(QLatin1String("code")); qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Received URL from webview in link function: " << url ; if (!code.isEmpty()) { qCDebug(DIGIKAM_WEBSERVICES_LOG) << "CODE Received"; d->view->close(); getToken(code); emit signalBusy(false); } } void PTalker::getToken(const QString& code) { qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Code: " << code; QUrl url(d->tokenUrl); QUrlQuery query(url); query.addQueryItem(QLatin1String("grant_type"), QLatin1String("authorization_code")); query.addQueryItem(QLatin1String("client_id"), d->clientId); query.addQueryItem(QLatin1String("client_secret"), d->clientSecret); query.addQueryItem(QLatin1String("code"), code); url.setQuery(query); qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Token Request URL: " << url.toString(); QNetworkRequest netRequest(url); netRequest.setHeader(QNetworkRequest::ContentTypeHeader, QLatin1String("application/x-www-form-urlencoded")); netRequest.setRawHeader("Accept", "application/json"); d->reply = d->netMngr->post(netRequest, QByteArray()); d->state = Private::P_ACCESSTOKEN; } QMap PTalker::ParseUrlParameters(const QString& url) { QMap urlParameters; if (url.indexOf(QLatin1Char('?')) == -1) { return urlParameters; } QString tmp = url.right(url.length()-url.indexOf(QLatin1Char('?')) - 1); QStringList paramlist = tmp.split(QLatin1Char('&')); for (int i = 0 ; i < paramlist.count() ; ++i) { QStringList paramarg = paramlist.at(i).split(QLatin1Char('=')); if (paramarg.count() == 2) { urlParameters.insert(paramarg.at(0), paramarg.at(1)); } } return urlParameters; } void PTalker::slotLinkingFailed() { qCDebug(DIGIKAM_WEBSERVICES_LOG) << "LINK to Pinterest fail"; emit signalBusy(false); } void PTalker::slotLinkingSucceeded() { if (d->accessToken.isEmpty()) { qCDebug(DIGIKAM_WEBSERVICES_LOG) << "UNLINK to Pinterest ok"; emit signalBusy(false); return; } qCDebug(DIGIKAM_WEBSERVICES_LOG) << "LINK to Pinterest ok"; writeSettings(); emit signalLinkingSucceeded(); } bool PTalker::authenticated() { return (!d->accessToken.isEmpty()); } void PTalker::cancel() { if (d->reply) { d->reply->abort(); d->reply = nullptr; } emit signalBusy(false); } void PTalker::createBoard(QString& boardName) { QUrl url(QLatin1String("https://api.pinterest.com/v1/boards/")); QNetworkRequest netRequest(url); netRequest.setHeader(QNetworkRequest::ContentTypeHeader, QLatin1String("application/json")); netRequest.setRawHeader("Authorization", QString::fromLatin1("Bearer %1").arg(d->accessToken).toUtf8()); QByteArray postData = QString::fromUtf8("{\"name\": \"%1\"}").arg(boardName).toUtf8(); - //qCDebug(DIGIKAM_WEBSERVICES_LOG) << "createBoard:" << postData; +/* + qCDebug(DIGIKAM_WEBSERVICES_LOG) << "createBoard:" << postData; +*/ d->reply = d->netMngr->post(netRequest, postData); d->state = Private::P_CREATEBOARD; emit signalBusy(true); } void PTalker::getUserName() { QUrl url(QLatin1String("https://api.pinterest.com/v1/me/?fields=username")); QNetworkRequest netRequest(url); netRequest.setRawHeader("Authorization", QString::fromLatin1("Bearer %1").arg(d->accessToken).toUtf8()); d->reply = d->netMngr->get(netRequest); d->state = Private::P_USERNAME; emit signalBusy(true); } -/** Get list of boards by parsing json sent by pinterest +/** + * Get list of boards by parsing json sent by pinterest */ void PTalker::listBoards(const QString& /*path*/) { QUrl url(QLatin1String("https://api.pinterest.com/v1/me/boards/"));; QNetworkRequest netRequest(url); netRequest.setRawHeader("Authorization", QString::fromLatin1("Bearer %1").arg(d->accessToken).toUtf8()); //netRequest.setHeader(QNetworkRequest::ContentTypeHeader, QLatin1String("application/json")); d->reply = d->netMngr->get(netRequest); d->state = Private::P_LISTBOARDS; emit signalBusy(true); } -bool PTalker::addPin(const QString& imgPath, const QString& uploadBoard, bool rescale, int maxDim, int imageQuality) +bool PTalker::addPin(const QString& imgPath, + const QString& uploadBoard, + bool rescale, + int maxDim, + int imageQuality) { if (d->reply) { d->reply->abort(); d->reply = nullptr; } emit signalBusy(true); QImage image = PreviewLoadThread::loadHighQualitySynchronously(imgPath).copyQImage(); if (image.isNull()) { emit signalBusy(false); return false; } QString path = WSToolUtils::makeTemporaryDir("pinterest").filePath(QFileInfo(imgPath) .baseName().trimmed() + QLatin1String(".jpg")); if (rescale && (image.width() > maxDim || image.height() > maxDim)) { image = image.scaled(maxDim, maxDim, Qt::KeepAspectRatio, Qt::SmoothTransformation); } image.save(path, "JPEG", imageQuality); if (d->meta.load(imgPath)) { d->meta.setItemDimensions(image.size()); d->meta.setItemOrientation(DMetadata::ORIENTATION_NORMAL); d->meta.setMetadataWritingMode((int)DMetadata::WRITE_TO_FILE_ONLY); d->meta.save(path, true); } - QString boardParam = d->userName + QLatin1Char('/') + uploadBoard; + QString boardParam = d->userName + QLatin1Char('/') + uploadBoard; QUrl url(QString::fromLatin1("https://api.pinterest.com/v1/pins/?access_token=%1").arg(d->accessToken)); QHttpMultiPart* const multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType); - ///Board Section + + // Board Section + QHttpPart board; QString boardHeader = QLatin1String("form-data; name=\"board\"") ; board.setHeader(QNetworkRequest::ContentDispositionHeader, boardHeader); QByteArray postData = boardParam.toUtf8(); board.setBody(postData); multiPart->append(board); - ///Note section + // Note section + QHttpPart note; QString noteHeader = QLatin1String("form-data; name=\"note\"") ; note.setHeader(QNetworkRequest::ContentDispositionHeader, noteHeader); - postData = QByteArray(); + postData = QByteArray(); note.setBody(postData); multiPart->append(note); - ///image section - QFile* const file = new QFile(imgPath); - file->open(QIODevice::ReadOnly); + // image section + + QFile* const file = new QFile(imgPath); + + if (!file) + { + return false; + } + + if (!file->open(QIODevice::ReadOnly)) + { + return false; + } QHttpPart imagePart; QString imagePartHeader = QLatin1String("form-data; name=\"image\"; filename=\"") + QFileInfo(imgPath).fileName() + QLatin1Char('"'); imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, imagePartHeader); imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QLatin1String("image/jpeg")); imagePart.setBodyDevice(file); multiPart->append(imagePart); QString content = QLatin1String("multipart/form-data;boundary=") + QString::fromUtf8(multiPart->boundary()); QNetworkRequest netRequest(url); netRequest.setHeader(QNetworkRequest::ContentTypeHeader, content); d->reply = d->netMngr->post(netRequest, multiPart); + // delete the multiPart and file with the reply - multiPart->setParent(d->reply); + multiPart->setParent(d->reply); d->state = Private::P_ADDPIN; + return true; } void PTalker::slotFinished(QNetworkReply* reply) { if (reply != d->reply) { return; } d->reply = nullptr; if (reply->error() != QNetworkReply::NoError) { if (d->state != Private::P_CREATEBOARD) { emit signalBusy(false); QMessageBox::critical(QApplication::activeWindow(), i18n("Error"), reply->errorString()); - - //qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Error content: " << QString(reply->readAll()); +/* + qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Error content: " << QString(reply->readAll()); +*/ reply->deleteLater(); return; } } QByteArray buffer = reply->readAll(); - //qCDebug(DIGIKAM_WEBSERVICES_LOG) << "BUFFER" << QString(buffer); - +/* + qCDebug(DIGIKAM_WEBSERVICES_LOG) << "BUFFER" << QString(buffer); +*/ switch (d->state) { case Private::P_LISTBOARDS: qCDebug(DIGIKAM_WEBSERVICES_LOG) << "In P_LISTBOARDS"; parseResponseListBoards(buffer); break; case Private::P_CREATEBOARD: qCDebug(DIGIKAM_WEBSERVICES_LOG) << "In P_CREATEBOARD"; parseResponseCreateBoard(buffer); break; case Private::P_ADDPIN: qCDebug(DIGIKAM_WEBSERVICES_LOG) << "In P_ADDPIN"; parseResponseAddPin(buffer); break; case Private::P_USERNAME: qCDebug(DIGIKAM_WEBSERVICES_LOG) << "In P_USERNAME"; parseResponseUserName(buffer); break; case Private::P_ACCESSTOKEN: qCDebug(DIGIKAM_WEBSERVICES_LOG) << "In P_ACCESSTOKEN"; parseResponseAccessToken(buffer); break; default: break; } reply->deleteLater(); } void PTalker::parseResponseAccessToken(const QByteArray& data) { QJsonDocument doc = QJsonDocument::fromJson(data); QJsonObject jsonObject = doc.object(); d->accessToken = jsonObject[QLatin1String("access_token")].toString(); if (!d->accessToken.isEmpty()) { qDebug(DIGIKAM_WEBSERVICES_LOG) << "Access token Received: " << d->accessToken; emit pinterestLinkingSucceeded(); } else { emit pinterestLinkingFailed(); } emit signalBusy(false); } void PTalker::parseResponseAddPin(const QByteArray& data) { QJsonDocument doc = QJsonDocument::fromJson(data); QJsonObject jsonObject = doc.object()[QLatin1String("data")].toObject(); bool success = jsonObject.contains(QLatin1String("id")); emit signalBusy(false); if (!success) { emit signalAddPinFailed(i18n("Failed to upload Pin")); } else { emit signalAddPinSucceeded(); } } void PTalker::parseResponseUserName(const QByteArray& data) { QJsonDocument doc = QJsonDocument::fromJson(data); QJsonObject jsonObject = doc.object()[QLatin1String("data")].toObject(); d->userName = jsonObject[QLatin1String("username")].toString(); emit signalBusy(false); emit signalSetUserName(d->userName); } void PTalker::parseResponseListBoards(const QByteArray& data) { QJsonParseError err; QJsonDocument doc = QJsonDocument::fromJson(data, &err); if (err.error != QJsonParseError::NoError) { emit signalBusy(false); emit signalListBoardsFailed(i18n("Failed to list boards")); return; } QJsonObject jsonObject = doc.object(); - //qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Json Listing Boards : " << doc; +/* + qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Json Listing Boards : " << doc; +*/ QJsonArray jsonArray = jsonObject[QLatin1String("data")].toArray(); QList > list; QString boardID; QString boardName; foreach (const QJsonValue& value, jsonArray) { QString boardID; QString boardName; QJsonObject obj = value.toObject(); boardID = obj[QLatin1String("id")].toString(); boardName = obj[QLatin1String("name")].toString(); list.append(qMakePair(boardID, boardName)); } emit signalBusy(false); emit signalListBoardsDone(list); } void PTalker::parseResponseCreateBoard(const QByteArray& data) { QJsonDocument doc = QJsonDocument::fromJson(data); QJsonObject jsonObject = doc.object(); bool fail = jsonObject.contains(QLatin1String("error")); emit signalBusy(false); if (fail) { QJsonParseError err; QJsonDocument doc = QJsonDocument::fromJson(data, &err); emit signalCreateBoardFailed(jsonObject[QLatin1String("error_summary")].toString()); } else { emit signalCreateBoardSucceeded(); } } void PTalker::writeSettings() { d->settings->beginGroup(d->serviceName); d->settings->setValue(d->serviceKey, d->accessToken); d->settings->endGroup(); } void PTalker::readSettings() { d->settings->beginGroup(d->serviceName); d->accessToken = d->settings->value(d->serviceKey).toString(); d->settings->endGroup(); if (d->accessToken.isEmpty()) { qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Linking..."; link(); } else { qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Already Linked"; emit pinterestLinkingSucceeded(); } } } // namespace DigikamGenericPinterestPlugin diff --git a/core/dplugins/generic/webservices/pinterest/pwidget.cpp b/core/dplugins/generic/webservices/pinterest/pwidget.cpp index e390276adc..db9577c6fb 100644 --- a/core/dplugins/generic/webservices/pinterest/pwidget.cpp +++ b/core/dplugins/generic/webservices/pinterest/pwidget.cpp @@ -1,68 +1,70 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2018-05-20 * Description : a tool to export images to Pinterest web service * * Copyright (C) 2018 by Tarek Talaat * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ #include "pwidget.h" // Qt includes #include #include namespace DigikamGenericPinterestPlugin { PWidget::PWidget(QWidget* const parent, - DInfoInterface* const iface, - const QString& toolName) + DInfoInterface* const iface, + const QString& toolName) : WSSettingsWidget(parent, iface, toolName) { getUploadBox()->hide(); getSizeBox()->hide(); } PWidget::~PWidget() { } void PWidget::updateLabels(const QString& name, const QString& url) { QString web(QLatin1String("https://www.pinterest.com/")); if (!url.isEmpty()) + { web = url; + } getHeaderLbl()->setText(QString::fromLatin1( "

" "Pinterest" "

").arg(web)); if (name.isEmpty()) { getUserNameLabel()->clear(); } else { getUserNameLabel()->setText(QString::fromLatin1("%1").arg(name)); } } } // namespace DigikamGenericPinterestPlugin diff --git a/core/dplugins/generic/webservices/pinterest/pwidget.h b/core/dplugins/generic/webservices/pinterest/pwidget.h index a740f566ac..ae1f444bde 100644 --- a/core/dplugins/generic/webservices/pinterest/pwidget.h +++ b/core/dplugins/generic/webservices/pinterest/pwidget.h @@ -1,64 +1,64 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2018-05-20 * Description : a tool to export images to Pinterest web service * * Copyright (C) 2018 by Tarek Talaat * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ #ifndef DIGIKAM_P_WIDGET_H #define DIGIKAM_P_WIDGET_H // Qt includes #include // Local includes #include "wssettingswidget.h" #include "pitem.h" #include "dinfointerface.h" class QButtonGroup; using namespace Digikam; namespace DigikamGenericPinterestPlugin { class PWidget : public WSSettingsWidget { Q_OBJECT public: explicit PWidget(QWidget* const parent, - DInfoInterface* const iface, - const QString& toolName); + DInfoInterface* const iface, + const QString& toolName); ~PWidget(); void updateLabels(const QString& name = QString(), const QString& url = QString()) override; private: friend class PWindow; }; } // namespace DigikamGenericPinterestPlugin #endif // DIGIKAM_P_WIDGET_H diff --git a/core/dplugins/generic/webservices/pinterest/pwindow.cpp b/core/dplugins/generic/webservices/pinterest/pwindow.cpp index 97f0c8dfb0..dbea185b56 100644 --- a/core/dplugins/generic/webservices/pinterest/pwindow.cpp +++ b/core/dplugins/generic/webservices/pinterest/pwindow.cpp @@ -1,468 +1,468 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2018-05-20 * Description : a tool to export images to Pinterest web service * * Copyright (C) 2018 by Tarek Talaat * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ #include "pwindow.h" // Qt includes #include #include #include #include #include #include // KDE includes #include #include #include // Local includes #include "digikam_debug.h" #include "ditemslist.h" #include "digikam_version.h" #include "ptalker.h" #include "pitem.h" #include "pnewalbumdlg.h" #include "pwidget.h" namespace DigikamGenericPinterestPlugin { class Q_DECL_HIDDEN PWindow::Private { public: explicit Private() { imagesCount = 0; imagesTotal = 0; widget = nullptr; albumDlg = nullptr; talker = nullptr; } unsigned int imagesCount; unsigned int imagesTotal; PWidget* widget; PNewAlbumDlg* albumDlg; PTalker* talker; QString currentAlbumName; QList transferQueue; }; PWindow::PWindow(DInfoInterface* const iface, QWidget* const /*parent*/) : WSToolDialog(nullptr, QLatin1String("Pinterest Export Dialog")), d(new Private) { d->widget = new PWidget(this, iface, QLatin1String("Pinterest")); d->widget->imagesList()->setIface(iface); setMainWidget(d->widget); setModal(false); setWindowTitle(i18n("Export to Pinterest")); startButton()->setText(i18n("Start Upload")); startButton()->setToolTip(i18n("Start upload to Pinterest")); d->widget->setMinimumSize(700, 500); connect(d->widget->imagesList(), SIGNAL(signalImageListChanged()), this, SLOT(slotImageListChanged())); connect(d->widget->getChangeUserBtn(), SIGNAL(clicked()), this, SLOT(slotUserChangeRequest())); connect(d->widget->getNewAlbmBtn(), SIGNAL(clicked()), this, SLOT(slotNewBoardRequest())); connect(d->widget->getReloadBtn(), SIGNAL(clicked()), this, SLOT(slotReloadBoardsRequest())); connect(startButton(), SIGNAL(clicked()), this, SLOT(slotStartTransfer())); d->albumDlg = new PNewAlbumDlg(this, QLatin1String("Pinterest")); d->talker = new PTalker(this); connect(d->talker,SIGNAL(signalBusy(bool)), this,SLOT(slotBusy(bool))); connect(d->talker,SIGNAL(signalLinkingFailed()), this,SLOT(slotSignalLinkingFailed())); connect(d->talker,SIGNAL(signalLinkingSucceeded()), this,SLOT(slotSignalLinkingSucceeded())); connect(d->talker,SIGNAL(signalSetUserName(QString)), this,SLOT(slotSetUserName(QString))); connect(d->talker,SIGNAL(signalListBoardsFailed(QString)), this,SLOT(slotListBoardsFailed(QString))); connect(d->talker,SIGNAL(signalListBoardsDone(QList >)), // krazy:exclude=normalize this,SLOT(slotListBoardsDone(QList >))); // krazy:exclude=normalize connect(d->talker,SIGNAL(signalCreateBoardFailed(QString)), this,SLOT(slotCreateBoardFailed(QString))); connect(d->talker,SIGNAL(signalCreateBoardSucceeded()), this,SLOT(slotCreateBoardSucceeded())); connect(d->talker,SIGNAL(signalAddPinFailed(QString)), this,SLOT(slotAddPinFailed(QString))); connect(d->talker,SIGNAL(signalAddPinSucceeded()), this,SLOT(slotAddPinSucceeded())); connect(this, SIGNAL(finished(int)), this, SLOT(slotFinished())); readSettings(); buttonStateChange(false); d->talker->readSettings(); } PWindow::~PWindow() { delete d->widget; delete d->albumDlg; delete d->talker; delete d; } void PWindow::readSettings() { KConfig config; KConfigGroup grp = config.group("Pinterest Settings"); d->currentAlbumName = grp.readEntry("Current Album",QString()); if (grp.readEntry("Resize", false)) { d->widget->getResizeCheckBox()->setChecked(true); d->widget->getDimensionSpB()->setEnabled(true); } else { d->widget->getResizeCheckBox()->setChecked(false); d->widget->getDimensionSpB()->setEnabled(false); } d->widget->getDimensionSpB()->setValue(grp.readEntry("Maximum Width", 1600)); d->widget->getImgQualitySpB()->setValue(grp.readEntry("Image Quality", 90)); KConfigGroup dialogGroup = config.group("Pinterest Export Dialog"); winId(); KWindowConfig::restoreWindowSize(windowHandle(), dialogGroup); resize(windowHandle()->size()); } void PWindow::writeSettings() { KConfig config; KConfigGroup grp = config.group("Pinterest Settings"); grp.writeEntry("Current Album", d->currentAlbumName); grp.writeEntry("Resize", d->widget->getResizeCheckBox()->isChecked()); grp.writeEntry("Maximum Width", d->widget->getDimensionSpB()->value()); grp.writeEntry("Image Quality", d->widget->getImgQualitySpB()->value()); KConfigGroup dialogGroup = config.group("Pinterest Export Dialog"); KWindowConfig::saveWindowSize(windowHandle(), dialogGroup); config.sync(); } void PWindow::reactivate() { d->widget->imagesList()->loadImagesFromCurrentSelection(); d->widget->progressBar()->hide(); show(); } void PWindow::setItemsList(const QList& urls) { d->widget->imagesList()->slotAddImages(urls); } void PWindow::slotBusy(bool val) { if (val) { setCursor(Qt::WaitCursor); d->widget->getChangeUserBtn()->setEnabled(false); buttonStateChange(false); } else { setCursor(Qt::ArrowCursor); d->widget->getChangeUserBtn()->setEnabled(true); buttonStateChange(true); } } void PWindow::slotSetUserName(const QString& msg) { d->widget->updateLabels(msg, QLatin1String("")); } void PWindow::slotListBoardsDone(const QList >& list) { d->widget->getAlbumsCoB()->clear(); for (int i = 0 ; i < list.size() ; ++i) { d->widget->getAlbumsCoB()->addItem( QIcon::fromTheme(QLatin1String("system-users")), list.value(i).second, list.value(i).second); if (d->currentAlbumName == list.value(i).first) { d->widget->getAlbumsCoB()->setCurrentIndex(i); } } buttonStateChange(true); d->talker->getUserName(); } void PWindow::slotStartTransfer() { d->widget->imagesList()->clearProcessedStatus(); if (d->widget->imagesList()->imageUrls().isEmpty()) { QMessageBox::critical(this, i18nc("@title:window", "Error"), i18n("No image selected. Please select which images should be uploaded.")); return; } if (!(d->talker->authenticated())) { QPointer warn = new QMessageBox(QMessageBox::Warning, - i18n("Warning"), - i18n("Authentication failed. Click \"Continue\" to authenticate."), - QMessageBox::Yes | QMessageBox::No); + i18n("Warning"), + i18n("Authentication failed. Click \"Continue\" to authenticate."), + QMessageBox::Yes | QMessageBox::No); (warn->button(QMessageBox::Yes))->setText(i18n("Continue")); (warn->button(QMessageBox::No))->setText(i18n("Cancel")); if (warn->exec() == QMessageBox::Yes) { d->talker->link(); delete warn; return; } else { delete warn; return; } } d->transferQueue = d->widget->imagesList()->imageUrls(); if (d->transferQueue.isEmpty()) { return; } d->currentAlbumName = d->widget->getAlbumsCoB()->itemData(d->widget->getAlbumsCoB()->currentIndex()).toString(); qCDebug(DIGIKAM_WEBSERVICES_LOG) << "StartTransfer:" << d->currentAlbumName << "INDEX: " << d->widget->getAlbumsCoB()->currentIndex(); - d->imagesTotal = d->transferQueue.count(); - d->imagesCount = 0; + d->imagesTotal = d->transferQueue.count(); + d->imagesCount = 0; d->widget->progressBar()->setFormat(i18n("%v / %m")); d->widget->progressBar()->setMaximum(d->imagesTotal); d->widget->progressBar()->setValue(0); d->widget->progressBar()->show(); d->widget->progressBar()->progressScheduled(i18n("Pinterest export"), true, true); d->widget->progressBar()->progressThumbnailChanged( QIcon::fromTheme(QLatin1String("dk-pinterest")).pixmap(22, 22)); uploadNextPhoto(); } void PWindow::uploadNextPhoto() { qCDebug(DIGIKAM_WEBSERVICES_LOG) << "uploadNextPhoto:" << d->transferQueue.count(); if (d->transferQueue.isEmpty()) { qCDebug(DIGIKAM_WEBSERVICES_LOG) << "empty"; d->widget->progressBar()->progressCompleted(); return; } QString imgPath = d->transferQueue.first().toLocalFile(); QString temp = d->currentAlbumName; bool result = d->talker->addPin(imgPath, temp, d->widget->getResizeCheckBox()->isChecked(), d->widget->getDimensionSpB()->value(), d->widget->getImgQualitySpB()->value()); if (!result) { slotAddPinFailed(QLatin1String("")); return; } } void PWindow::slotAddPinFailed(const QString& msg) { if (QMessageBox::question(this, i18n("Uploading Failed"), i18n("Failed to upload photo to Pinterest." "\n%1\n" "Do you want to continue?", msg)) != QMessageBox::Yes) { d->transferQueue.clear(); d->widget->progressBar()->hide(); } else { d->transferQueue.pop_front(); d->imagesTotal--; d->widget->progressBar()->setMaximum(d->imagesTotal); d->widget->progressBar()->setValue(d->imagesCount); uploadNextPhoto(); } } void PWindow::slotAddPinSucceeded() { // Remove photo uploaded from the list d->widget->imagesList()->removeItemByUrl(d->transferQueue.first()); d->transferQueue.pop_front(); d->imagesCount++; d->widget->progressBar()->setMaximum(d->imagesTotal); d->widget->progressBar()->setValue(d->imagesCount); uploadNextPhoto(); } void PWindow::slotImageListChanged() { startButton()->setEnabled(!(d->widget->imagesList()->imageUrls().isEmpty())); } void PWindow::slotNewBoardRequest() { if (d->albumDlg->exec() == QDialog::Accepted) { PFolder newFolder; d->albumDlg->getFolderTitle(newFolder); d->currentAlbumName = d->widget->getAlbumsCoB()->itemData(d->widget->getAlbumsCoB()->currentIndex()).toString(); d->currentAlbumName = newFolder.title; d->talker->createBoard(d->currentAlbumName); } } void PWindow::slotReloadBoardsRequest() { d->talker->listBoards(); } void PWindow::slotSignalLinkingFailed() { slotSetUserName(QLatin1String("")); d->widget->getAlbumsCoB()->clear(); if (QMessageBox::question(this, i18n("Login Failed"), i18n("Authentication failed. Do you want to try again?")) == QMessageBox::Yes) { d->talker->link(); } } void PWindow::slotSignalLinkingSucceeded() { d->talker->listBoards(); } void PWindow::slotListBoardsFailed(const QString& msg) { QMessageBox::critical(this, QString(), i18n("Pinterest call failed:\n%1", msg)); } void PWindow::slotCreateBoardFailed(const QString& msg) { QMessageBox::critical(this, QString(), i18n("Pinterest call failed:\n%1", msg)); } void PWindow::slotCreateBoardSucceeded() { d->talker->listBoards(); } void PWindow::slotTransferCancel() { d->transferQueue.clear(); d->widget->progressBar()->hide(); d->talker->cancel(); } void PWindow::slotUserChangeRequest() { slotSetUserName(QLatin1String("")); d->widget->getAlbumsCoB()->clear(); d->talker->unLink(); d->talker->link(); } void PWindow::buttonStateChange(bool state) { d->widget->getNewAlbmBtn()->setEnabled(state); d->widget->getReloadBtn()->setEnabled(state); startButton()->setEnabled(state); } void PWindow::slotFinished() { writeSettings(); d->widget->imagesList()->listView()->clear(); } void PWindow::closeEvent(QCloseEvent* e) { if (!e) { return; } slotFinished(); e->accept(); } } // namespace DigikamGenericPinterestPlugin