1
/* ============================================================
3
* This file is a part of kipi-plugins project
4
* http://www.kipi-plugins.org
7
* Description : a kipi plugin to export images to Picasa web service
9
* Copyright (C) 2007-2008 by Vardhman Jain <vardhman at gmail dot com>
10
* Copyright (C) 2008-2010 by Gilles Caulier <caulier dot gilles at gmail dot com>
11
* Copyright (C) 2009 by Luka Renko <lure at kubuntu dot org>
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.
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.
23
* ============================================================ */
25
#include "picasawebtalker.moc"
36
#include <QTextDocument>
38
#include <QDomDocument>
39
#include <QDomElement>
44
#include <QLinkedList>
45
#include <QStringList>
51
#include <kapplication.h>
55
#include <kio/jobclasses.h>
56
#include <kio/jobuidelegate.h>
57
#include <klineedit.h>
59
#include <kmessagebox.h>
60
#include <kmimetype.h>
61
#include <kstandarddirs.h>
66
#include <libkexiv2/kexiv2.h>
70
#include <libkdcraw/version.h>
71
#include <libkdcraw/kdcraw.h>
76
#include "picasawebitem.h"
77
#include "picasaweblogin.h"
78
#include "picasawebwindow.h"
79
#include "pluginsversion.h"
83
namespace KIPIPicasawebExportPlugin
86
PicasawebTalker::PicasawebTalker( QWidget* parent )
87
: m_parent( parent ), m_job( 0 )
89
connect(this, SIGNAL(signalError(QString)),
90
this, SLOT(slotError(QString)));
93
PicasawebTalker::~PicasawebTalker()
99
void PicasawebTalker::getToken(const QString& username, const QString& password )
107
QString url = "https://www.google.com/accounts/ClientLogin";
109
QPointer<PicasawebLogin> loginDialog = new PicasawebLogin(kapp->activeWindow(), i18n("Login"), username, password);
111
QString username_edit, password_edit;
113
if (loginDialog->exec() == QDialog::Accepted)
115
username_edit = loginDialog->username();
116
password_edit = loginDialog->password();
122
//Return something which say authentication needed.
126
m_username = username_edit;
127
QString accountType = "GOOGLE";
130
// do not encode username to support email adress
131
qsl.append("Email="+username_edit);
132
qsl.append("Passwd="+QUrl::toPercentEncoding(password_edit));
133
qsl.append("accountType="+accountType);
134
qsl.append("service=lh2");
135
qsl.append("source=kipi-picasaweb-client");
136
QString dataParameters = qsl.join("&");
138
buffer.append(dataParameters.toUtf8());
139
KIO::TransferJob* job = KIO::http_post(url, buffer, KIO::HideProgressInfo);
140
job->ui()->setWindow(m_parent);
141
job->addMetaData("content-type", "Content-Type: application/x-www-form-urlencoded" );
142
m_state = FE_GETTOKEN;
143
emit signalLoginProgress(1, 2, "Getting the token");
145
connect(job, SIGNAL(data(KIO::Job*,QByteArray)),
146
this, SLOT(data(KIO::Job*,QByteArray)));
148
connect(job, SIGNAL(result(KJob*)),
149
this, SLOT(slotResult(KJob*)));
153
emit signalBusy( true );
156
void PicasawebTalker::authenticate(const QString& token, const QString& username, const QString& password)
158
if (!token.isNull() || token.length() > 0)
160
kDebug() << " Checktoken being called" << token ;
161
m_username = username;
162
m_password = password; //this would be needed if the checktoken failed
163
//we would need to reauthenticate using auth
169
getToken(username, password);
173
void PicasawebTalker::checkToken(const QString& token)
181
KUrl url("http://picasaweb.google.com/data/feed/api");
182
url.addPath("/user/" + m_username);
183
kDebug() << " token value is " << token ;
184
QString auth_string = "GoogleLogin auth=" + token;
185
KIO::TransferJob* job = KIO::get(url, KIO::NoReload, KIO::HideProgressInfo);
186
job->ui()->setWindow(m_parent);
187
job->addMetaData("content-type", "Content-Type: application/x-www-form-urlencoded" );
188
job->addMetaData("customHTTPHeader", "Authorization: " + auth_string );
190
connect(job, SIGNAL(data(KIO::Job*,QByteArray)),
191
this, SLOT(data(KIO::Job*,QByteArray)));
193
connect(job, SIGNAL(result(KJob*)),
194
this, SLOT(slotResult(KJob*)));
196
m_state = FE_CHECKTOKEN;
197
emit signalLoginProgress(1, 2, "Checking if previous token is still valid");
200
emit signalBusy( true );
203
/** PicasaWeb's Album listing request/response
204
* First a request is sent to the url below and then we might(?) get a redirect URL
205
* WE then need to send the GET request to the Redirect url (this however gets taken care off by the
207
* This uses the authenticated album list fetching to get all the albums included the unlisted-albums
208
* which is not returned for an unauthorised request as done without the Authorization header.
210
void PicasawebTalker::listAlbums(const QString& username)
217
KUrl url("http://picasaweb.google.com/data/feed/api");
218
// do not encode username to support email adress
219
url.addPath("/user/" + username);
220
KIO::TransferJob* job = KIO::get(url, KIO::NoReload, KIO::HideProgressInfo);
221
job->ui()->setWindow(m_parent);
222
job->addMetaData("content-type", "Content-Type: application/x-www-form-urlencoded" );
223
if (!m_token.isEmpty())
225
QString auth_string = "GoogleLogin auth=" + m_token;
226
job->addMetaData("customHTTPHeader", "Authorization: " + auth_string );
229
connect(job, SIGNAL(data(KIO::Job*,QByteArray)),
230
this, SLOT(data(KIO::Job*,QByteArray)));
232
connect(job, SIGNAL(result(KJob*)),
233
this, SLOT(slotResult(KJob*)));
235
m_state = FE_LISTALBUMS;
238
emit signalBusy( true );
241
void PicasawebTalker::listPhotos(const QString& username,
242
const QString& albumId)
249
KUrl url("http://picasaweb.google.com/data/feed/api");
250
url.addPath("/user/" + username);
251
url.addPath("/albumid/" + albumId);
252
url.addQueryItem("thumbsize", "200");
253
KIO::TransferJob* job = KIO::get(url, KIO::NoReload, KIO::HideProgressInfo);
254
job->ui()->setWindow(m_parent);
255
job->addMetaData("content-type", "Content-Type: application/x-www-form-urlencoded" );
256
if (!m_token.isEmpty())
258
QString auth_string = "GoogleLogin auth=" + m_token;
259
job->addMetaData("customHTTPHeader", "Authorization: " + auth_string );
262
connect(job, SIGNAL(data(KIO::Job*,QByteArray)),
263
this, SLOT(data(KIO::Job*,QByteArray)));
265
connect(job, SIGNAL(result(KJob*)),
266
this, SLOT(slotResult(KJob*)));
268
m_state = FE_LISTPHOTOS;
271
emit signalBusy( true );
274
void PicasawebTalker::createAlbum(const PicasaWebAlbum& album)
282
//Create the Body in atom-xml
283
QDomDocument docMeta;
284
QDomProcessingInstruction instr = docMeta.createProcessingInstruction(
285
"xml", "version='1.0' encoding='UTF-8'");
286
docMeta.appendChild(instr);
287
QDomElement entryElem = docMeta.createElement("entry");
288
docMeta.appendChild(entryElem);
289
entryElem.setAttribute("xmlns", "http://www.w3.org/2005/Atom");
290
QDomElement titleElem = docMeta.createElement("title");
291
entryElem.appendChild(titleElem);
292
QDomText titleText = docMeta.createTextNode(album.title);
293
titleElem.appendChild(titleText);
294
QDomElement summaryElem = docMeta.createElement("summary");
295
entryElem.appendChild(summaryElem);
296
QDomText summaryText = docMeta.createTextNode(album.description);
297
summaryElem.appendChild(summaryText);
298
QDomElement locationElem = docMeta.createElementNS("http://schemas.google.com/photos/2007", "gphoto:location");
299
entryElem.appendChild(locationElem);
300
QDomText locationText = docMeta.createTextNode(album.location);
301
locationElem.appendChild(locationText);
302
QDomElement accessElem = docMeta.createElementNS("http://schemas.google.com/photos/2007", "gphoto:access");
303
entryElem.appendChild(accessElem);
304
QDomText accessText = docMeta.createTextNode(album.access);
305
accessElem.appendChild(accessText);
306
QDomElement commentElem = docMeta.createElementNS("http://schemas.google.com/photos/2007", "gphoto:commentingEnabled");
307
entryElem.appendChild(commentElem);
308
QDomText commentText = docMeta.createTextNode(album.canComment ? "true" : "false");
309
commentElem.appendChild(commentText);
310
QDomElement timestampElem = docMeta.createElementNS("http://schemas.google.com/photos/2007", "gphoto:timestamp");
311
entryElem.appendChild(timestampElem);
312
QDomText timestampText = docMeta.createTextNode(album.timestamp);
313
timestampElem.appendChild(timestampText);
314
QDomElement categoryElem = docMeta.createElement("category");
315
entryElem.appendChild(categoryElem);
316
categoryElem.setAttribute("scheme", "http://schemas.google.com/g/2005#kind");
317
categoryElem.setAttribute("term", "http://schemas.google.com/photos/2007#album");
318
QDomElement mediaGroupElem = docMeta.createElementNS("http://search.yahoo.com/mrss/", "media:group");
319
entryElem.appendChild(mediaGroupElem);
320
QDomElement mediaKeywordsElem = docMeta.createElementNS("http://search.yahoo.com/mrss/", "media:keywords");
321
mediaGroupElem.appendChild(mediaKeywordsElem);
322
QDomText mediaKeywordsText = docMeta.createTextNode(album.tags.join(","));
323
mediaKeywordsElem.appendChild(mediaKeywordsText);
326
buffer.append(docMeta.toString().toUtf8());
328
KUrl url("http://picasaweb.google.com/data/feed/api");
329
url.addPath("/user/" + m_username);
330
QString auth_string = "GoogleLogin auth=" + m_token;
331
KIO::TransferJob* job = KIO::http_post(url, buffer, KIO::HideProgressInfo);
332
job->ui()->setWindow(m_parent);
333
job->addMetaData("content-type", "Content-Type: application/atom+xml");
334
job->addMetaData("content-length", QString("Content-Length: %1").arg(buffer.length()));
335
job->addMetaData("customHTTPHeader", "Authorization: " + auth_string );
337
connect(job, SIGNAL(data(KIO::Job*,QByteArray)),
338
this, SLOT(data(KIO::Job*,QByteArray)));
340
connect(job, SIGNAL(result(KJob*)),
341
this, SLOT(slotResult(KJob*)));
343
m_state = FE_CREATEALBUM;
346
emit signalBusy(true);
349
bool PicasawebTalker::addPhoto(const QString& photoPath, PicasaWebPhoto& info,
350
const QString& albumId)
358
KUrl url("http://picasaweb.google.com/data/feed/api");
359
url.addPath("/user/" + m_username);
360
url.addPath("/albumid/" + albumId);
361
QString auth_string = "GoogleLogin auth=" + m_token;
364
//Create the Body in atom-xml
365
QDomDocument docMeta;
366
QDomProcessingInstruction instr = docMeta.createProcessingInstruction(
367
"xml", "version='1.0' encoding='UTF-8'");
368
docMeta.appendChild(instr);
369
QDomElement entryElem = docMeta.createElement("entry");
370
docMeta.appendChild(entryElem);
371
entryElem.setAttribute("xmlns", "http://www.w3.org/2005/Atom");
372
QDomElement titleElem = docMeta.createElement("title");
373
entryElem.appendChild(titleElem);
374
QDomText titleText = docMeta.createTextNode(info.title);
375
titleElem.appendChild(titleText);
376
QDomElement summaryElem = docMeta.createElement("summary");
377
entryElem.appendChild(summaryElem);
378
QDomText summaryText = docMeta.createTextNode(info.description);
379
summaryElem.appendChild(summaryText);
380
QDomElement categoryElem = docMeta.createElement("category");
381
entryElem.appendChild(categoryElem);
382
categoryElem.setAttribute("scheme", "http://schemas.google.com/g/2005#kind");
383
categoryElem.setAttribute("term", "http://schemas.google.com/photos/2007#photo");
384
QDomElement mediaGroupElem = docMeta.createElementNS("http://search.yahoo.com/mrss/", "media:group");
385
entryElem.appendChild(mediaGroupElem);
386
QDomElement mediaKeywordsElem = docMeta.createElementNS("http://search.yahoo.com/mrss/", "media:keywords");
387
mediaGroupElem.appendChild(mediaKeywordsElem);
388
QDomText mediaKeywordsText = docMeta.createTextNode(info.tags.join(","));
389
mediaKeywordsElem.appendChild(mediaKeywordsText);
390
if (!info.gpsLat.isEmpty() && !info.gpsLon.isEmpty())
392
QDomElement whereElem = docMeta.createElementNS("http://www.georss.org/georss", "georss:where");
393
entryElem.appendChild(whereElem);
394
QDomElement pointElem = docMeta.createElementNS("http://www.opengis.net/gml", "gml:Point");
395
whereElem.appendChild(pointElem);
396
QDomElement gpsElem = docMeta.createElementNS("http://www.opengis.net/gml", "gml:pos");
397
pointElem.appendChild(gpsElem);
398
QDomText gpsVal = docMeta.createTextNode(info.gpsLat + " " + info.gpsLon);
399
gpsElem.appendChild(gpsVal);
402
form.addPair("descr", docMeta.toString(), "application/atom+xml");
404
if (!form.addFile("photo", photoPath))
409
KIO::TransferJob* job = KIO::http_post(url, form.formData(), KIO::HideProgressInfo);
410
job->ui()->setWindow(m_parent);
411
job->addMetaData("content-type", form.contentType());
412
job->addMetaData("content-length", QString("Content-Length: %1").arg(form.formData().length()));
413
job->addMetaData("customHTTPHeader", "Authorization: " + auth_string + "\nMIME-version: 1.0" );
415
connect(job, SIGNAL(data(KIO::Job*,QByteArray)),
416
this, SLOT(data(KIO::Job*,QByteArray)));
418
connect(job, SIGNAL(result(KJob*)),
419
this, SLOT(slotResult(KJob*)));
421
m_state = FE_ADDPHOTO;
424
emit signalBusy(true);
428
bool PicasawebTalker::updatePhoto(const QString& photoPath, PicasaWebPhoto& info)
438
//Create the Body in atom-xml
439
QDomDocument docMeta;
440
QDomProcessingInstruction instr = docMeta.createProcessingInstruction(
441
"xml", "version='1.0' encoding='UTF-8'");
442
docMeta.appendChild(instr);
443
QDomElement entryElem = docMeta.createElement("entry");
444
docMeta.appendChild(entryElem);
445
entryElem.setAttribute("xmlns", "http://www.w3.org/2005/Atom");
446
QDomElement titleElem = docMeta.createElement("title");
447
entryElem.appendChild(titleElem);
448
QDomText titleText = docMeta.createTextNode(info.title);
449
titleElem.appendChild(titleText);
450
QDomElement summaryElem = docMeta.createElement("summary");
451
entryElem.appendChild(summaryElem);
452
QDomText summaryText = docMeta.createTextNode(info.description);
453
summaryElem.appendChild(summaryText);
454
QDomElement categoryElem = docMeta.createElement("category");
455
entryElem.appendChild(categoryElem);
456
categoryElem.setAttribute("scheme", "http://schemas.google.com/g/2005#kind");
457
categoryElem.setAttribute("term", "http://schemas.google.com/photos/2007#photo");
458
QDomElement mediaGroupElem = docMeta.createElementNS("http://search.yahoo.com/mrss/", "media:group");
459
entryElem.appendChild(mediaGroupElem);
460
QDomElement mediaKeywordsElem = docMeta.createElementNS("http://search.yahoo.com/mrss/", "media:keywords");
461
mediaGroupElem.appendChild(mediaKeywordsElem);
462
QDomText mediaKeywordsText = docMeta.createTextNode(info.tags.join(","));
463
mediaKeywordsElem.appendChild(mediaKeywordsText);
464
if (!info.gpsLat.isEmpty() && !info.gpsLon.isEmpty())
466
QDomElement whereElem = docMeta.createElementNS("http://www.georss.org/georss", "georss:where");
467
entryElem.appendChild(whereElem);
468
QDomElement pointElem = docMeta.createElementNS("http://www.opengis.net/gml", "gml:Point");
469
whereElem.appendChild(pointElem);
470
QDomElement gpsElem = docMeta.createElementNS("http://www.opengis.net/gml", "gml:pos");
471
pointElem.appendChild(gpsElem);
472
QDomText gpsVal = docMeta.createTextNode(info.gpsLat + " " + info.gpsLon);
473
gpsElem.appendChild(gpsVal);
476
form.addPair("descr", docMeta.toString(), "application/atom+xml");
478
if (!form.addFile("photo", photoPath))
483
QString auth_string = "GoogleLogin auth=" + m_token;
484
KIO::TransferJob* job = KIO::put(info.editUrl, -1, KIO::HideProgressInfo);
485
job->ui()->setWindow(m_parent);
486
job->addMetaData("content-type", form.contentType());
487
job->addMetaData("content-length", QString("Content-Length: %1").arg(form.formData().length()));
488
job->addMetaData("customHTTPHeader", "Authorization: " + auth_string + "\nIf-Match: *");
490
m_jobData.insert(job, form.formData());
492
connect(job, SIGNAL(dataReq(KIO::Job*,QByteArray&)),
493
this, SLOT(dataReq(KIO::Job*,QByteArray&)));
495
connect(job, SIGNAL(result(KJob*)),
496
this, SLOT(slotResult(KJob*)));
498
m_state = FE_UPDATEPHOTO;
501
emit signalBusy(true);
505
void PicasawebTalker::getPhoto(const QString& imgPath)
512
emit signalBusy(true);
514
KIO::TransferJob* job = KIO::get(imgPath, KIO::Reload, KIO::HideProgressInfo);
515
//job->addMetaData("customHTTPHeader", "Authorization: " + auth_string );
517
connect(job, SIGNAL(data(KIO::Job*,QByteArray)),
518
this, SLOT(data(KIO::Job*,QByteArray)));
520
connect(job, SIGNAL(result(KJob*)),
521
this, SLOT(slotResult(KJob*)));
523
m_state = FE_GETPHOTO;
528
QString PicasawebTalker::getUserName()
533
void PicasawebTalker::cancel()
541
emit signalBusy(false);
544
void PicasawebTalker::info(KIO::Job* /*job*/, const QString& /*str*/)
548
void PicasawebTalker::data(KIO::Job*, const QByteArray& data)
553
int oldSize = m_buffer.size();
554
m_buffer.resize(m_buffer.size() + data.size());
555
memcpy(m_buffer.data()+oldSize, data.data(), data.size());
558
void PicasawebTalker::dataReq(KIO::Job* job, QByteArray& data)
560
if (m_jobData.contains(job))
562
data = m_jobData.value(job);
563
m_jobData.remove(job);
567
void PicasawebTalker::slotError(const QString & error)
572
if (!error.isEmpty())
573
errorNo = error.toInt();
578
transError=i18n("No photo specified");break;
580
transError=i18n("General upload failure");break;
582
transError=i18n("File-size was zero");break;
584
transError=i18n("File-type was not recognized");break;
586
transError=i18n("User exceeded upload limit");break;
588
transError=i18n("Invalid signature"); break;
590
transError=i18n("Missing signature"); break;
592
transError=i18n("Login failed / Invalid auth token"); break;
594
transError=i18n("Invalid API Key"); break;
596
transError=i18n("Service currently unavailable");break;
598
transError=i18n("Invalid Frob");break;
600
transError=i18n("Format \"xxx\" not found"); break;
602
transError=i18n("Method \"xxx\" not found"); break;
604
transError=i18n("Invalid SOAP envelope");break;
606
transError=i18n("Invalid XML-RPC Method Call");break;
608
transError=i18n("The POST method is now required for all setters."); break;
610
transError=i18n("Unknown error");
613
KMessageBox::error(kapp->activeWindow(), i18n("Error occurred: %1\nUnable to proceed further.",transError + error));
616
void PicasawebTalker::slotResult(KJob *job)
619
emit signalBusy(false);
623
if (m_state == FE_ADDPHOTO)
625
emit signalAddPhotoDone(job->error(), job->errorText(), "");
629
static_cast<KIO::Job*>(job)->ui()->showErrorMessage();
634
if (static_cast<KIO::TransferJob*>(job)->isErrorPage())
636
if (m_state == FE_CHECKTOKEN)
638
kDebug() << " Error encountered in checking token, require user credentials" ;
639
return getToken(m_username, "");
645
//parseResponseLogin(m_buffer);
647
case(FE_CREATEALBUM):
648
parseResponseCreateAlbum(m_buffer);
651
parseResponseListAlbums(m_buffer);
654
parseResponseGetToken(m_buffer);
657
parseResponseCheckToken(m_buffer);
660
parseResponseListPhotos(m_buffer);
663
parseResponseAddPhoto(m_buffer);
665
case(FE_UPDATEPHOTO):
666
emit signalAddPhotoDone(0, "", "");
669
// all we get is data of the image
670
emit signalGetPhotoDone(0, QString(), m_buffer);
675
void PicasawebTalker::parseResponseCheckToken(const QByteArray& /*data*/)
678
// TODO(vardhman): Fix this with proper error handling.
680
getToken(m_username, m_password);
681
emit signalLoginDone(0, "");
684
void PicasawebTalker::parseResponseGetToken(const QByteArray& data)
686
bool success = false;
689
//Check the response code should it be 200, proceed
690
//if it is 403 handle the error mesg
691
//figure out the auth string from this response
693
if (str.contains("Auth="))
695
QStringList strList = str.split("Auth=");
696
if ( strList.count() > 0 )
698
m_token = strList[1].trimmed();
699
kDebug() << " m_token as obtained in token Response " << m_token ;
706
emit signalLoginDone(0, "");
710
emit signalError("98");
714
void PicasawebTalker::parseResponseListAlbums(const QByteArray& data)
716
QDomDocument doc( "feed" );
717
if ( !doc.setContent( data ) )
719
emit signalListAlbumsDone(1, i18n("Failed to fetch photo-set list"), QList<PicasaWebAlbum>());
723
QDomElement docElem = doc.documentElement();
724
QDomNode node = docElem.firstChild();
727
QList<PicasaWebAlbum> albumList;
729
while(!node.isNull())
731
if(node.isElement() && node.nodeName() == "gphoto:user")
733
m_username = node.toElement().text();
736
if (node.isElement() && node.nodeName() == "entry")
738
e = node.toElement();
739
QDomNode details=e.firstChild();
741
QDomNode detailsNode = details;
743
while(!detailsNode.isNull())
745
if(detailsNode.isElement())
747
if(detailsNode.nodeName() == "gphoto:id")
749
fps.id = detailsNode.toElement().text();
752
if(detailsNode.nodeName() == "title")
754
fps.title = detailsNode.toElement().text();
757
if(detailsNode.nodeName()=="gphoto:access")
759
fps.access = detailsNode.toElement().text();
762
detailsNode = detailsNode.nextSibling();
764
albumList.append(fps);
766
node = node.nextSibling();
769
emit signalListAlbumsDone(0, "", albumList);
772
void PicasawebTalker::parseResponseListPhotos(const QByteArray& data)
774
QDomDocument doc( "feed" );
775
if ( !doc.setContent( data ) )
777
emit signalListPhotosDone(1, i18n("Failed to fetch photo-set list"), QList<PicasaWebPhoto>());
781
QDomElement docElem = doc.documentElement();
782
QDomNode node = docElem.firstChild();
784
QList<PicasaWebPhoto> photoList;
786
while(!node.isNull())
788
if (node.isElement() && node.nodeName() == "entry")
790
QDomNode details = node.firstChild();
792
QDomNode detailsNode = details;
794
while(!detailsNode.isNull())
796
if(detailsNode.isElement())
798
QDomElement detailsElem = detailsNode.toElement();
799
if(detailsNode.nodeName() == "gphoto:id")
801
fps.id = detailsElem.text();
804
if(detailsNode.nodeName() == "title")
806
fps.title = detailsElem.text();
809
if(detailsNode.nodeName()=="gphoto:access")
811
fps.access = detailsElem.text();
814
if (detailsNode.nodeName() == "link" && detailsElem.attribute("rel") == "edit-media")
816
fps.editUrl = detailsElem.attribute("href");
819
if(detailsNode.nodeName()=="georss:where")
821
QDomNode geoPointNode = detailsElem.namedItem("gml:Point");
822
if (!geoPointNode.isNull() && geoPointNode.isElement())
824
QDomNode geoPosNode = geoPointNode.toElement().namedItem("gml:pos");
825
if (!geoPosNode.isNull() && geoPosNode.isElement())
827
QStringList value = geoPosNode.toElement().text().split(" ");
828
if (value.size() == 2)
830
fps.gpsLat = value[0];
831
fps.gpsLon = value[1];
837
if(detailsNode.nodeName()=="media:group")
839
QDomNode thumbNode = detailsElem.namedItem("media:thumbnail");
840
if (!thumbNode.isNull() && thumbNode.isElement())
842
fps.thumbURL = thumbNode.toElement().attribute("url", "");
844
QDomNode keywordNode = detailsElem.namedItem("media:keywords");
845
if (!keywordNode.isNull() && keywordNode.isElement())
847
fps.tags = keywordNode.toElement().text().split(",");
850
QDomNodeList contentsList = detailsElem.elementsByTagName("media:content");
851
for(int i = 0; i < contentsList.size(); ++i)
853
QDomElement contentElem = contentsList.at(i).toElement();
854
if (!contentElem.isNull())
856
if ((contentElem.attribute("medium") == "image") &&
857
fps.originalURL.isEmpty())
859
fps.originalURL = contentElem.attribute("url");
860
fps.mimeType = contentElem.attribute("type");
863
if ((contentElem.attribute("medium") == "video") &&
864
(contentElem.attribute("type") == "video/mpeg4"))
866
fps.originalURL = contentElem.attribute("url");
867
fps.mimeType = contentElem.attribute("type");
873
detailsNode = detailsNode.nextSibling();
875
photoList.append(fps);
877
node = node.nextSibling();
880
emit signalListPhotosDone(0, "", photoList);
883
void PicasawebTalker::parseResponseCreateAlbum(const QByteArray& data)
885
bool success = false;
887
QDomDocument doc( "AddPhoto Response" );
888
if ( !doc.setContent( data ) )
890
signalCreateAlbumDone(1, i18n("Failed to create album"), "-1");
894
// parse the new album name
895
QDomElement docElem = doc.documentElement();
897
if (docElem.nodeName() == "entry")
900
QDomNode node = docElem.firstChild(); //this should mean <entry>
901
while( !node.isNull() )
903
if ( node.isElement())
905
if (node.nodeName() == "gphoto:id")
907
albumId = node.toElement().text();
910
node = node.nextSibling();
916
signalCreateAlbumDone(0, "", albumId);
920
signalCreateAlbumDone(1, i18n("Failed to create album"), "-1");
924
void PicasawebTalker::parseResponseAddPhoto(const QByteArray& data)
926
QDomDocument doc( "AddPhoto Response" );
927
if ( !doc.setContent( data ) )
929
emit signalAddPhotoDone(1, i18n("Failed to upload photo"), "");
933
// parse the new album name
934
QDomElement docElem = doc.documentElement();
936
if (docElem.nodeName() == "entry")
938
QDomNode node = docElem.firstChild(); //this should mean <entry>
939
while(!node.isNull())
941
if (node.isElement())
943
if (node.nodeName() == "gphoto:id")
945
photoId = node.toElement().text();
948
node = node.nextSibling();
952
emit signalAddPhotoDone(0, "", photoId);
955
} // KIPIPicasawebExportPlugin