You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kipi-plugins/kipi-plugins/picasawebexport/picasawebtalker.cpp

960 lines
29 KiB

/* ============================================================
*
* This file is a part of kipi-plugins project
* http://www.kipi-plugins.org
*
* Date : 2007-16-07
* Description : a kipi plugin to export images to Picasa web service
*
* Copyright (C) 2007-2008 by Vardhman Jain <vardhman at gmail dot com>
* Copyright (C) 2008 by Gilles Caulier <caulier dot gilles at gmail dot com>
*
* 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.
*
* ============================================================ */
// C++ includes.
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <string>
// TQt includes.
#include <tqcstring.h>
#include <tqtextstream.h>
#include <tqfile.h>
#include <tqfileinfo.h>
#include <tqimage.h>
#include <tqstringlist.h>
#include <tqurl.h>
#include <tqlineedit.h>
#include <tqmessagebox.h>
#include <tqdom.h>
// KDE includes.
#include <tdelocale.h>
#include <tdeio/job.h>
#include <kdebug.h>
#include <kmimetype.h>
#include <kstandarddirs.h>
#include <kmdcodec.h>
#include <tdeapplication.h>
#include <tdemessagebox.h>
#include <tdeio/jobclasses.h>
#include <kurl.h>
// LibKExiv2 includes.
#include <libkexiv2/kexiv2.h>
// LibKDcraw includes.
#include <libkdcraw/version.h>
#include <libkdcraw/kdcraw.h>
#if KDCRAW_VERSION < 0x000106
#include <libkdcraw/dcrawbinary.h>
#endif
// Local includes.
#include "pluginsversion.h"
#include "mpform.h"
#include "picasawebitem.h"
#include "picasawebtalker.h"
#include "picasawebwindow.h"
#include "picasaweblogin.h"
#include "picasawebtalker.moc"
class PicasawebLogin;
namespace KIPIPicasawebExportPlugin
{
PicasawebTalker::PicasawebTalker( TQWidget* parent )
: m_parent( parent ), m_job( 0 )
{
m_apikey="49d585bafa0758cb5c58ab67198bf632";
m_secret="34b39925e6273ffd";
connect(this, TQT_SIGNAL(signalError(const TQString&)),
this, TQT_SLOT(slotError(const TQString&)));
authProgressDlg=new TQProgressDialog();
}
PicasawebTalker::~PicasawebTalker()
{
if (m_job)
m_job->kill();
}
TQString PicasawebTalker::getApiSig(TQString secret, TQStringList headers)
{
TQStringList compressed ;//= new List<string>(headers.Length);
for ( TQStringList::Iterator it = headers.begin(); it != headers.end(); ++it ) {
TQStringList str=TQStringList::split("=",(*it));
compressed.append(str[0].stripWhiteSpace()+str[1].stripWhiteSpace());
}
compressed.sort();
TQString merged=compressed.join("");
TQString final = secret + merged;
const char *test=final.ascii();
KMD5 context (test);
//kdDebug()<< "Test Hex Digest output: " << context.hexDigest().data() << endl;
return context.hexDigest().data();
}
void PicasawebTalker::getToken(const TQString& username, const TQString& password )
{
if (m_job)
{
m_job->kill();
m_job = 0;
}
TQString url = "https://www.google.com/accounts/ClientLogin";
PicasawebLogin *loginDialog = new PicasawebLogin(TQT_TQWIDGET(kapp->activeWindow()), TQString("LoginWindow"), username, password);
/*if (username!=NULL && username.length() > 0){
// kdDebug()<<"Showing stored username"<< username << endl;
loginDialog->setUsername(username);
if (password != NULL && password.length() > 0){
// kdDebug()<<"Showing stored password"<< password << endl;
loginDialog->setPassword(password);
// kdDebug()<<"Showing stored password"<< password << endl;
}
}
*/
TQString username_edit, password_edit;
if (!loginDialog)
{
kdDebug()<<" Out of memory error "<< endl;
}
if (loginDialog->exec() == TQDialog::Accepted)
{
username_edit = loginDialog->username();
password_edit = loginDialog->password();
}
else
{
//Return something which say authentication needed.
return ;
}
m_username = username_edit;
username_edit = username;
TQString accountType = "GOOGLE";
if (!(username_edit.endsWith("@gmail.com")))
username_edit += "@gmail.com";
TQByteArray buffer;
TQStringList qsl;
qsl.append("Email="+username_edit);
qsl.append("Passwd="+password_edit);
qsl.append("accountType="+accountType);
qsl.append("service=lh2");
qsl.append("source=kipi-picasaweb-client");
TQString dataParameters = qsl.join("&");
TQTextStream ts(buffer, IO_Append|IO_WriteOnly);
ts.setEncoding(TQTextStream::UnicodeUTF8);
ts << dataParameters;
TDEIO::TransferJob* job = TDEIO::http_post(url, buffer, false);
job->addMetaData("content-type", "Content-Type: application/x-www-form-urlencoded" );
m_state = FE_GETTOKEN;
authProgressDlg->setLabelText(i18n("Getting the token"));
connect(job, TQT_SIGNAL(data(TDEIO::Job*, const TQByteArray&)),
this, TQT_SLOT(data(TDEIO::Job*, const TQByteArray&)));
connect(job, TQT_SIGNAL(result(TDEIO::Job *)),
this, TQT_SLOT(slotResult(TDEIO::Job *)));
m_job = job;
m_buffer.resize(0);
emit signalBusy( true );
}
void PicasawebTalker::authenticate(const TQString& token, const TQString& username, const TQString& password)
{
if (!token || token.length() < 1)
{
checkToken(token);
m_username = username;
m_password = password; //this would be needed if the checktoken failed
//we would need to reauthenticate using auth
}
else
{
getToken(username, password);
}
}
void PicasawebTalker::checkToken(const TQString& /*token*/)
{
if (m_job)
{
m_job->kill();
m_job = 0;
}
TQString url = "https://www.google.com/accounts/ClientLogin";
TQString auth_string = "GoogleLogin auth=" + m_token;
TQByteArray tmp;
TDEIO::TransferJob* job = TDEIO::http_post(url, tmp, false);
job->addMetaData("customHTTPHeader", "Authorization: " + auth_string);
job->addMetaData("content-type", "Content-Type: application/x-www-form-urlencoded");
connect(job, TQT_SIGNAL(data(TDEIO::Job*, const TQByteArray&)),
this, TQT_SLOT(data(TDEIO::Job*, const TQByteArray&)));
connect(job, TQT_SIGNAL(result(TDEIO::Job *)),
this, TQT_SLOT(slotResult(TDEIO::Job *)));
m_state = FE_CHECKTOKEN;
authProgressDlg->setLabelText(i18n("Checking if previous token is still valid"));
authProgressDlg->setProgress(1,4);
m_job = job;
m_buffer.resize(0);
emit signalBusy( true );
}
/** PicasaWeb's Album listing request/response
* First a request is sent to the url below and then we might(?) get a redirect URL
* WE then need to send the GET request to the Redirect url (this however gets taken care off by the
* TDEIO libraries.
* This uses the authenticated album list fetching to get all the albums included the unlisted-albums
* which is not returned for an unauthorised request as done without the Authorization header.
*/
void PicasawebTalker::listAllAlbums() {
if (m_job)
{
m_job->kill();
m_job = 0;
}
TQString url = "http://picasaweb.google.com/data/feed/api/user/" + m_username + "?kind=album";
TQByteArray tmp;
TQString auth_string = "GoogleLogin auth=" + m_token;
TDEIO::TransferJob* job = TDEIO::get(url, !tmp.isNull(), false);
job->addMetaData("content-type", "Content-Type: application/x-www-form-urlencoded" );
job->addMetaData("customHTTPHeader", "Authorization: " + auth_string );
connect(job, TQT_SIGNAL(data(TDEIO::Job*, const TQByteArray&)),
this, TQT_SLOT(data(TDEIO::Job*, const TQByteArray&)));
connect(job, TQT_SIGNAL(result(TDEIO::Job *)),
this, TQT_SLOT(slotResult(TDEIO::Job *)));
m_state = FE_LISTALBUMS;
m_job = job;
m_buffer.resize(0);
emit signalBusy( true );
}
void PicasawebTalker::getPhotoProperty(const TQString& method,const TQString& argList)
{
if (m_job)
{
m_job->kill();
m_job = 0;
}
TQString url="http://www.picasaweb.com/services/rest/?";
TQStringList headers;
headers.append("api_key="+ m_apikey);
headers.append("method="+method);
headers.append("frob="+ m_frob);
headers.append(argList);
TQString md5=getApiSig(m_secret,headers);
headers.append("api_sig="+ md5);
TQString queryStr=headers.join("&");
TQString postUrl=url+queryStr;
TQByteArray tmp;
TDEIO::TransferJob* job = TDEIO::http_post(postUrl, tmp, false);
job->addMetaData("content-type", "Content-Type: application/x-www-form-urlencoded" );
connect(job, TQT_SIGNAL(data(TDEIO::Job*, const TQByteArray&)),
this, TQT_SLOT(data(TDEIO::Job*, const TQByteArray&)));
connect(job, TQT_SIGNAL(result(TDEIO::Job *)),
this, TQT_SLOT(slotResult(TDEIO::Job *)));
m_state = FE_GETPHOTOPROPERTY;
m_job = job;
m_buffer.resize(0);
emit signalBusy( true );
//authProgressDlg->setLabelText("Getting the Token from the server");
//authProgressDlg->setProgress(3,4);
}
void PicasawebTalker::addPhotoTag(const TQString& photoURI, const TQString& tag)
{
//if (m_job && m_state != FE_ADDTAG){ //we shouldn't kill the old tag request
// m_job->kill();
// m_job = 0;
//}
TQString addTagXML = TQString("<entry xmlns='http://www.w3.org/2005/Atom'> "
"<title>%1</title> "
"<category scheme='http://schemas.google.com/g/2005#kind' "
"term='http://schemas.google.com/photos/2007#tag'/> "
"</entry>").arg(tag);
TQString postUrl = TQString("%1").arg(photoURI);
TQByteArray buffer;
TQTextStream ts(buffer, IO_Append|IO_WriteOnly);
ts.setEncoding(TQTextStream::UnicodeUTF8);
ts << addTagXML;
TQString auth_string = "GoogleLogin auth=" + m_token;
TDEIO::TransferJob* job = TDEIO::http_post(postUrl, buffer, false);
job->addMetaData("content-type", "Content-Type: application/atom+xml");
job->addMetaData("content-length", TQString("Content-Length: %1").arg(addTagXML.length()));
job->addMetaData("customHTTPHeader", "Authorization: " + auth_string );
//connect(job, TQT_SIGNAL(data(TDEIO::Job*, const TQByteArray&)),
// this, TQT_SLOT(data(TDEIO::Job*, const TQByteArray&)));
connect(job, TQT_SIGNAL(result(TDEIO::Job *)),
this, TQT_SLOT(slotResult(TDEIO::Job *)));
m_state = FE_ADDTAG;
m_job = job;
m_buffer.resize(0);
emit signalBusy(true);
}
void PicasawebTalker::listPhotos(const TQString& /*albumName*/)
{
// TODO
}
void PicasawebTalker::createAlbum(const TQString& albumTitle, const TQString& albumDesc,
const TQString& location, uint timestamp, const TQString& access,
const TQString& media_keywords, bool isCommentsEnabled)
{
if (m_job)
{
m_job->kill();
m_job = 0;
}
TQString newAlbumXML = TQString("<entry xmlns='http://www.w3.org/2005/Atom' "
"xmlns:media='http://search.yahoo.com/mrss/' "
"xmlns:gphoto='http://schemas.google.com/photos/2007'> "
"<title type='text'>%1</title> "
"<summary type='text'>%2</summary> "
"<gphoto:location>%3</gphoto:location> "
"<gphoto:access>%4</gphoto:access> "
"<gphoto:commentingEnabled>%5</gphoto:commentingEnabled> "
"<gphoto:timestamp>%6</gphoto:timestamp> "
"<media:group> "
"<media:keywords>%7</media:keywords> "
"</media:group> "
"<category scheme='http://schemas.google.com/g/2005#kind' "
"term='http://schemas.google.com/photos/2007#album'></category> "
"</entry> ").arg(albumTitle)
.arg(albumDesc)
.arg(location)
.arg(access)
.arg(isCommentsEnabled==true?"true":"false")
.arg(timestamp)
.arg(media_keywords);
TQByteArray buffer;
TQTextStream ts(buffer, IO_Append|IO_WriteOnly);
ts.setEncoding(TQTextStream::UnicodeUTF8);
ts << newAlbumXML;
MPForm form;
TQString postUrl = "http://www.picasaweb.google.com/data/feed/api/user/" + m_username ;
TQString auth_string = "GoogleLogin auth=" + m_token;
TDEIO::TransferJob* job = TDEIO::http_post(postUrl, buffer, false);
job->addMetaData("content-type", "Content-Type: application/atom+xml");
job->addMetaData("content-length", TQString("Content-Length: %1").arg(newAlbumXML.length()));
job->addMetaData("customHTTPHeader", "Authorization: " + auth_string );
connect(job, TQT_SIGNAL(data(TDEIO::Job*, const TQByteArray&)),
this, TQT_SLOT(data(TDEIO::Job*, const TQByteArray&)));
connect(job, TQT_SIGNAL(result(TDEIO::Job *)),
this, TQT_SLOT(slotResult(TDEIO::Job *)));
m_state = FE_CREATEALBUM;
m_job = job;
m_buffer.resize(0);
emit signalBusy(true);
}
bool PicasawebTalker::addPhoto(const TQString& photoPath, FPhotoInfo& info,
const TQString& albumId, bool rescale,
int maxDim, int imageQuality)
{
// Disabling this totally may be checking the m_state and doing selecting
// disabling is a better idea
/*if (m_job)
{
m_job->kill();
m_job = 0;
}*/
TQString album_id = albumId;
if (album_id.length() == 0)
album_id = "test";
TQString postUrl = "http://www.picasaweb.google.com/data/feed/api/user/" + KURL::encode_string(m_username) + "/albumid/" + album_id;
TQString path = postUrl;
TQStringList headers;
MPForm form;
TQString auth_string = "GoogleLogin auth=" + m_token;
//form.addPair("Authorization", auth_string);
//Create the Body in atom-xml
TQStringList body_xml;
body_xml.append("<entry xmlns=\'http://www.w3.org/2005/Atom\'>");
body_xml.append("<title>"+ info.title +"</title>");
body_xml.append("<summary>"+ info.description +"</summary>");
body_xml.append("<category scheme=\"http://schemas.google.com/g/2005#kind\" "
"term=\"http://schemas.google.com/photos/2007#photo\" />");
body_xml.append("</entry>");
TQString body = body_xml.join("");
form.addPair("test", body, "application/atom+xml");
// save the tags for this photo in to the tags hashmap
tags_map.insert(info.title, info.tags);
TQImage image;
// Check if RAW file.
#if KDCRAW_VERSION < 0x000106
TQString rawFilesExt(KDcrawIface::DcrawBinary::instance()->rawFiles());
#else
TQString rawFilesExt(KDcrawIface::KDcraw::rawFiles());
#endif
TQFileInfo fileInfo(photoPath);
if (rawFilesExt.upper().contains(fileInfo.extension(false).upper()))
KDcrawIface::KDcraw::loadDcrawPreview(image, photoPath);
else
image.load(photoPath);
if (!image.isNull())
{
path = locateLocal("tmp", TQFileInfo(photoPath).baseName().stripWhiteSpace() + ".jpg");
if (rescale && (image.width() > maxDim || image.height() > maxDim))
image = image.smoothScale(maxDim, maxDim, TQ_ScaleMin);
image.save(path, "JPEG", imageQuality);
// Restore all metadata.
KExiv2Iface::KExiv2 exiv2Iface;
if (exiv2Iface.load(photoPath))
{
exiv2Iface.setImageProgramId(TQString("Kipi-plugins"), TQString(kipiplugins_version));
exiv2Iface.setImageDimensions(image.size());
exiv2Iface.save(path);
}
else
{
kdWarning(51000) << "(picasawebExport::Image doesn't have exif data)" << endl;
}
kdDebug() << "Resizing and saving to temp file: " << path << endl;
}
if (!form.addFile("photo", path))
return false;
form.finish();
TDEIO::TransferJob* job = TDEIO::http_post(postUrl, form.formData(), false);
job->addMetaData("content-type", form.contentType());
job->addMetaData("customHTTPHeader", "Authorization: " + auth_string );
connect(job, TQT_SIGNAL(data(TDEIO::Job*, const TQByteArray&)),
this, TQT_SLOT(data(TDEIO::Job*, const TQByteArray&)));
connect(job, TQT_SIGNAL(result(TDEIO::Job *)),
this, TQT_SLOT(slotResult(TDEIO::Job *)));
m_state = FE_ADDPHOTO;
m_job = job;
m_buffer.resize(0);
emit signalBusy(true);
return true;
}
TQString PicasawebTalker::getUserName()
{
return m_username;
}
TQString PicasawebTalker::getUserId()
{
return m_userId;
}
void PicasawebTalker::cancel()
{
if (m_job)
{
m_job->kill();
m_job = 0;
}
if (authProgressDlg && !authProgressDlg->isHidden())
authProgressDlg->hide();
}
void PicasawebTalker::info(TDEIO::Job* /*job*/, const TQString& /*str*/)
{
}
void PicasawebTalker::data(TDEIO::Job*, const TQByteArray& data)
{
if (data.isEmpty())
return;
int oldSize = m_buffer.size();
m_buffer.resize(m_buffer.size() + data.size());
TQString output_data = TQString(data);
memcpy(m_buffer.data()+oldSize, data.data(), data.size());
}
void PicasawebTalker::slotError(const TQString & error)
{
TQString transError;
int errorNo = 0;
if (!error.isEmpty())
errorNo = atoi(error.latin1());
switch (errorNo)
{
case 2:
transError=i18n("No photo specified");break;
case 3:
transError=i18n("General upload failure");break;
case 4:
transError=i18n("Filesize was zero");break;
case 5:
transError=i18n("Filetype was not recognised");break;
case 6:
transError=i18n("User exceeded upload limit");break;
case 96:
transError=i18n("Invalid signature"); break;
case 97:
transError=i18n("Missing signature"); break;
case 98:
transError=i18n("Login Failed / Invalid auth token"); break;
case 100:
transError=i18n("Invalid API Key"); break;
case 105:
transError=i18n("Service currently unavailable");break;
case 108:
transError=i18n("Invalid Frob");break;
case 111:
transError=i18n("Format \"xxx\" not found"); break;
case 112:
transError=i18n("Method \"xxx\" not found"); break;
case 114:
transError=i18n("Invalid SOAP envelope");break;
case 115:
transError=i18n("Invalid XML-RPC Method Call");break;
case 116:
transError=i18n("The POST method is now required for all setters"); break;
default:
transError=i18n("Unknown error");
};
KMessageBox::error(TQT_TQWIDGET(kapp->activeWindow()), i18n("Error Occured: %1\n We can not proceed further").arg(transError));
//kdDebug()<<"Not handling the error now will see it later"<<endl;
}
void PicasawebTalker::slotResult(TDEIO::Job *job)
{
m_job = 0;
emit signalBusy(false);
if (job->error())
{
if (m_state == FE_ADDPHOTO)
{
emit signalAddPhotoFailed(job->errorString());
}
else
{
job->showErrorDialog(m_parent);
}
return;
}
switch(m_state)
{
case(FE_LOGIN):
//parseResponseLogin(m_buffer);
break;
case(FE_CREATEALBUM):
parseResponseCreateAlbum(m_buffer);
break;
case(FE_LISTALBUMS):
parseResponseListAlbums(m_buffer);
break;
case(FE_GETFROB):
break;
case(FE_GETTOKEN):
parseResponseGetToken(m_buffer);
break;
case(FE_CHECKTOKEN):
parseResponseCheckToken(m_buffer);
break;
case(FE_GETAUTHORIZED):
break;
case(FE_LISTPHOTOS):
parseResponseListPhotos(m_buffer);
break;
case(FE_GETPHOTOPROPERTY):
parseResponsePhotoProperty(m_buffer);
break;
case(FE_ADDPHOTO):
parseResponseAddPhoto(m_buffer);
break;
case(FE_ADDTAG):
parseResponseAddTag(m_buffer);
break;
}
}
void PicasawebTalker::parseResponseCheckToken(const TQByteArray &data)
{
bool success = false;
TQString errorString;
TQString username;
TQString transReturn(data);
// If checktoken failed.
// getToken ...
if(transReturn.startsWith("Error="))
success = false;
else
success = true;
if(!success)
getToken(m_username, m_password);
//emit signalError(errorString);
}
void PicasawebTalker::parseResponseGetToken(const TQByteArray &data)
{
bool success = false;
TQString errorString;
TQString str(data);
//Check the response code should it be 200, proceed
//if it is 403 handle the error mesg
//figure out the auth string from this response
if (str.find("Auth="))
{
TQStringList strList = TQStringList::split("Auth=", str);
m_token = strList[1];
success = 1;
}
if(success)
{
authProgressDlg->hide();
emit signalTokenObtained(m_token);
}
else
{
emit signalError(errorString);
}
emit signalBusy(false);
}
void PicasawebTalker::getHTMLResponseCode(const TQString& /*str*/)
{
}
void PicasawebTalker::parseResponseListAlbums(const TQByteArray &data)
{
bool success = false;
TQString str(data);
TQDomDocument doc( "feed" );
if ( !doc.setContent( data ) )
{
return;
}
TQDomElement docElem = doc.documentElement();
TQDomNode node = docElem.firstChild();
TQDomElement e;
TQString feed_id, feed_updated, feed_title, feed_subtitle;
TQString feed_icon_url, feed_link_url;
TQString feed_username, feed_user_uri;
TQString album_id, album_title, album_description;
m_albumsList = new TQValueList <PicasaWebAlbum>();
while(!node.isNull())
{
if (node.isElement() && node.nodeName() == "entry")
{
success = true;
e = node.toElement();
TQDomNode details=e.firstChild();
PicasaWebAlbum fps;
TQDomNode detailsNode = details;
while(!detailsNode.isNull())
{
if(detailsNode.isElement())
{
if(detailsNode.nodeName() == "id")
{
// The node data is a URL of which album id is the string following the last /
// like <id>http://www.picasaweb.google.com/.../AlbumID<id>
TQString albumIdUrl = detailsNode.toElement().text();
int index = albumIdUrl.findRev("/");
int length = albumIdUrl.length();
TQString album_id = albumIdUrl.right(length - index - 1);
fps.id = album_id;
}
if(detailsNode.nodeName() == "title")
{
album_title = "Not fetched";
if(detailsNode.toElement().attribute("type")=="text")
album_title = detailsNode.toElement().text();
//this is what is obtained from data.
fps.title = album_title;
}
if(detailsNode.nodeName()=="gphoto:name")
{
TQString name = detailsNode.toElement().text();
}
}
detailsNode = detailsNode.nextSibling();
}
m_albumsList->append(fps);
}
node = node.nextSibling();
}
if (!success)
{
emit signalGetAlbumsListFailed(i18n("Failed to fetch photoSets List"));
m_albumsList = NULL;
}
else
{
emit signalGetAlbumsListSucceeded();
}
}
void PicasawebTalker::parseResponseListPhotos(const TQByteArray &data)
{
TQDomDocument doc( "getPhotosList" );
if ( !doc.setContent( data ) )
{
return;
}
TQDomElement docElem = doc.documentElement();
TQDomNode node = docElem.firstChild();
//TQDomElement e;
// TODO
}
void PicasawebTalker::parseResponseCreateAlbum(const TQByteArray &data)
{
bool success = false;
TQString errorString;
TQString response(data);
TQDomDocument doc( "AddPhoto Response" );
// parse the new album name
TQDomElement docElem = doc.documentElement();
TQString title, photo_id, album_id, photoURI;
TQDomNode node = docElem.firstChild(); //this should mean <entry>
TQDomElement e;
while( !node.isNull() )
{
if ( node.isElement())
{
TQString node_name = node.nodeName();
TQString node_value = node.toElement().text();
if(node_name == "title")
{
success = true;
title = node_value;
}
else if (node_name == "id")
photoURI = node_value;
else if(node_name == "gphoto:id")
photo_id = node_value;
else if(node_name == "gphoto:albumid")
album_id = node_value;
}
node = node.nextSibling();
}
// Raise a popup informing success
}
void PicasawebTalker::parseResponseAddTag(const TQByteArray &data)
{
TQString str(data);
remaining_tags_count -= 1;
emit signalBusy( false );
m_buffer.resize(0);
if (remaining_tags_count == 0)
emit signalAddPhotoSucceeded();
}
void PicasawebTalker::parseResponseAddPhoto(const TQByteArray &data)
{
bool success = false;
TQString line;
TQString str(data);
success = 1;
TQDomDocument doc( "AddPhoto Response" );
if ( !doc.setContent( data ) )
{
return;
}
TQDomElement docElem = doc.documentElement();
TQString title, photo_id, album_id, photoURI;
TQDomNode node = docElem.firstChild(); //this should mean <entry>
TQDomElement e;
while( !node.isNull() )
{
if ( node.isElement())
{
TQString node_name = node.nodeName();
TQString node_value = node.toElement().text();
if(node_name == "title")
{
success = true;
title = node_value;
}
else if (node_name == "id")
photoURI = node_value;
else if(node_name == "gphoto:id")
photo_id = node_value;
else if(node_name == "gphoto:albumid")
album_id = node_value;
}
node = node.nextSibling();
}
if (!success)
{
emit signalAddPhotoFailed(i18n("Failed to upload photo"));
}
else
{
// Update the tags information from the tags_map
TQStringList tags = tags_map[title];
remaining_tags_count = tags.count();
if (tags.count() == 0)
emit signalAddPhotoSucceeded();
for ( TQStringList::Iterator it = tags.begin(); it != tags.end(); ++it )
{
TQString photoURI= TQString("http://picasaweb.google.com/data/feed/api/user/"
"%1/albumid/%2/photoid/%3").arg(m_username).arg(album_id).arg(photo_id);
addPhotoTag( photoURI, *it);
}
}
}
void PicasawebTalker::parseResponsePhotoProperty(const TQByteArray &data)
{
bool success = false;
TQString line;
TQDomDocument doc( "Photos Properties" );
if ( !doc.setContent( data ) )
{
return;
}
TQDomElement docElem = doc.documentElement();
TQDomNode node = docElem.firstChild();
TQDomElement e;
while( !node.isNull() )
{
if ( node.isElement() && node.nodeName() == "photoid" )
{
e = node.toElement(); // try to convert the node to an element.
TQDomNode details=e.firstChild();
success=true;
}
if ( node.isElement() && node.nodeName() == "err" )
{
kdDebug()<<"Checking Error in response"<<endl;
TQString code=node.toElement().attribute("code");
kdDebug()<<"Error code="<<code<<endl;
kdDebug()<<"Msg="<<node.toElement().attribute("msg")<<endl;
emit signalError(code);
}
node = node.nextSibling();
}
kdDebug()<<"GetToken finished"<<endl;
if (!success)
{
emit signalAddPhotoFailed(i18n("Failed to query photo information"));
}
else
{
//emit signalAddPhotoSucceeded();
}
}
} // KIPIPicasawebExportPlugin