File indexing completed on 2025-01-05 03:53:25
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2008-12-26 0007 * Description : a tool to export items to Facebook web service 0008 * 0009 * SPDX-FileCopyrightText: 2008-2010 by Luka Renko <lure at kubuntu dot org> 0010 * SPDX-FileCopyrightText: 2011 by Dirk Tilger <dirk dot kde at miriup dot de> 0011 * SPDX-FileCopyrightText: 2008-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0012 * SPDX-FileCopyrightText: 2018 by Thanh Trung Dinh <dinhthanhtrung1996 at gmail dot com> 0013 * 0014 * SPDX-License-Identifier: GPL-2.0-or-later 0015 * 0016 * ============================================================ */ 0017 0018 #include "fbtalker_wizard.h" 0019 0020 // Qt includes 0021 0022 #include <QJsonDocument> 0023 #include <QJsonParseError> 0024 #include <QJsonObject> 0025 #include <QJsonValue> 0026 #include <QJsonArray> 0027 #include <QByteArray> 0028 #include <QDomDocument> 0029 #include <QDomElement> 0030 #include <QtAlgorithms> 0031 #include <QVBoxLayout> 0032 #include <QLineEdit> 0033 #include <QDesktopServices> 0034 #include <QApplication> 0035 #include <QPushButton> 0036 #include <QDialog> 0037 #include <QDialogButtonBox> 0038 #include <QUrlQuery> 0039 #include <QMessageBox> 0040 #include <QNetworkAccessManager> 0041 0042 // Local includes 0043 0044 #include "digikam_version.h" 0045 #include "fbmpform.h" 0046 #include "fbnewalbumdlg.h" 0047 #include "digikam_debug.h" 0048 #include "o0settingsstore.h" 0049 #include "wstoolutils.h" 0050 0051 namespace DigikamGenericFaceBookPlugin 0052 { 0053 0054 bool operator< (const FbUser& first, const FbUser& second) 0055 { 0056 return first.name < second.name; 0057 } 0058 0059 bool operator< (const FbAlbum& first, const FbAlbum& second) 0060 { 0061 return first.title < second.title; 0062 } 0063 0064 // ----------------------------------------------------------------------------- 0065 0066 class Q_DECL_HIDDEN FbTalker::Private 0067 { 0068 0069 public: 0070 0071 explicit Private(WSNewAlbumDialog* albumDlg) 0072 : dialog(0), 0073 parent(0), 0074 apiURL(QLatin1String("https://graph.facebook.com/%1/%2")), 0075 authUrl(QLatin1String("https://www.facebook.com/dialog/oauth")), 0076 tokenUrl(QLatin1String("https://graph.facebook.com/oauth/access_token")), 0077 scope(QLatin1String("user_photos,publish_pages,manage_pages")), //publish_to_groups,user_friends not necessary? 0078 apikey(QLatin1String("400589753481372")), 0079 clientSecret(QLatin1String("5b0b5cd096e110cd4f4c72f517e2c544")), 0080 loginInProgress(false), 0081 albumDlg(dynamic_cast<FbNewAlbumDlg*>(albumDlg)), 0082 o2(0) 0083 { 0084 } 0085 0086 QDialog* dialog; 0087 QWidget* parent; 0088 0089 QString apiURL; 0090 QString authUrl; 0091 QString tokenUrl; 0092 QString scope; 0093 QString apikey; 0094 QString clientSecret; 0095 0096 bool loginInProgress; 0097 0098 FbUser user; 0099 FbNewAlbumDlg* const albumDlg; // Pointer to FbNewAlbumDlg* const so that no modification can impact this pointer 0100 0101 //Ported to O2 here 0102 O2* o2; 0103 }; 0104 0105 // ----------------------------------------------------------------------------- 0106 0107 FbTalker::FbTalker(QWidget* const parent, WSNewAlbumDialog* albumDlg) 0108 : WSTalker(parent), 0109 d(new Private(albumDlg)) 0110 { 0111 d->parent = parent; 0112 0113 //TODO: Ported to O2 here 0114 0115 d->o2 = new O2(this); 0116 0117 d->o2->setClientId(d->apikey); 0118 d->o2->setClientSecret(d->clientSecret); 0119 0120 d->o2->setRequestUrl(d->authUrl); 0121 d->o2->setTokenUrl(d->tokenUrl); 0122 d->o2->setRefreshTokenUrl(d->tokenUrl); 0123 d->o2->setLocalhostPolicy(QLatin1String("https://www.facebook.com/connect/login_success.html")); 0124 d->o2->setUseExternalWebInterceptor(true); 0125 d->o2->setLocalPort(8000); 0126 d->o2->setGrantFlow(O2::GrantFlow::GrantFlowImplicit); 0127 d->o2->setScope(d->scope); 0128 0129 m_store->setGroupKey(QLatin1String("Facebook")); 0130 d->o2->setStore(m_store); 0131 0132 connect(d->o2, SIGNAL(linkingFailed()), 0133 this, SLOT(slotLinkingFailed())); 0134 0135 connect(d->o2, SIGNAL(linkingSucceeded()), 0136 this, SLOT(slotLinkingSucceeded())); 0137 0138 connect(d->o2, SIGNAL(openBrowser(QUrl)), 0139 this, SLOT(slotOpenBrowser(QUrl))); 0140 0141 connect(d->o2, SIGNAL(closeBrowser()), 0142 this, SLOT(slotCloseBrowser())); 0143 } 0144 0145 FbTalker::~FbTalker() 0146 { 0147 if (m_reply) 0148 { 0149 m_reply->abort(); 0150 } 0151 0152 delete d; 0153 } 0154 0155 //TODO: Ported to O2 here 0156 // ---------------------------------------------------------------------------------------------- 0157 void FbTalker::link() 0158 { 0159 Q_EMIT signalBusy(true); 0160 0161 d->loginInProgress = true; 0162 d->o2->link(); 0163 } 0164 0165 void FbTalker::unlink() 0166 { 0167 Q_EMIT signalBusy(true); 0168 d->o2->unlink(); 0169 } 0170 0171 void FbTalker::slotResponseTokenReceived(const QMap<QString, QString>& rep) 0172 { 0173 d->o2->onVerificationReceived(rep); 0174 } 0175 0176 bool FbTalker::linked() const 0177 { 0178 return d->o2->linked(); 0179 } 0180 0181 void FbTalker::resetTalker(const QString& expire, const QString& accessToken, const QString& refreshToken) 0182 { 0183 m_store->setValue(QString::fromUtf8(O2_KEY_EXPIRES).arg(d->apikey), expire); 0184 m_store->setValue(QString::fromUtf8(O2_KEY_LINKED).arg(d->apikey), QLatin1String("1")); 0185 m_store->setValue(QString::fromUtf8(O2_KEY_REFRESH_TOKEN).arg(d->apikey), refreshToken); 0186 m_store->setValue(QString::fromUtf8(O2_KEY_TOKEN).arg(d->apikey), accessToken); 0187 } 0188 0189 FbUser FbTalker::getUser() const 0190 { 0191 return d->user; 0192 } 0193 0194 void FbTalker::authenticate() 0195 { 0196 d->loginInProgress = true; 0197 Q_EMIT signalLoginProgress(2, 9, i18n("Validate previous session...")); 0198 0199 WSTalker::authenticate(); 0200 } 0201 0202 void FbTalker::getLoggedInUser() 0203 { 0204 qCDebug(DIGIKAM_WEBSERVICES_LOG) << "getLoggedInUser called "; 0205 0206 if (m_reply) 0207 { 0208 m_reply->abort(); 0209 m_reply = 0; 0210 } 0211 0212 Q_EMIT signalBusy(true); 0213 Q_EMIT signalLoginProgress(3); 0214 0215 QUrl url(d->apiURL.arg(QLatin1String("me")) 0216 .arg(QString())); 0217 QUrlQuery q; 0218 // q.addQueryItem(QLatin1String("fields"), QLatin1String("id,name,link")); 0219 q.addQueryItem(QLatin1String("access_token"), d->o2->token()); 0220 url.setQuery(q); 0221 0222 QNetworkRequest netRequest(url); 0223 netRequest.setHeader(QNetworkRequest::ContentTypeHeader, 0224 QLatin1String("application/x-www-form-urlencoded")); 0225 0226 qCDebug(DIGIKAM_WEBSERVICES_LOG) << "url = " << netRequest.url(); 0227 m_reply = m_netMngr->get(netRequest); 0228 0229 m_state = WSTalker::GETUSER; 0230 } 0231 0232 // ---------------------------------------------------------------------------------------------- 0233 0234 /** Compute MD5 signature using url queries keys and values: 0235 * wiki.developers.facebook.com/index.php/How_Facebook_Authenticates_Your_Application 0236 * This method was used for the legacy authentication scheme and has been obsoleted with OAuth2 authentication. 0237 */ 0238 /* 0239 QString FbTalker::getApiSig(const QMap<QString, QString>& args) 0240 { 0241 QString concat; 0242 // NOTE: QMap iterator will sort alphabetically 0243 0244 for (QMap<QString, QString>::const_iterator it = args.constBegin() ; 0245 it != args.constEnd() ; ++it) 0246 { 0247 concat.append(it.key()); 0248 concat.append("="); 0249 concat.append(it.value()); 0250 } 0251 0252 if (args["session_key"].isEmpty()) 0253 concat.append(d->clientSecret); 0254 else 0255 concat.append(d->sessionSecret); 0256 0257 KMD5 md5(concat.toUtf8()); 0258 return md5.hexDigest().data(); 0259 } 0260 */ 0261 0262 void FbTalker::logout() 0263 { 0264 if (m_reply) 0265 { 0266 m_reply->abort(); 0267 m_reply = 0; 0268 } 0269 0270 QMap<QString, QString> args; 0271 args[QLatin1String("next")] = QLatin1String("https://www.digikam.org"); 0272 args[QLatin1String("access_token")] = d->o2->token(); 0273 0274 QUrl url(QLatin1String("https://www.facebook.com/logout.php")); 0275 QUrlQuery q; 0276 q.addQueryItem(QLatin1String("next"), QLatin1String("https://www.digikam.org")); 0277 q.addQueryItem(QLatin1String("access_token"), d->o2->token()); 0278 url.setQuery(q); 0279 qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Logout URL: " << url; 0280 QDesktopServices::openUrl(url); 0281 0282 Q_EMIT signalBusy(false); 0283 } 0284 0285 //TODO: Ported to O2 0286 //---------------------------------------------------------------------------------------------------- 0287 0288 void FbTalker::listAlbums(long long userID) 0289 { 0290 qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Requesting albums for user " << userID; 0291 0292 if (m_reply) 0293 { 0294 m_reply->abort(); 0295 m_reply = 0; 0296 } 0297 0298 Q_EMIT signalBusy(true); 0299 0300 QUrl url; 0301 0302 /* 0303 * If userID is specified, load albums of that user, 0304 * else load albums of current user 0305 */ 0306 if (!userID) 0307 { 0308 url = QUrl(d->apiURL.arg(d->user.id) 0309 .arg(QLatin1String("albums"))); 0310 } 0311 else 0312 { 0313 url = QUrl(d->apiURL.arg(userID) 0314 .arg(QLatin1String("albums"))); 0315 } 0316 0317 QUrlQuery q; 0318 q.addQueryItem(QLatin1String("fields"), 0319 QLatin1String("id,name,description,privacy,link,location")); 0320 q.addQueryItem(QLatin1String("access_token"), d->o2->token()); 0321 url.setQuery(q); 0322 0323 QNetworkRequest netRequest(url); 0324 netRequest.setHeader(QNetworkRequest::ContentTypeHeader, 0325 QLatin1String("application/x-www-form-urlencoded")); 0326 0327 m_reply = m_netMngr->get(netRequest); 0328 0329 m_state = WSTalker::LISTALBUMS; 0330 } 0331 0332 void FbTalker::createAlbum(const FbAlbum& album) 0333 { 0334 if (m_reply) 0335 { 0336 m_reply->abort(); 0337 m_reply = 0; 0338 } 0339 0340 Q_EMIT signalBusy(true); 0341 0342 QUrlQuery params; 0343 params.addQueryItem(QLatin1String("access_token"), d->o2->token()); 0344 params.addQueryItem(QLatin1String("name"), album.title); 0345 0346 if (!album.location.isEmpty()) 0347 params.addQueryItem(QLatin1String("location"), album.location); 0348 /* 0349 * description is deprecated and now a param of message 0350 */ 0351 if (!album.description.isEmpty()) 0352 params.addQueryItem(QLatin1String("message"), album.description); 0353 0354 // TODO (Dirk): Wasn't that a requested feature in Bugzilla? 0355 switch (album.privacy) 0356 { 0357 case FB_ME: 0358 params.addQueryItem(QLatin1String("privacy"), QLatin1String("{'value':'SELF'}")); 0359 break; 0360 case FB_FRIENDS: 0361 params.addQueryItem(QLatin1String("privacy"), QLatin1String("{'value':'ALL_FRIENDS'}")); 0362 break; 0363 case FB_FRIENDS_OF_FRIENDS: 0364 params.addQueryItem(QLatin1String("privacy"), QLatin1String("{'value':'FRIENDS_OF_FRIENDS'}")); 0365 break; 0366 case FB_EVERYONE: 0367 params.addQueryItem(QLatin1String("privacy"), QLatin1String("{'value':'EVERYONE'}")); 0368 break; 0369 case FB_CUSTOM: 0370 //TODO 0371 params.addQueryItem(QLatin1String("privacy"), QLatin1String("{'value':'CUSTOM'}")); 0372 break; 0373 } 0374 0375 QUrl url(QUrl(d->apiURL.arg(d->user.id) 0376 .arg(QLatin1String("albums")))); 0377 // url.setQuery(params); 0378 0379 QNetworkRequest netRequest(url); 0380 netRequest.setHeader(QNetworkRequest::ContentTypeHeader, 0381 QLatin1String("application/x-www-form-urlencoded")); 0382 0383 qCDebug(DIGIKAM_WEBSERVICES_LOG) << "url to create new album " << netRequest.url() << params.query(); 0384 0385 m_reply = m_netMngr->post(netRequest, params.query().toUtf8()); 0386 0387 m_state = WSTalker::CREATEALBUM; 0388 } 0389 0390 void FbTalker::createNewAlbum() 0391 { 0392 FbAlbum album; 0393 d->albumDlg->getAlbumProperties(album); 0394 createAlbum(album); 0395 } 0396 0397 void FbTalker::addPhoto(const QString& imgPath, const QString& albumID, const QString& caption) 0398 { 0399 qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Adding photo " << imgPath << " to album with id " 0400 << albumID << " using caption '" << caption << "'"; 0401 0402 if (m_reply) 0403 { 0404 m_reply->abort(); 0405 m_reply = 0; 0406 } 0407 0408 Q_EMIT signalBusy(true); 0409 0410 QMap<QString, QString> args; 0411 args[QLatin1String("access_token")] = d->o2->token(); 0412 0413 if (!caption.isEmpty()) 0414 args[QLatin1String("message")] = caption; 0415 0416 FbMPForm form; 0417 0418 for (QMap<QString, QString>::const_iterator it = args.constBegin() ; 0419 it != args.constEnd() ; ++it) 0420 { 0421 form.addPair(it.key(), it.value()); 0422 } 0423 0424 qCDebug(DIGIKAM_WEBSERVICES_LOG) << "FORM: " << QT_ENDL << form.formData(); 0425 0426 if (!form.addFile(QUrl::fromLocalFile(imgPath).fileName(), imgPath)) 0427 { 0428 Q_EMIT signalAddPhotoDone(666, i18n("Cannot open file")); 0429 Q_EMIT signalBusy(false); 0430 return; 0431 } 0432 0433 form.finish(); 0434 0435 QVariant arg_1; 0436 0437 if (albumID.isEmpty()) 0438 { 0439 arg_1 = d->user.id; 0440 } 0441 else 0442 { 0443 arg_1 = albumID; 0444 } 0445 0446 QNetworkRequest netRequest(QUrl(d->apiURL.arg(arg_1.toString()).arg(QLatin1String("photos")))); 0447 netRequest.setHeader(QNetworkRequest::ContentTypeHeader, form.contentType()); 0448 0449 m_reply = m_netMngr->post(netRequest, form.formData()); 0450 0451 m_state = WSTalker::ADDPHOTO; 0452 } 0453 0454 //---------------------------------------------------------------------------------------------------- 0455 0456 QString FbTalker::errorToText(int errCode, const QString& errMsg) 0457 { 0458 QString transError; 0459 qCDebug(DIGIKAM_WEBSERVICES_LOG) << "errorToText: " << errCode << ": " << errMsg; 0460 0461 switch (errCode) 0462 { 0463 case 0: 0464 transError = QLatin1String(""); 0465 break; 0466 case 2: 0467 transError = i18n("The service is not available at this time."); 0468 break; 0469 case 4: 0470 transError = i18n("The application has reached the maximum number of requests allowed."); 0471 break; 0472 case 102: 0473 transError = i18n("Invalid session key or session expired. Try to log in again."); 0474 break; 0475 case 120: 0476 transError = i18n("Invalid album ID."); 0477 break; 0478 case 321: 0479 transError = i18n("Album is full."); 0480 break; 0481 case 324: 0482 transError = i18n("Missing or invalid file."); 0483 break; 0484 case 325: 0485 transError = i18n("Too many unapproved photos pending."); 0486 break; 0487 default: 0488 transError = errMsg; 0489 break; 0490 } 0491 0492 return transError; 0493 } 0494 0495 /* 0496 * (Trung) This has to be adapted in slotFinished in WSTalker 0497 * 0498 void FbTalker::slotFinished(QNetworkReply* reply) 0499 { 0500 if (reply != m_reply) 0501 { 0502 return; 0503 } 0504 0505 m_reply = 0; 0506 0507 if (reply->error() != QNetworkReply::NoError) 0508 { 0509 if (d->loginInProgress) 0510 { 0511 authenticationDone(reply->error(), reply->errorString()); 0512 } 0513 else if (d->state == Private::FB_ADDPHOTO) 0514 { 0515 Q_EMIT signalBusy(false); 0516 Q_EMIT signalAddPhotoDone(reply->error(), reply->errorString()); 0517 } 0518 else 0519 { 0520 Q_EMIT signalBusy(false); 0521 QMessageBox::critical(QApplication::activeWindow(), 0522 i18nc("@title:window", "Error"), reply->errorString()); 0523 } 0524 0525 qCDebug(DIGIKAM_WEBSERVICES_LOG) << reply->error() << " text :"<< QString(reply->readAll()); 0526 0527 reply->deleteLater(); 0528 return; 0529 } 0530 0531 m_buffer.append(reply->readAll()); 0532 0533 switch (d->state) 0534 { 0535 case (Private::FB_GETLOGGEDINUSER): 0536 parseResponseGetLoggedInUser(m_buffer); 0537 break; 0538 case (Private::FB_LISTALBUMS): 0539 parseResponseListAlbums(m_buffer); 0540 break; 0541 case (Private::FB_CREATEALBUM): 0542 parseResponseCreateAlbum(m_buffer); 0543 break; 0544 case (Private::FB_ADDPHOTO): 0545 parseResponseAddPhoto(m_buffer); 0546 break; 0547 } 0548 0549 reply->deleteLater(); 0550 } 0551 */ 0552 0553 void FbTalker::authenticationDone(int errCode, const QString& errMsg) 0554 { 0555 if (errCode != 0) 0556 { 0557 d->user.clear(); 0558 } 0559 else 0560 { 0561 saveUserAccount(d->user.name, d->user.id, d->o2->expires(), d->o2->token(), d->o2->refreshToken()); 0562 } 0563 0564 Q_EMIT signalLoginDone(errCode, errMsg); 0565 d->loginInProgress = false; 0566 0567 WSTalker::authenticationDone(errCode, errMsg); 0568 } 0569 0570 int FbTalker::parseErrorResponse(const QDomElement& e, QString& errMsg) 0571 { 0572 int errCode = -1; 0573 0574 for (QDomNode node = e.firstChild() ; 0575 !node.isNull() ; node = node.nextSibling()) 0576 { 0577 if (!node.isElement()) 0578 continue; 0579 0580 if (node.nodeName() == QLatin1String("error_code")) 0581 { 0582 errCode = node.toElement().text().toInt(); 0583 qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Error Code:" << errCode; 0584 } 0585 else if (node.nodeName() == QLatin1String("error_msg")) 0586 { 0587 errMsg = node.toElement().text(); 0588 qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Error Text:" << errMsg; 0589 } 0590 } 0591 0592 return errCode; 0593 } 0594 0595 //TODO: Port to O2 0596 void FbTalker::parseResponseGetLoggedInUser(const QByteArray& data) 0597 { 0598 QString errMsg; 0599 QJsonParseError err; 0600 QJsonDocument doc = QJsonDocument::fromJson(data, &err); 0601 0602 qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Logged in data " << doc; 0603 0604 if (err.error != QJsonParseError::NoError) 0605 { 0606 Q_EMIT signalBusy(false); 0607 return; 0608 } 0609 0610 QJsonObject jsonObject = doc.object(); 0611 d->user.id = jsonObject[QLatin1String("id")].toString(); 0612 0613 if (!(QString::compare(jsonObject[QLatin1String("id")].toString(), QLatin1String(""), Qt::CaseInsensitive) == 0)) 0614 { 0615 qCDebug(DIGIKAM_WEBSERVICES_LOG) << "ID found in response of GetLoggedInUser"; 0616 } 0617 0618 d->user.name = jsonObject[QLatin1String("name")].toString(); 0619 m_userName = d->user.name; 0620 0621 d->user.profileURL = jsonObject[QLatin1String("link")].toString(); 0622 } 0623 0624 void FbTalker::parseResponseAddPhoto(const QByteArray& data) 0625 { 0626 qCDebug(DIGIKAM_WEBSERVICES_LOG) <<"Parse Add Photo data is "<<data; 0627 int errCode = -1; 0628 QString errMsg; 0629 QJsonParseError err; 0630 QJsonDocument doc = QJsonDocument::fromJson(data, &err); 0631 0632 if (err.error != QJsonParseError::NoError) 0633 { 0634 Q_EMIT signalBusy(false); 0635 return; 0636 } 0637 0638 QJsonObject jsonObject = doc.object(); 0639 0640 if (jsonObject.contains(QLatin1String("id"))) 0641 { 0642 qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Id of photo exported is" << jsonObject[QLatin1String("id")].toString(); 0643 errCode = 0; 0644 } 0645 0646 if (jsonObject.contains(QLatin1String("error"))) 0647 { 0648 QJsonObject obj = jsonObject[QLatin1String("error")].toObject(); 0649 errCode = obj[QLatin1String("code")].toInt(); 0650 errMsg = obj[QLatin1String("message")].toString(); 0651 } 0652 0653 qCDebug(DIGIKAM_WEBSERVICES_LOG) << "add photo : " << doc; 0654 0655 Q_EMIT signalBusy(false); 0656 Q_EMIT signalAddPhotoDone(errCode, errorToText(errCode, errMsg)); 0657 } 0658 0659 void FbTalker::parseResponseCreateAlbum(const QByteArray& data) 0660 { 0661 qCDebug(DIGIKAM_WEBSERVICES_LOG) <<"Parse Create album data is"<<data; 0662 int errCode = -1; 0663 QString errMsg; 0664 QString newAlbumID; 0665 QJsonParseError err; 0666 QJsonDocument doc = QJsonDocument::fromJson(data, &err); 0667 0668 if (err.error != QJsonParseError::NoError) 0669 { 0670 Q_EMIT signalBusy(false); 0671 return; 0672 } 0673 0674 QJsonObject jsonObject = doc.object(); 0675 0676 if (jsonObject.contains(QLatin1String("id"))) 0677 { 0678 newAlbumID = jsonObject[QLatin1String("id")].toString(); 0679 qCDebug(DIGIKAM_WEBSERVICES_LOG) << "Id of album created is" << newAlbumID; 0680 errCode = 0; 0681 } 0682 0683 if (jsonObject.contains(QLatin1String("error"))) 0684 { 0685 QJsonObject obj = jsonObject[QLatin1String("error")].toObject(); 0686 errCode = obj[QLatin1String("code")].toInt(); 0687 errMsg = obj[QLatin1String("message")].toString(); 0688 } 0689 0690 qCDebug(DIGIKAM_WEBSERVICES_LOG) << "error create photo : " << doc; 0691 0692 Q_EMIT signalBusy(false); 0693 Q_EMIT signalCreateAlbumDone(errCode, errorToText(errCode, errMsg), 0694 newAlbumID); 0695 } 0696 0697 void FbTalker::parseResponseListAlbums(const QByteArray& data) 0698 { 0699 int errCode = -1; 0700 QString errMsg; 0701 QJsonParseError err; 0702 QList<WSAlbum> albumsList; // QList <FbAlbum> albumsList; 0703 QJsonDocument doc = QJsonDocument::fromJson(data, &err); 0704 0705 if (err.error != QJsonParseError::NoError) 0706 { 0707 Q_EMIT signalBusy(false); 0708 return; 0709 } 0710 0711 QJsonObject jsonObject = doc.object(); 0712 0713 if (jsonObject.contains(QLatin1String("data"))) 0714 { 0715 QJsonArray jsonArray = jsonObject[QLatin1String("data")].toArray(); 0716 0717 Q_FOREACH (const QJsonValue& value, jsonArray) 0718 { 0719 QJsonObject obj = value.toObject(); 0720 WSAlbum album; //FbAlbum album; 0721 album.id = obj[QLatin1String("id")].toString(); 0722 album.title = obj[QLatin1String("name")].toString(); 0723 album.location = obj[QLatin1String("location")].toString(); 0724 album.url = obj[QLatin1String("link")].toString(); 0725 album.description = obj[QLatin1String("description")].toString(); 0726 album.uploadable = obj[QLatin1String("can_upload")].toBool(); 0727 0728 qCDebug(DIGIKAM_WEBSERVICES_LOG) << "can_upload " << album.uploadable; 0729 /* 0730 if (QString::compare(obj[QLatin1String("privacy")].toString(), 0731 QLatin1String("ALL_FRIENDS"), Qt::CaseInsensitive) == 0) 0732 { 0733 album.privacy = FB_FRIENDS; 0734 } 0735 else if (QString::compare(obj[QLatin1String("privacy")].toString(), 0736 QLatin1String("FRIENDS_OF_FRIENDS"), Qt::CaseInsensitive) == 0) 0737 { 0738 album.privacy = FB_FRIENDS; 0739 } 0740 else if (QString::compare(obj[QLatin1String("privacy")].toString(), 0741 QLatin1String("EVERYONE"), Qt::CaseInsensitive) == 0) 0742 { 0743 album.privacy = FB_EVERYONE; 0744 } 0745 else if (QString::compare(obj[QLatin1String("privacy")].toString(), 0746 QLatin1String("CUSTOM"), Qt::CaseInsensitive) == 0) 0747 { 0748 album.privacy = FB_CUSTOM; 0749 } 0750 else if (QString::compare(obj[QLatin1String("privacy")].toString(), 0751 QLatin1String("SELF"), Qt::CaseInsensitive) == 0) 0752 { 0753 album.privacy = FB_ME; 0754 } 0755 */ 0756 albumsList.append(album); 0757 } 0758 0759 errCode = 0; 0760 } 0761 0762 if (jsonObject.contains(QLatin1String("error"))) 0763 { 0764 QJsonObject obj = jsonObject[QLatin1String("error")].toObject(); 0765 errCode = obj[QLatin1String("code")].toInt(); 0766 errMsg = obj[QLatin1String("message")].toString(); 0767 } 0768 0769 /* std::sort(albumsList.begin(), albumsList.end()); 0770 * This function is replaced by method below which is defined in WSTalker as a virtual method for further evolution if needed 0771 */ 0772 sortAlbumsList(albumsList); 0773 0774 Q_EMIT signalBusy(false); 0775 Q_EMIT signalListAlbumsDone(errCode, errorToText(errCode, errMsg), 0776 albumsList); 0777 } 0778 0779 } // namespace DigikamGenericFaceBookPlugin 0780 0781 #include "moc_fbtalker_wizard.cpp"