1 /* ============================================================
2 *
3 * This file is a part of KDE project
4 *
5 *
6 * Date : 2005-07-07
7 * Description : a kipi plugin to export images to Flickr web service
8 *
9 * Copyright (C) 2005-2009 by Vardhman Jain <vardhman at gmail dot com>
10 * Copyright (C) 2009-2018 by Gilles Caulier <caulier dot gilles at gmail dot com>
11 * Copyright (C) 2017 by Maik Qualmann <metzpinguin at gmail dot com>
12 *
13 * This program is free software; you can redistribute it
14 * and/or modify it under the terms of the GNU General
15 * Public License as published by the Free Software Foundation;
16 * either version 2, or (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * ============================================================ */
24
25 #include "flickrtalker.h"
26
27 // Qt includes
28
29 #include <QByteArray>
30 #include <QDomDocument>
31 #include <QDomElement>
32 #include <QFile>
33 #include <QFileInfo>
34 #include <QImage>
35 #include <QMap>
36 #include <QStringList>
37 #include <QProgressDialog>
38 #include <QStandardPaths>
39 #include <QApplication>
40 #include <QDesktopServices>
41 #include <QMessageBox>
42
43 // Libkipi includes
44
45 #include <KIPI/PluginLoader>
46
47 // Local includes
48
49 #include "kputil.h"
50 #include "kpversion.h"
51 #include "mpform.h"
52 #include "flickritem.h"
53 #include "flickrwindow.h"
54 #include "kipiplugins_debug.h"
55
56 using namespace KIPIPlugins;
57
58 namespace KIPIFlickrPlugin
59 {
60
FlickrTalker(QWidget * const parent,const QString & serviceName)61 FlickrTalker::FlickrTalker(QWidget* const parent, const QString& serviceName)
62 {
63 m_parent = parent;
64 m_netMngr = nullptr;
65 m_reply = nullptr;
66 m_settings = nullptr;
67 m_photoSetsList = nullptr;
68 m_authProgressDlg = nullptr;
69 m_state = FE_LOGOUT;
70 m_serviceName = serviceName;
71 m_iface = nullptr;
72 m_o1 = nullptr;
73 m_store = nullptr;
74 m_requestor = nullptr;
75
76 PluginLoader* const pl = PluginLoader::instance();
77
78 if (pl)
79 {
80 m_iface = pl->interface();
81 }
82
83 if (serviceName == QLatin1String("23"))
84 {
85 m_apiUrl = QLatin1String("http://www.23hq.com/services/rest/");
86 m_authUrl = QLatin1String("http://www.23hq.com/services/auth/");
87 m_uploadUrl = QLatin1String("http://www.23hq.com/services/upload/");
88
89 // bshanks: do 23 and flickr really share API keys? or does 23 not need
90 // one?
91 m_apikey = QLatin1String("49d585bafa0758cb5c58ab67198bf632");
92 m_secret = QLatin1String("34b39925e6273ffd");
93 }
94 else
95 {
96 m_apiUrl = QLatin1String("https://www.flickr.com/services/rest/");
97 m_authUrl = QLatin1String("https://www.flickr.com/services/oauth/authorize?perms=write");
98 m_tokenUrl = QLatin1String("https://www.flickr.com/services/oauth/request_token");
99 m_accessUrl = QLatin1String("https://www.flickr.com/services/oauth/access_token");
100 m_uploadUrl = QLatin1String("https://up.flickr.com/services/upload/");
101
102 m_apikey = QLatin1String("49d585bafa0758cb5c58ab67198bf632");
103 m_secret = QLatin1String("34b39925e6273ffd");
104 }
105
106 m_netMngr = new QNetworkAccessManager(this);
107
108 connect(m_netMngr, SIGNAL(finished(QNetworkReply*)),
109 this, SLOT(slotFinished(QNetworkReply*)));
110
111 /* Initialize selected photo set as empty. */
112 m_selectedPhotoSet = FPhotoSet();
113 /* Initialize photo sets list. */
114 m_photoSetsList = new QLinkedList<FPhotoSet>();
115
116 m_o1 = new O1(this);
117
118 m_o1->setClientId(m_apikey);
119 m_o1->setClientSecret(m_secret);
120 m_o1->setAuthorizeUrl(QUrl(m_authUrl));
121 m_o1->setAccessTokenUrl(QUrl(m_accessUrl));
122 m_o1->setRequestTokenUrl(QUrl(m_tokenUrl));
123
124 QString kipioauth = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QLatin1String("/kipioauthrc");
125
126 m_settings = new QSettings(kipioauth, QSettings::IniFormat, this);
127 m_store = new O0SettingsStore(m_settings, QLatin1String(O2_ENCRYPTION_KEY), this);
128 m_store->setGroupKey(m_serviceName);
129 m_o1->setStore(m_store);
130
131 connect(m_o1, SIGNAL(linkingFailed()),
132 this, SLOT(slotLinkingFailed()));
133
134 connect(m_o1, SIGNAL(linkingSucceeded()),
135 this, SLOT(slotLinkingSucceeded()));
136
137 connect(m_o1, SIGNAL(openBrowser(QUrl)),
138 this, SLOT(slotOpenBrowser(QUrl)));
139
140 m_requestor = new O1Requestor(m_netMngr, m_o1, this);
141 }
142
~FlickrTalker()143 FlickrTalker::~FlickrTalker()
144 {
145 if (m_reply)
146 {
147 m_reply->abort();
148 }
149
150 delete m_photoSetsList;
151
152 removeTemporaryDir(m_serviceName.toLatin1().constData());
153 }
154
link(const QString & userName)155 void FlickrTalker::link(const QString& userName)
156 {
157 emit signalBusy(true);
158
159 if (userName.isEmpty())
160 {
161 m_store->setGroupKey(m_serviceName);
162 }
163 else
164 {
165 m_store->setGroupKey(m_serviceName + userName);
166 }
167
168 m_o1->link();
169 }
170
unLink()171 void FlickrTalker::unLink()
172 {
173 m_o1->unlink();
174 }
175
removeUserName(const QString & userName)176 void FlickrTalker::removeUserName(const QString& userName)
177 {
178 if (userName.startsWith(m_serviceName))
179 {
180 m_settings->beginGroup(userName);
181 m_settings->remove(QString());
182 m_settings->endGroup();
183 }
184 }
185
slotLinkingFailed()186 void FlickrTalker::slotLinkingFailed()
187 {
188 qCDebug(KIPIPLUGINS_LOG) << "LINK to Flickr fail";
189 m_username = QString();
190 emit signalBusy(false);
191 }
192
slotLinkingSucceeded()193 void FlickrTalker::slotLinkingSucceeded()
194 {
195 if (!m_o1->linked())
196 {
197 qCDebug(KIPIPLUGINS_LOG) << "UNLINK to Flickr ok";
198 m_username = QString();
199 return;
200 }
201
202 qCDebug(KIPIPLUGINS_LOG) << "LINK to Flickr ok";
203
204 m_username = m_o1->extraTokens()[QLatin1String("username")].toString();
205 m_userId = m_o1->extraTokens()[QLatin1String("user_nsid")].toString();
206
207 if (m_store->groupKey() == m_serviceName)
208 {
209 m_settings->beginGroup(m_serviceName);
210 QStringList keys = m_settings->allKeys();
211 m_settings->endGroup();
212
213 foreach(const QString& key, keys)
214 {
215 m_settings->beginGroup(m_serviceName);
216 QVariant value = m_settings->value(key);
217 m_settings->endGroup();
218 m_settings->beginGroup(m_serviceName + m_username);
219 m_settings->setValue(key, value);
220 m_settings->endGroup();
221 }
222
223 m_store->setGroupKey(m_serviceName + m_username);
224 removeUserName(m_serviceName);
225 }
226
227 emit signalLinkingSucceeded();
228 }
229
slotOpenBrowser(const QUrl & url)230 void FlickrTalker::slotOpenBrowser(const QUrl& url)
231 {
232 qCDebug(KIPIPLUGINS_LOG) << "Open Browser...";
233 QDesktopServices::openUrl(url);
234 }
235
getMaxAllowedFileSize()236 QString FlickrTalker::getMaxAllowedFileSize()
237 {
238 return m_maxSize;
239 }
240
maxAllowedFileSize()241 void FlickrTalker::maxAllowedFileSize()
242 {
243 if (m_reply)
244 {
245 m_reply->abort();
246 m_reply = nullptr;
247 }
248
249 if (!m_o1->linked())
250 return;
251
252 QUrl url(m_apiUrl);
253 QNetworkRequest netRequest(url);
254 QList<O0RequestParameter> reqParams = QList<O0RequestParameter>();
255
256 netRequest.setHeader(QNetworkRequest::ContentTypeHeader, QLatin1String(O2_MIME_TYPE_XFORM));
257
258 reqParams << O0RequestParameter("method", "flickr.people.getLimits");
259
260 QByteArray postData = O1::createQueryParameters(reqParams);
261
262 m_reply = m_requestor->post(netRequest, reqParams, postData);
263
264 m_state = FE_GETMAXSIZE;
265 m_authProgressDlg->setLabelText(i18n("Getting the maximum allowed file size."));
266 m_authProgressDlg->setMaximum(4);
267 m_authProgressDlg->setValue(1);
268 m_buffer.resize(0);
269 emit signalBusy(true);
270 }
271
listPhotoSets()272 void FlickrTalker::listPhotoSets()
273 {
274 if (m_reply)
275 {
276 m_reply->abort();
277 m_reply = nullptr;
278 }
279
280 if (!m_o1->linked())
281 return;
282
283 qCDebug(KIPIPLUGINS_LOG) << "List photoset invoked";
284
285 QUrl url(m_apiUrl);
286 QNetworkRequest netRequest(url);
287 QList<O0RequestParameter> reqParams = QList<O0RequestParameter>();
288
289 netRequest.setHeader(QNetworkRequest::ContentTypeHeader, QLatin1String(O2_MIME_TYPE_XFORM));
290
291 reqParams << O0RequestParameter("method", "flickr.photosets.getList");
292
293 QByteArray postData = O1::createQueryParameters(reqParams);
294
295 m_reply = m_requestor->post(netRequest, reqParams, postData);
296
297 m_state = FE_LISTPHOTOSETS;
298 m_buffer.resize(0);
299 emit signalBusy(true);
300 }
301
getPhotoProperty(const QString & method,const QStringList & argList)302 void FlickrTalker::getPhotoProperty(const QString& method, const QStringList& argList)
303 {
304 if (m_reply)
305 {
306 m_reply->abort();
307 m_reply = nullptr;
308 }
309
310 if (!m_o1->linked())
311 return;
312
313 QUrl url(m_apiUrl);
314 QNetworkRequest netRequest(url);
315 QList<O0RequestParameter> reqParams = QList<O0RequestParameter>();
316
317 netRequest.setHeader(QNetworkRequest::ContentTypeHeader, QLatin1String(O2_MIME_TYPE_XFORM));
318
319 reqParams << O0RequestParameter("method", method.toLatin1());
320
321 for (QStringList::const_iterator it = argList.constBegin(); it != argList.constEnd(); ++it)
322 {
323 QStringList str = (*it).split(QLatin1Char('='), QString::SkipEmptyParts);
324 reqParams << O0RequestParameter(str[0].toLatin1(), str[1].toLatin1());
325 }
326
327 QByteArray postData = O1::createQueryParameters(reqParams);
328
329 m_reply = m_requestor->post(netRequest, reqParams, postData);
330
331 m_state = FE_GETPHOTOPROPERTY;
332 m_buffer.resize(0);
333 emit signalBusy(true);
334 }
335
listPhotos(const QString &)336 void FlickrTalker::listPhotos(const QString& /*albumName*/)
337 {
338 // TODO
339 }
340
createPhotoSet(const QString &,const QString & albumTitle,const QString & albumDescription,const QString & primaryPhotoId)341 void FlickrTalker::createPhotoSet(const QString& /*albumName*/, const QString& albumTitle,
342 const QString& albumDescription, const QString& primaryPhotoId)
343 {
344 if (m_reply)
345 {
346 m_reply->abort();
347 m_reply = nullptr;
348 }
349
350 if (!m_o1->linked())
351 return;
352
353 qCDebug(KIPIPLUGINS_LOG) << "Create photoset invoked";
354
355 QUrl url(m_apiUrl);
356 QNetworkRequest netRequest(url);
357 QList<O0RequestParameter> reqParams = QList<O0RequestParameter>();
358
359 netRequest.setHeader(QNetworkRequest::ContentTypeHeader, QLatin1String(O2_MIME_TYPE_XFORM));
360
361 reqParams << O0RequestParameter("method", "flickr.photosets.create");
362 reqParams << O0RequestParameter("title", albumTitle.toLatin1());
363 reqParams << O0RequestParameter("description", albumDescription.toLatin1());
364 reqParams << O0RequestParameter("primary_photo_id", primaryPhotoId.toLatin1());
365
366 QByteArray postData = O1::createQueryParameters(reqParams);
367
368 m_reply = m_requestor->post(netRequest, reqParams, postData);
369
370 m_state = FE_CREATEPHOTOSET;
371 m_buffer.resize(0);
372 emit signalBusy(true);
373 }
374
addPhotoToPhotoSet(const QString & photoId,const QString & photoSetId)375 void FlickrTalker::addPhotoToPhotoSet(const QString& photoId,
376 const QString& photoSetId)
377 {
378 if (m_reply)
379 {
380 m_reply->abort();
381 m_reply = nullptr;
382 }
383
384 if (!m_o1->linked())
385 return;
386
387 qCDebug(KIPIPLUGINS_LOG) << "AddPhotoToPhotoSet invoked";
388
389 /* If the photoset id starts with the special string "UNDEFINED_", it means
390 * it doesn't exist yet on Flickr and needs to be created. Note that it's
391 * not necessary to subsequently add the photo to the photo set, as this
392 * is done in the set creation call to Flickr. */
393 if (photoSetId.startsWith(QLatin1String("UNDEFINED_")))
394 {
395 createPhotoSet(QLatin1String(""), m_selectedPhotoSet.title, m_selectedPhotoSet.description, photoId);
396 }
397 else
398 {
399 QUrl url(m_apiUrl);
400 QNetworkRequest netRequest(url);
401 QList<O0RequestParameter> reqParams = QList<O0RequestParameter>();
402
403 netRequest.setHeader(QNetworkRequest::ContentTypeHeader, QLatin1String(O2_MIME_TYPE_XFORM));
404
405 reqParams << O0RequestParameter("method", "flickr.photosets.addPhoto");
406 reqParams << O0RequestParameter("photoset_id", photoSetId.toLatin1());
407 reqParams << O0RequestParameter("photo_id", photoId.toLatin1());
408
409 QByteArray postData = O1::createQueryParameters(reqParams);
410
411 m_reply = m_requestor->post(netRequest, reqParams, postData);
412
413 m_state = FE_ADDPHOTOTOPHOTOSET;
414 m_buffer.resize(0);
415 emit signalBusy(true);
416 }
417 }
418
addPhoto(const QString & photoPath,const FPhotoInfo & info,bool original,bool rescale,int maxDim,int imageQuality)419 bool FlickrTalker::addPhoto(const QString& photoPath, const FPhotoInfo& info,
420 bool original, bool rescale, int maxDim, int imageQuality)
421 {
422 if (m_reply)
423 {
424 m_reply->abort();
425 m_reply = nullptr;
426 }
427
428 if (!m_o1->linked())
429 return false;
430
431 QUrl url(m_uploadUrl);
432 QNetworkRequest netRequest(url);
433 QList<O0RequestParameter> reqParams = QList<O0RequestParameter>();
434
435 QString path = photoPath;
436 MPForm form;
437
438 QString ispublic = (info.is_public == 1) ? QLatin1String("1") : QLatin1String("0");
439 form.addPair(QLatin1String("is_public"), ispublic, QLatin1String("text/plain"));
440 reqParams << O0RequestParameter("is_public", ispublic.toLatin1());
441
442 QString isfamily = (info.is_family == 1) ? QLatin1String("1") : QLatin1String("0");
443 form.addPair(QLatin1String("is_family"), isfamily, QLatin1String("text/plain"));
444 reqParams << O0RequestParameter("is_family", isfamily.toLatin1());
445
446 QString isfriend = (info.is_friend == 1) ? QLatin1String("1") : QLatin1String("0");
447 form.addPair(QLatin1String("is_friend"), isfriend, QLatin1String("text/plain"));
448 reqParams << O0RequestParameter("is_friend", isfriend.toLatin1());
449
450 QString safetyLevel = QString::number(static_cast<int>(info.safety_level));
451 form.addPair(QLatin1String("safety_level"), safetyLevel, QLatin1String("text/plain"));
452 reqParams << O0RequestParameter("safety_level", safetyLevel.toLatin1());
453
454 QString contentType = QString::number(static_cast<int>(info.content_type));
455 form.addPair(QLatin1String("content_type"), contentType, QLatin1String("text/plain"));
456 reqParams << O0RequestParameter("content_type", contentType.toLatin1());
457
458 QString tags = QLatin1String("\"") + info.tags.join(QLatin1String("\" \"")) + QLatin1String("\"");
459
460 if (tags.length() > 0)
461 {
462 form.addPair(QLatin1String("tags"), tags, QLatin1String("text/plain"));
463 reqParams << O0RequestParameter("tags", tags.toUtf8());
464 }
465
466 if (!info.title.isEmpty())
467 {
468 form.addPair(QLatin1String("title"), info.title, QLatin1String("text/plain"));
469 reqParams << O0RequestParameter("title", info.title.toUtf8());
470 }
471
472 if (!info.description.isEmpty())
473 {
474 form.addPair(QLatin1String("description"), info.description, QLatin1String("text/plain"));
475 reqParams << O0RequestParameter("description", info.description.toUtf8());
476 }
477
478 if (!original)
479 {
480 QImage image;
481
482 if (m_iface)
483 {
484 image = m_iface->preview(QUrl::fromLocalFile(photoPath));
485 }
486
487 if (image.isNull())
488 {
489 image.load(photoPath);
490 }
491
492 if (!image.isNull())
493 {
494 if (!m_lastTmpFile.isEmpty())
495 {
496 QFile::remove(m_lastTmpFile);
497 }
498
499 path = makeTemporaryDir(m_serviceName.toLatin1().constData()).filePath(QFileInfo(photoPath)
500 .baseName().trimmed() + QLatin1String(".jpg"));
501
502 if (rescale)
503 {
504 if (image.width() > maxDim || image.height() > maxDim)
505 image = image.scaled(maxDim, maxDim, Qt::KeepAspectRatio, Qt::SmoothTransformation);
506 }
507
508 image.save(path, "JPEG", imageQuality);
509 m_lastTmpFile = path;
510
511 // Restore all metadata.
512
513 if (m_iface)
514 {
515 QPointer<MetadataProcessor> meta = m_iface->createMetadataProcessor();
516
517 if (meta && meta->load(QUrl::fromLocalFile(photoPath)))
518 {
519 meta->setImageDimensions(image.size());
520 meta->setImageOrientation(MetadataProcessor::NORMAL);
521
522 // NOTE: see bug #153207: Flickr use IPTC keywords to create Tags in web interface
523 // As IPTC do not support UTF-8, we need to remove it.
524 // This function call remove all Application2 Tags.
525 meta->removeIptcTags(QStringList() << QLatin1String("Application2"));
526 // NOTE: see bug # 384260: Flickr use Xmp.dc.subject to create Tags
527 // in web interface, we need to remove it.
528 // This function call remove all Dublin Core Tags.
529 meta->removeXmpTags(QStringList() << QLatin1String("dc"));
530
531 meta->setImageProgramId(QLatin1String("Kipi-plugins"), kipipluginsVersion());
532 meta->save(QUrl::fromLocalFile(path), true);
533 }
534 else
535 {
536 qCWarning(KIPIPLUGINS_LOG) << "flickrExport::Image doesn't have metadata";
537 }
538 }
539
540 qCDebug(KIPIPLUGINS_LOG) << "Resizing and saving to temp file: " << path;
541 }
542 }
543
544 QFileInfo tempFileInfo(path);
545
546 qCDebug(KIPIPLUGINS_LOG) << "QUrl path is " << QUrl::fromLocalFile(path) << "Image size (in bytes) is "<< tempFileInfo.size();
547
548 if (tempFileInfo.size() > (getMaxAllowedFileSize().toLongLong()))
549 {
550 emit signalAddPhotoFailed(i18n("File Size exceeds maximum allowed file size."));
551 return false;
552 }
553
554 if (!form.addFile(QLatin1String("photo"), path))
555 {
556 return false;
557 }
558
559 form.finish();
560
561 netRequest.setHeader(QNetworkRequest::ContentTypeHeader, form.contentType());
562
563 m_reply = m_requestor->post(netRequest, reqParams, form.formData());
564
565 m_state = FE_ADDPHOTO;
566 m_buffer.resize(0);
567 emit signalBusy(true);
568 return true;
569 }
570
getUserName() const571 QString FlickrTalker::getUserName() const
572 {
573 return m_username;
574 }
575
getUserId() const576 QString FlickrTalker::getUserId() const
577 {
578 return m_userId;
579 }
580
cancel()581 void FlickrTalker::cancel()
582 {
583 if (m_reply)
584 {
585 m_reply->abort();
586 m_reply = nullptr;
587 }
588
589 if (m_authProgressDlg && !m_authProgressDlg->isHidden())
590 {
591 m_authProgressDlg->hide();
592 }
593 }
594
slotError(const QString & error)595 void FlickrTalker::slotError(const QString& error)
596 {
597 QString transError;
598 int errorNo = error.toInt();
599
600 switch (errorNo)
601 {
602 case 2:
603 transError = i18n("No photo specified");
604 break;
605
606 case 3:
607 transError = i18n("General upload failure");
608 break;
609
610 case 4:
611 transError = i18n("Filesize was zero");
612 break;
613
614 case 5:
615 transError = i18n("Filetype was not recognized");
616 break;
617
618 case 6:
619 transError = i18n("User exceeded upload limit");
620 break;
621
622 case 96:
623 transError = i18n("Invalid signature");
624 break;
625
626 case 97:
627 transError = i18n("Missing signature");
628 break;
629
630 case 98:
631 transError = i18n("Login Failed / Invalid auth token");
632 break;
633
634 case 100:
635 transError = i18n("Invalid API Key");
636 break;
637
638 case 105:
639 transError = i18n("Service currently unavailable");
640 break;
641
642 case 108:
643 transError = i18n("Invalid Frob");
644 break;
645
646 case 111:
647 transError = i18n("Format \"xxx\" not found");
648 break;
649
650 case 112:
651 transError = i18n("Method \"xxx\" not found");
652 break;
653
654 case 114:
655 transError = i18n("Invalid SOAP envelope");
656 break;
657
658 case 115:
659 transError = i18n("Invalid XML-RPC Method Call");
660 break;
661
662 case 116:
663 transError = i18n("The POST method is now required for all setters");
664 break;
665
666 default:
667 transError = i18n("Unknown error");
668 break;
669 };
670
671 QMessageBox::critical(QApplication::activeWindow(),
672 i18n("Error"),
673 i18n("Error Occurred: %1\nCannot proceed any further.", transError));
674 }
675
slotFinished(QNetworkReply * reply)676 void FlickrTalker::slotFinished(QNetworkReply* reply)
677 {
678 emit signalBusy(false);
679
680 if (reply != m_reply)
681 {
682 return;
683 }
684
685 m_reply = nullptr;
686
687 if (reply->error() != QNetworkReply::NoError)
688 {
689 if (m_state == FE_ADDPHOTO)
690 {
691 emit signalAddPhotoFailed(reply->errorString());
692 }
693 else
694 {
695 QMessageBox::critical(QApplication::activeWindow(),
696 i18n("Error"), reply->errorString());
697 }
698
699 reply->deleteLater();
700 return;
701 }
702
703 m_buffer.append(reply->readAll());
704
705 switch (m_state)
706 {
707 case (FE_LOGIN):
708 //parseResponseLogin(m_buffer);
709 break;
710
711 case (FE_LISTPHOTOSETS):
712 parseResponseListPhotoSets(m_buffer);
713 break;
714
715 case (FE_LISTPHOTOS):
716 parseResponseListPhotos(m_buffer);
717 break;
718
719 case (FE_GETPHOTOPROPERTY):
720 parseResponsePhotoProperty(m_buffer);
721 break;
722
723 case (FE_ADDPHOTO):
724 parseResponseAddPhoto(m_buffer);
725 break;
726
727 case (FE_ADDPHOTOTOPHOTOSET):
728 parseResponseAddPhotoToPhotoSet(m_buffer);
729 break;
730
731 case (FE_CREATEPHOTOSET):
732 parseResponseCreatePhotoSet(m_buffer);
733 break;
734
735 case (FE_GETMAXSIZE):
736 parseResponseMaxSize(m_buffer);
737 break;
738
739 default: // FR_LOGOUT
740 break;
741 }
742
743 reply->deleteLater();
744 }
745
parseResponseMaxSize(const QByteArray & data)746 void FlickrTalker::parseResponseMaxSize(const QByteArray& data)
747 {
748 QString errorString;
749 QDomDocument doc(QLatin1String("mydocument"));
750
751 if (!doc.setContent(data))
752 {
753 return;
754 }
755
756 QDomElement docElem = doc.documentElement();
757 QDomNode node = docElem.firstChild();
758
759 QDomElement e;
760
761 while (!node.isNull())
762 {
763 if (node.isElement() && node.nodeName() == QLatin1String("person"))
764 {
765 e = node.toElement();
766 QDomNode details = e.firstChild();
767
768 while (!details.isNull())
769 {
770 if (details.isElement())
771 {
772 e = details.toElement();
773
774 if (details.nodeName() == QLatin1String("photos"))
775 {
776 QDomAttr a = e.attributeNode(QLatin1String("maxupload"));
777 m_maxSize = a.value();
778 qCDebug(KIPIPLUGINS_LOG) << "Max upload size is"<<m_maxSize;
779 }
780 }
781
782 details = details.nextSibling();
783 }
784 }
785
786 if (node.isElement() && node.nodeName() == QLatin1String("err"))
787 {
788 qCDebug(KIPIPLUGINS_LOG) << "Checking Error in response";
789 errorString = node.toElement().attribute(QLatin1String("code"));
790 qCDebug(KIPIPLUGINS_LOG) << "Error code=" << errorString;
791 qCDebug(KIPIPLUGINS_LOG) << "Msg=" << node.toElement().attribute(QLatin1String("msg"));
792 }
793
794 node = node.nextSibling();
795 }
796
797 m_authProgressDlg->hide();
798 }
799
parseResponseCreatePhotoSet(const QByteArray & data)800 void FlickrTalker::parseResponseCreatePhotoSet(const QByteArray& data)
801 {
802 qCDebug(KIPIPLUGINS_LOG) << "Parse response create photoset received " << data;
803
804 //bool success = false;
805
806 QDomDocument doc(QLatin1String("getListPhotoSets"));
807
808 if (!doc.setContent(data))
809 {
810 return;
811 }
812
813 QDomElement docElem = doc.documentElement();
814 QDomNode node = docElem.firstChild();
815 QDomElement e;
816
817 while (!node.isNull())
818 {
819 if (node.isElement() && node.nodeName() == QLatin1String("photoset"))
820 {
821 // Parse the id from the response.
822 QString new_id = node.toElement().attribute(QLatin1String("id"));
823
824 // Set the new id in the photo sets list.
825 QLinkedList<FPhotoSet>::iterator it = m_photoSetsList->begin();
826
827 while (it != m_photoSetsList->end())
828 {
829 if (it->id == m_selectedPhotoSet.id)
830 {
831 it->id = new_id;
832 break;
833 }
834
835 ++it;
836 }
837
838 // Set the new id in the selected photo set.
839 m_selectedPhotoSet.id = new_id;
840
841 qCDebug(KIPIPLUGINS_LOG) << "PhotoSet created successfully with id" << new_id;
842 emit signalAddPhotoSetSucceeded();
843 }
844
845 if (node.isElement() && node.nodeName() == QLatin1String("err"))
846 {
847 qCDebug(KIPIPLUGINS_LOG) << "Checking Error in response";
848 QString code = node.toElement().attribute(QLatin1String("code"));
849 qCDebug(KIPIPLUGINS_LOG) << "Error code=" << code;
850 QString msg = node.toElement().attribute(QLatin1String("msg"));
851 qCDebug(KIPIPLUGINS_LOG) << "Msg=" << msg;
852 QMessageBox::critical(QApplication::activeWindow(), i18n("Error"), i18n("PhotoSet creation failed: ") + msg);
853 }
854
855 node = node.nextSibling();
856 }
857 }
858
parseResponseListPhotoSets(const QByteArray & data)859 void FlickrTalker::parseResponseListPhotoSets(const QByteArray& data)
860 {
861 qCDebug(KIPIPLUGINS_LOG) << "parseResponseListPhotosets" << data;
862 bool success = false;
863 QDomDocument doc(QLatin1String("getListPhotoSets"));
864
865 if (!doc.setContent(data))
866 {
867 return;
868 }
869
870 QDomElement docElem = doc.documentElement();
871 QDomNode node = docElem.firstChild();
872 QDomElement e;
873
874 QString photoSet_id, photoSet_title, photoSet_description;
875 m_photoSetsList->clear();
876
877 while (!node.isNull())
878 {
879 if (node.isElement() && node.nodeName() == QLatin1String("photosets"))
880 {
881 e = node.toElement();
882 QDomNode details = e.firstChild();
883 FPhotoSet fps;
884 QDomNode detailsNode = details;
885
886 while (!detailsNode.isNull())
887 {
888 if (detailsNode.isElement())
889 {
890 e = detailsNode.toElement();
891
892 if (detailsNode.nodeName() == QLatin1String("photoset"))
893 {
894 qCDebug(KIPIPLUGINS_LOG) << "id=" << e.attribute(QLatin1String("id"));
895 photoSet_id = e.attribute(QLatin1String("id")); // this is what is obtained from data.
896 fps.id = photoSet_id;
897 QDomNode photoSetDetails = detailsNode.firstChild();
898 QDomElement e_detail;
899
900 while (!photoSetDetails.isNull())
901 {
902 e_detail = photoSetDetails.toElement();
903
904 if (photoSetDetails.nodeName() == QLatin1String("title"))
905 {
906 qCDebug(KIPIPLUGINS_LOG) << "Title=" << e_detail.text();
907 photoSet_title = e_detail.text();
908 fps.title = photoSet_title;
909 }
910 else if (photoSetDetails.nodeName() == QLatin1String("description"))
911 {
912 qCDebug(KIPIPLUGINS_LOG) << "Description =" << e_detail.text();
913 photoSet_description = e_detail.text();
914 fps.description = photoSet_description;
915 }
916
917 photoSetDetails = photoSetDetails.nextSibling();
918 }
919
920 m_photoSetsList->append(fps);
921 }
922 }
923
924 detailsNode = detailsNode.nextSibling();
925 }
926
927 details = details.nextSibling();
928 success = true;
929 }
930
931 if (node.isElement() && node.nodeName() == QLatin1String("err"))
932 {
933 qCDebug(KIPIPLUGINS_LOG) << "Checking Error in response";
934 QString code = node.toElement().attribute(QLatin1String("code"));
935 qCDebug(KIPIPLUGINS_LOG) << "Error code=" << code;
936 qCDebug(KIPIPLUGINS_LOG) << "Msg=" << node.toElement().attribute(QLatin1String("msg"));
937 emit signalError(code);
938 }
939
940 node = node.nextSibling();
941 }
942
943 qCDebug(KIPIPLUGINS_LOG) << "GetPhotoList finished";
944
945 if (!success)
946 {
947 emit signalListPhotoSetsFailed(i18n("Failed to fetch list of photo sets."));
948 }
949 else
950 {
951 emit signalListPhotoSetsSucceeded();
952 maxAllowedFileSize();
953 }
954 }
955
parseResponseListPhotos(const QByteArray & data)956 void FlickrTalker::parseResponseListPhotos(const QByteArray& data)
957 {
958 QDomDocument doc(QLatin1String("getPhotosList"));
959
960 if (!doc.setContent(data))
961 {
962 return;
963 }
964
965 QDomElement docElem = doc.documentElement();
966 QDomNode node = docElem.firstChild();
967 //QDomElement e;
968 //TODO
969 }
970
parseResponseCreateAlbum(const QByteArray & data)971 void FlickrTalker::parseResponseCreateAlbum(const QByteArray& data)
972 {
973 QDomDocument doc(QLatin1String("getCreateAlbum"));
974
975 if (!doc.setContent(data))
976 {
977 return;
978 }
979
980 QDomElement docElem = doc.documentElement();
981 QDomNode node = docElem.firstChild();
982
983 //TODO
984 }
985
parseResponseAddPhoto(const QByteArray & data)986 void FlickrTalker::parseResponseAddPhoto(const QByteArray& data)
987 {
988 bool success = false;
989 QString line;
990 QDomDocument doc(QLatin1String("AddPhoto Response"));
991
992 if (!doc.setContent(data))
993 {
994 return;
995 }
996
997 QDomElement docElem = doc.documentElement();
998 QDomNode node = docElem.firstChild();
999 QDomElement e;
1000 QString photoId;
1001
1002 while (!node.isNull())
1003 {
1004 if (node.isElement() && node.nodeName() == QLatin1String("photoid"))
1005 {
1006 e = node.toElement(); // try to convert the node to an element.
1007 QDomNode details = e.firstChild();
1008 photoId = e.text();
1009 qCDebug(KIPIPLUGINS_LOG) << "Photoid= " << photoId;
1010 success = true;
1011 }
1012
1013 if (node.isElement() && node.nodeName() == QLatin1String("err"))
1014 {
1015 qCDebug(KIPIPLUGINS_LOG) << "Checking Error in response";
1016 QString code = node.toElement().attribute(QLatin1String("code"));
1017 qCDebug(KIPIPLUGINS_LOG) << "Error code=" << code;
1018 qCDebug(KIPIPLUGINS_LOG) << "Msg=" << node.toElement().attribute(QLatin1String("msg"));
1019 emit signalError(code);
1020 }
1021
1022 node = node.nextSibling();
1023 }
1024
1025 if (!success)
1026 {
1027 emit signalAddPhotoFailed(i18n("Failed to upload photo"));
1028 }
1029 else
1030 {
1031 QString photoSetId = m_selectedPhotoSet.id;
1032
1033 if (photoSetId == QLatin1String("-1"))
1034 {
1035 qCDebug(KIPIPLUGINS_LOG) << "PhotoSet Id not set, not adding the photo to any photoset";
1036 emit signalAddPhotoSucceeded();
1037 }
1038 else
1039 {
1040 addPhotoToPhotoSet(photoId, photoSetId);
1041 }
1042 }
1043 }
1044
parseResponsePhotoProperty(const QByteArray & data)1045 void FlickrTalker::parseResponsePhotoProperty(const QByteArray& data)
1046 {
1047 bool success = false;
1048 QString line;
1049 QDomDocument doc(QLatin1String("Photos Properties"));
1050
1051 if (!doc.setContent(data))
1052 {
1053 return;
1054 }
1055
1056 QDomElement docElem = doc.documentElement();
1057 QDomNode node = docElem.firstChild();
1058 QDomElement e;
1059
1060 while (!node.isNull())
1061 {
1062 if (node.isElement() && node.nodeName() == QLatin1String("photoid"))
1063 {
1064 e = node.toElement(); // try to convert the node to an element.
1065 QDomNode details = e.firstChild();
1066 success = true;
1067 qCDebug(KIPIPLUGINS_LOG) << "Photoid=" << e.text();
1068 }
1069
1070 if (node.isElement() && node.nodeName() == QLatin1String("err"))
1071 {
1072 qCDebug(KIPIPLUGINS_LOG) << "Checking Error in response";
1073 QString code = node.toElement().attribute(QLatin1String("code"));
1074 qCDebug(KIPIPLUGINS_LOG) << "Error code=" << code;
1075 qCDebug(KIPIPLUGINS_LOG) << "Msg=" << node.toElement().attribute(QLatin1String("msg"));
1076 emit signalError(code);
1077 }
1078
1079 node = node.nextSibling();
1080 }
1081
1082 qCDebug(KIPIPLUGINS_LOG) << "GetToken finished";
1083
1084 if (!success)
1085 {
1086 emit signalAddPhotoFailed(i18n("Failed to query photo information"));
1087 }
1088 else
1089 {
1090 emit signalAddPhotoSucceeded();
1091 }
1092 }
1093
parseResponseAddPhotoToPhotoSet(const QByteArray & data)1094 void FlickrTalker::parseResponseAddPhotoToPhotoSet(const QByteArray& data)
1095 {
1096 qCDebug(KIPIPLUGINS_LOG) << "parseResponseListPhotosets" << data;
1097 emit signalAddPhotoSucceeded();
1098 }
1099
1100 } // namespace KIPIFlickrPlugin
1101