• Skip to content
  • Skip to link menu
KDE 4.0 API Reference
  • KDE API Reference
  • KDE-PIM Libraries
  • Sitemap
  • Contact Us
 

KBlog Client Library

gdata.cpp

00001 /*
00002     This file is part of the kblog library.
00003 
00004     Copyright (c) 2007 Christian Weilbach <christian_weilbach@web.de>
00005 
00006     This library is free software; you can redistribute it and/or
00007     modify it under the terms of the GNU Library General Public
00008     License as published by the Free Software Foundation; either
00009     version 2 of the License, or (at your option) any later version.
00010 
00011     This library is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014     Library General Public License for more details.
00015 
00016     You should have received a copy of the GNU Library General Public License
00017     along with this library; see the file COPYING.LIB.  If not, write to
00018     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019     Boston, MA 02110-1301, USA.
00020 */
00021 
00022 #include "gdata.h"
00023 #include "gdata_p.h"
00024 #include "blogpost.h"
00025 #include "blogcomment.h"
00026 
00027 #include <syndication/loader.h>
00028 #include <syndication/item.h>
00029 
00030 #include <kio/netaccess.h>
00031 #include <kio/http.h>
00032 #include <kio/job.h>
00033 #include <KDebug>
00034 #include <KLocale>
00035 #include <KDateTime>
00036 
00037 #include <QByteArray>
00038 #include <QRegExp>
00039 #include <QDomDocument>
00040 
00041 #define TIMEOUT 600
00042 
00043 using namespace KBlog;
00044 
00045 GData::GData( const KUrl &server, QObject *parent )
00046   : Blog( server, *new GDataPrivate, parent )
00047 {
00048   kDebug(5323);
00049   setUrl( server );
00050 }
00051 
00052 GData::~GData()
00053 {
00054   kDebug(5323);
00055 }
00056 
00057 QString GData::interfaceName() const
00058 {
00059   kDebug(5323);
00060   return QLatin1String( "Google Blogger Data" );
00061 }
00062 
00063 QString GData::fullName() const
00064 {
00065   kDebug(5323);
00066   return d_func()->mFullName;
00067 }
00068 
00069 void GData::setFullName( const QString &fullName )
00070 {
00071   kDebug(5323);
00072   Q_D( GData );
00073   d->mFullName = fullName;
00074 }
00075 
00076 QString GData::profileId() const
00077 {
00078   kDebug(5323);
00079   return d_func()->mProfileId;
00080 }
00081 
00082 void GData::setProfileId( const QString &pid )
00083 {
00084   kDebug(5323);
00085   Q_D( GData );
00086   d->mProfileId = pid;
00087 }
00088 
00089 void GData::fetchProfileId()
00090 {
00091   kDebug(5323);
00092   QByteArray data;
00093   KIO::Job *job = KIO::get( url(), KIO::NoReload, KIO::HideProgressInfo );
00094   KUrl blogUrl = url();
00095   connect( job, SIGNAL(data(KIO::Job*,const QByteArray&)),
00096            this, SLOT(slotFetchProfileIdData(KIO::Job*,const QByteArray&)) );
00097   connect( job, SIGNAL(result(KJob*)),
00098            this, SLOT(slotFetchProfileId(KJob*)) );
00099 }
00100 
00101 void GData::listBlogs()
00102 {
00103   kDebug(5323);
00104   Syndication::Loader *loader = Syndication::Loader::create();
00105   connect( loader,
00106            SIGNAL(loadingComplete(Syndication::Loader*,Syndication::FeedPtr,Syndication::ErrorCode)),
00107            this,
00108            SLOT(slotListBlogs(Syndication::Loader*,Syndication::FeedPtr,Syndication::ErrorCode)) );
00109   loader->loadFrom( "http://www.blogger.com/feeds/" + profileId() + "/blogs" );
00110 }
00111 
00112 void GData::listRecentPosts( const QStringList &labels, int number,
00113                              const KDateTime &upMinTime, const KDateTime &upMaxTime,
00114                              const KDateTime &pubMinTime, const KDateTime &pubMaxTime )
00115 {
00116   kDebug(5323);
00117   Q_D( GData );
00118   QString urlString( "http://www.blogger.com/feeds/" + blogId() + "/posts/default" );
00119   if ( ! labels.empty() ) {
00120     urlString += "/-/" + labels.join( "/" );
00121   }
00122   kDebug() << "listRecentPosts()";
00123   KUrl url( urlString );
00124 
00125   if ( !upMinTime.isNull() ) {
00126     url.addQueryItem( "updated-min", upMinTime.toString() );
00127   }
00128 
00129   if( !upMaxTime.isNull() ) {
00130     url.addQueryItem( "updated-max", upMaxTime.toString() );
00131   }
00132 
00133   if( !pubMinTime.isNull() ) {
00134     url.addQueryItem( "published-min", pubMinTime.toString() );
00135   }
00136 
00137   if( !pubMaxTime.isNull() ) {
00138     url.addQueryItem( "published-max", pubMaxTime.toString() );
00139   }
00140 
00141   Syndication::Loader *loader = Syndication::Loader::create();
00142   if ( number > 0 ) {
00143     d->mListRecentPostsMap[ loader ] = number;
00144   }
00145   connect( loader,
00146            SIGNAL(loadingComplete(Syndication::Loader*,Syndication::FeedPtr,Syndication::ErrorCode)),
00147            this,
00148            SLOT(slotListRecentPosts(Syndication::Loader*,Syndication::FeedPtr,Syndication::ErrorCode)) );
00149   loader->loadFrom( url.url() );
00150 }
00151 
00152 void GData::listRecentPosts( int number )
00153 {
00154   kDebug(5323);
00155   listRecentPosts( QStringList(), number );
00156 }
00157 
00158 void GData::listComments( KBlog::BlogPost *post )
00159 {
00160   kDebug(5323);
00161   Q_D( GData );
00162   Syndication::Loader *loader = Syndication::Loader::create();
00163   d->mListCommentsMap[ loader ] = post;
00164   connect( loader,
00165            SIGNAL(loadingComplete(Syndication::Loader*,Syndication::FeedPtr,Syndication::ErrorCode)),
00166            this,
00167            SLOT(slotListComments(Syndication::Loader*,Syndication::FeedPtr,Syndication::ErrorCode)) );
00168   loader->loadFrom( "http://www.blogger.com/feeds/" + blogId() + '/' +
00169                     post->postId() + "/comments/default" );
00170 }
00171 
00172 void GData::listAllComments()
00173 {
00174   kDebug(5323);
00175   Syndication::Loader *loader = Syndication::Loader::create();
00176   connect( loader,
00177            SIGNAL(loadingComplete(Syndication::Loader*,Syndication::FeedPtr,Syndication::ErrorCode)),
00178            this,
00179            SLOT(slotListAllComments(Syndication::Loader*,Syndication::FeedPtr,Syndication::ErrorCode)) );
00180   loader->loadFrom( "http://www.blogger.com/feeds/" + blogId() + "/comments/default" );
00181 }
00182 
00183 void GData::fetchPost( KBlog::BlogPost *post )
00184 {
00185   kDebug(5323);
00186   Q_D( GData );
00187 
00188   if ( !post ) {
00189     kError(5323) << "post is null pointer";
00190     return;
00191   }
00192 
00193   kDebug();
00194   Syndication::Loader *loader = Syndication::Loader::create();
00195   d->mFetchPostMap[ loader ] = post;
00196   connect( loader,
00197            SIGNAL(loadingComplete(Syndication::Loader*,Syndication::FeedPtr,Syndication::ErrorCode)),
00198            this,
00199            SLOT(slotFetchPost(Syndication::Loader*,Syndication::FeedPtr,Syndication::ErrorCode)) );
00200   loader->loadFrom( "http://www.blogger.com/feeds/" + blogId() + "/posts/default" );
00201 }
00202 
00203 void GData::modifyPost( KBlog::BlogPost *post )
00204 {
00205   kDebug(5323);
00206   Q_D( GData );
00207 
00208   if ( !post ) {
00209     kError(5323) << "post is null pointer";
00210     return;
00211   }
00212 
00213   if ( !d->authenticate() ){
00214     kError(5323) << "Authentication failed.";
00215     emit errorPost( Atom, i18n( "Authentication failed." ), post );
00216     return;
00217   }
00218 
00219   QString atomMarkup = "<entry xmlns='http://www.w3.org/2005/Atom'>";
00220   atomMarkup += "<id>tag:blogger.com,1999:blog-" + blogId();
00221   atomMarkup += ".post-" + post->postId() + "</id>";
00222   atomMarkup += "<published>" + post->creationDateTime().toString() + "</published>";
00223   atomMarkup += "<updated>" + post->modificationDateTime().toString() + "</updated>";
00224   atomMarkup += "<title type='text'>" + post->title() + "</title>";
00225   if( post->isPrivate() ) {
00226     atomMarkup += "<app:control xmlns:app='http://purl.org/atom/app#'>";
00227     atomMarkup += "<app:draft>yes</app:draft></app:control>";
00228   }
00229   atomMarkup += "<content type='xhtml'>";
00230   atomMarkup += "<div xmlns='http://www.w3.org/1999/xhtml'>";
00231   atomMarkup += post->content();
00232   atomMarkup += "</div></content>";
00233   atomMarkup += "<author>";
00234   if ( !fullName().isEmpty() ) {
00235     atomMarkup += "<name>" + fullName() + "</name>";
00236   }
00237   atomMarkup += "<email>" + username() + "</email>";
00238   atomMarkup += "</author>";
00239   atomMarkup += "</entry>";
00240   QByteArray postData;
00241   QDataStream stream( &postData, QIODevice::WriteOnly );
00242   stream.writeRawData( atomMarkup.toUtf8(), atomMarkup.toUtf8().length() );
00243 
00244   KIO::TransferJob *job = KIO::http_post(
00245       KUrl( "http://www.blogger.com/feeds/" + blogId() + "/posts/default/" + post->postId() ),
00246       postData, KIO::HideProgressInfo );
00247 
00248   Q_ASSERT( job );
00249 
00250   d->mModifyPostMap[ job ] = post;
00251 
00252   job->addMetaData( "content-type", "Content-Type: application/atom+xml; charset=utf-8" );
00253   job->addMetaData( "ConnectTimeout", "50" );
00254   job->addMetaData( "UserAgent", userAgent() );
00255   job->addMetaData( "customHTTPHeader",
00256                     "Authorization: GoogleLogin auth=" + d->mAuthenticationString +
00257                     "\r\nX-HTTP-Method-Override: PUT" );
00258 
00259   connect( job, SIGNAL(data(KIO::Job*,const QByteArray&)),
00260            this, SLOT(slotModifyPostData(KIO::Job*,const QByteArray&)) );
00261   connect( job, SIGNAL(result(KJob*)),
00262            this, SLOT(slotModifyPost(KJob*)) );
00263 }
00264 
00265 void GData::createPost( KBlog::BlogPost *post )
00266 {
00267   kDebug(5323);
00268   Q_D( GData );
00269 
00270   if ( !post ) {
00271     kError(5323) << "post is null pointer";
00272     return;
00273   }
00274 
00275   if ( !d->authenticate() ){
00276     kError(5323) << "Authentication failed.";
00277     emit errorPost( Atom, i18n( "Authentication failed." ), post );
00278     return;
00279   }
00280 
00281   QString atomMarkup = "<entry xmlns='http://www.w3.org/2005/Atom'>";
00282   atomMarkup += "<title type='text'>" + post->title() + "</title>";
00283   if ( post->isPrivate() ) {
00284     atomMarkup += "<app:control xmlns:app='http://purl.org/atom/app#'>";
00285     atomMarkup += "<app:draft>yes</app:draft></app:control>";
00286   }
00287   atomMarkup += "<content type='xhtml'>";
00288   atomMarkup += "<div xmlns='http://www.w3.org/1999/xhtml'>";
00289   atomMarkup += post->content(); // FIXME check for Utf
00290   atomMarkup += "</div></content>";
00291   atomMarkup += "<author>";
00292   if ( !fullName().isEmpty() ) {
00293     atomMarkup += "<name>" + fullName() + "</name>";
00294   }
00295   atomMarkup += "<email>" + username() + "</email>";
00296   atomMarkup += "</author>";
00297   atomMarkup += "</entry>";
00298 
00299   QByteArray postData;
00300   QDataStream stream( &postData, QIODevice::WriteOnly );
00301   stream.writeRawData( atomMarkup.toUtf8(), atomMarkup.toUtf8().length() );
00302 
00303   KIO::TransferJob *job = KIO::http_post(
00304     KUrl( "http://www.blogger.com/feeds/" + blogId() + "/posts/default" ),
00305     postData, KIO::HideProgressInfo );
00306 
00307   d->mCreatePostMap[ job ] = post;
00308 
00309   if ( !job ) {
00310     kWarning() << "Unable to create KIO job for http://www.blogger.com/feeds/"
00311                << blogId() << "/posts/default";
00312   }
00313 
00314   job->addMetaData( "content-type", "Content-Type: application/atom+xml; charset=utf-8" );
00315   job->addMetaData( "ConnectTimeout", "50" );
00316   job->addMetaData( "UserAgent", userAgent() );
00317   job->addMetaData( "customHTTPHeader",
00318                     "Authorization: GoogleLogin auth=" + d->mAuthenticationString );
00319 
00320   connect( job, SIGNAL(data(KIO::Job*,const QByteArray&)),
00321            this, SLOT(slotCreatePostData(KIO::Job*,const QByteArray&)) );
00322   connect( job, SIGNAL(result(KJob*)),
00323            this, SLOT(slotCreatePost(KJob*)) );
00324 }
00325 
00326 void GData::removePost( KBlog::BlogPost *post )
00327 {
00328   kDebug(5323);
00329   Q_D( GData );
00330 
00331   if ( !post ) {
00332     kError(5323) << "post is null pointer";
00333     return;
00334   }
00335 
00336   if ( !d->authenticate() ){
00337     kError(5323) << "Authentication failed.";
00338     emit errorPost( Atom, i18n( "Authentication failed." ), post );
00339     return;
00340   }
00341 
00342   QByteArray postData;
00343 
00344   KIO::TransferJob *job = KIO::http_post(
00345     KUrl( "http://www.blogger.com/feeds/" + blogId() + "/posts/default/" + post->postId() ),
00346     postData, KIO::HideProgressInfo );
00347 
00348   d->mRemovePostMap[ job ] = post;
00349 
00350   if ( !job ) {
00351     kWarning() << "Unable to create KIO job for http://www.blogger.com/feeds/"
00352                << blogId() << "/posts/default/" + post->postId();
00353   }
00354 
00355   job->addMetaData( "ConnectTimeout", "50" );
00356   job->addMetaData( "UserAgent", userAgent() );
00357   job->addMetaData( "customHTTPHeader",
00358                     "Authorization: GoogleLogin auth=" + d->mAuthenticationString +
00359                     "\r\nX-HTTP-Method-Override: DELETE" );
00360 
00361   connect( job, SIGNAL(data(KIO::Job*,const QByteArray&)),
00362            this, SLOT(slotRemovePostData(KIO::Job*,const QByteArray&)) );
00363   connect( job, SIGNAL(result(KJob*)),
00364            this, SLOT(slotRemovePost(KJob*)) );
00365 }
00366 
00367 void GData::createComment( KBlog::BlogPost *post, KBlog::BlogComment *comment )
00368 {
00369   kDebug(5323);
00370 
00371   if ( !comment ) {
00372     kError(5323) << "comment is null pointer";
00373     return;
00374   }
00375 
00376   if ( !post ) {
00377     kError(5323) << "post is null pointer";
00378     return;
00379   }
00380 
00381   Q_D( GData );
00382   if ( !d->authenticate() ){
00383     kError(5323) << "Authentication failed.";
00384     emit errorComment( Atom, i18n( "Authentication failed." ), post, comment );
00385     return;
00386   }
00387   QString atomMarkup = "<entry xmlns='http://www.w3.org/2005/Atom'>";
00388   atomMarkup += "<title type=\"text\">" + comment->title() + "</title>";
00389   atomMarkup += "<content type=\"html\">" + comment->content() + "</content>";
00390   atomMarkup += "<author>";
00391   atomMarkup += "<name>" + comment->name() + "</name>";
00392   atomMarkup += "<email>" + comment->email() + "</email>";
00393   atomMarkup += "</author></entry>";
00394 
00395   QByteArray postData;
00396   kDebug() <<  postData;
00397   QDataStream stream( &postData, QIODevice::WriteOnly );
00398   stream.writeRawData( atomMarkup.toUtf8(), atomMarkup.toUtf8().length() );
00399 
00400   KIO::TransferJob *job = KIO::http_post(
00401     KUrl( "http://www.blogger.com/feeds/" + blogId() + "/" + post->postId() + "/comments/default" ),
00402     postData, KIO::HideProgressInfo );
00403 
00404   d->mCreateCommentMap[ job ][post] = comment;
00405 
00406   if ( !job ) {
00407     kWarning() << "Unable to create KIO job for http://www.blogger.com/feeds/"
00408                << blogId() << "/" << post->postId() << "/comments/default";
00409   }
00410 
00411   job->addMetaData( "content-type", "Content-Type: application/atom+xml; charset=utf-8" );
00412   job->addMetaData( "ConnectTimeout", "50" );
00413   job->addMetaData( "customHTTPHeader",
00414                     "Authorization: GoogleLogin auth=" + d->mAuthenticationString );
00415   job->addMetaData( "UserAgent", userAgent() );
00416 
00417   connect( job, SIGNAL(data(KIO::Job*,const QByteArray&)),
00418            this, SLOT(slotCreateCommentData(KIO::Job*,const QByteArray&)) );
00419   connect( job, SIGNAL(result(KJob*)),
00420            this, SLOT(slotCreateComment(KJob*)) );
00421 }
00422 
00423 void GData::removeComment( KBlog::BlogPost *post, KBlog::BlogComment *comment )
00424 {
00425   kDebug(5323);
00426   Q_D( GData );
00427   kDebug();
00428 
00429   if ( !comment ) {
00430     kError(5323) << "comment is null pointer";
00431     return;
00432   }
00433 
00434   if ( !post ) {
00435     kError(5323) << "post is null pointer";
00436     return;
00437   }
00438 
00439   if ( !d->authenticate() ){
00440     kError(5323) << "Authentication failed.";
00441     emit errorComment( Atom, i18n( "Authentication failed." ), post, comment );
00442     return;
00443   }
00444 
00445   QByteArray postData;
00446 
00447   KIO::TransferJob *job = KIO::http_post(
00448     KUrl( "http://www.blogger.com/feeds/" + blogId() + "/" + post->postId() +
00449           "/comments/default/" + comment->commentId() ),
00450     postData, KIO::HideProgressInfo );
00451   d->mRemoveCommentMap[ job ][ post ] = comment;
00452 
00453   if ( !job ) {
00454     kWarning() << "Unable to create KIO job for http://www.blogger.com/feeds/"
00455                << blogId() << post->postId()
00456                << "/comments/default/" << comment->commentId();
00457   }
00458 
00459   job->addMetaData( "ConnectTimeout", "50" );
00460   job->addMetaData( "UserAgent", userAgent() );
00461   job->addMetaData( "customHTTPHeader",
00462                     "Authorization: GoogleLogin auth=" +
00463                     d->mAuthenticationString + "\r\nX-HTTP-Method-Override: DELETE" );
00464 
00465   connect( job, SIGNAL(data(KIO::Job*,const QByteArray&)),
00466            this, SLOT(slotRemoveCommentData(KIO::Job*,const QByteArray&)) );
00467   connect( job, SIGNAL(result(KJob*)),
00468            this, SLOT(slotRemoveComment(KJob*)) );
00469 }
00470 
00471 GDataPrivate::GDataPrivate():mAuthenticationString(), mAuthenticationTime()
00472 {
00473   kDebug(5323);
00474 }
00475 
00476 GDataPrivate::~GDataPrivate()
00477 {
00478   kDebug(5323);
00479 }
00480 
00481 bool GDataPrivate::authenticate()
00482 {
00483   kDebug(5323);
00484   Q_Q( GData );
00485   QByteArray data;
00486   KUrl authGateway( "https://www.google.com/accounts/ClientLogin" );
00487   authGateway.addQueryItem( "Email", q->username() );
00488   authGateway.addQueryItem( "Passwd", q->password() );
00489   authGateway.addQueryItem( "source", q->userAgent() );
00490   authGateway.addQueryItem( "service", "blogger" );
00491   if ( !mAuthenticationTime.isValid() ||
00492        QDateTime::currentDateTime().toTime_t() - mAuthenticationTime.toTime_t() > TIMEOUT ||
00493        mAuthenticationString.isEmpty() ) {
00494     KIO::Job *job = KIO::http_post( authGateway, QByteArray(), KIO::HideProgressInfo );
00495     if ( KIO::NetAccess::synchronousRun( job, (QWidget*)0, &data, &authGateway ) ) {
00496       kDebug(5323) << "Fetched authentication result for"
00497                    << authGateway.prettyUrl() << ".";
00498       kDebug(5323) << "Authentication response:" << data;
00499       QRegExp rx( "Auth=(.+)" );
00500       if ( rx.indexIn( data ) != -1 ) {
00501         kDebug(5323) << "RegExp got authentication string:" << rx.cap(1);
00502         mAuthenticationString = rx.cap(1);
00503         mAuthenticationTime = QDateTime::currentDateTime();
00504         return true;
00505       }
00506     }
00507     return false;
00508   }
00509   return true;
00510 }
00511 
00512 void GDataPrivate::slotFetchProfileIdData( KIO::Job *job, const QByteArray &data )
00513 {
00514   kDebug(5323);
00515   if( !job ){
00516     kError(5323) << "job is a null pointer.";
00517     return;
00518   }
00519   unsigned int oldSize = mFetchProfileIdBuffer[ job ].size();
00520   mFetchProfileIdBuffer[ job ].resize( oldSize + data.size() );
00521   memcpy( mFetchProfileIdBuffer[ job ].data() + oldSize, data.data(), data.size() );
00522 }
00523 
00524 void GDataPrivate::slotFetchProfileId( KJob *job )
00525 {
00526   kDebug(5323);
00527   if( !job ){
00528     kError(5323) << "job is a null pointer.";
00529     return;
00530   }
00531   Q_Q( GData );
00532   if ( !job->error() ) {
00533     QRegExp pid( "http://www.blogger.com/profile/(\\d+)" );
00534     if ( pid.indexIn( mFetchProfileIdBuffer[ job ] ) != -1 ) {
00535       q->setProfileId( pid.cap(1) );
00536       emit q->fetchedProfileId( pid.cap(1) );
00537       kDebug(5323) << "QRegExp bid( 'http://www.blogger.com/profile/(\\d+)' matches" << pid.cap(1);
00538     } else {
00539       kError(5323) << "QRegExp bid( 'http://www.blogger.com/profile/(\\d+)' "
00540                    << " could not regexp the Profile ID";
00541       emit q->error( GData::Other, i18n( "Could not regexp the Profile ID." ) );
00542       emit q->fetchedProfileId( QString() );
00543     }
00544   } else {
00545     kError(5323) << "Could not fetch the homepage data.";
00546     emit q->error( GData::Other, i18n( "Could not fetch the homepage data." ) );
00547     emit q->fetchedProfileId( QString() );
00548   }
00549   mFetchProfileIdBuffer[ job ].resize( 0 );
00550   mFetchProfileIdBuffer.remove( job );
00551 }
00552 
00553 void GDataPrivate::slotListBlogs( Syndication::Loader *loader,
00554                                   Syndication::FeedPtr feed,
00555                                   Syndication::ErrorCode status ) {
00556   kDebug(5323);
00557   Q_Q( GData );
00558   if( !loader ) {
00559     kError(5323) << "loader is a null pointer.";
00560     return;
00561   }
00562   if ( status != Syndication::Success ) {
00563     emit q->error( GData::Atom, i18n( "Could not get blogs." ) );
00564     return;
00565   }
00566 
00567   QList<QMap<QString,QString> > blogsList;
00568 
00569   QList<Syndication::ItemPtr> items = feed->items();
00570   QList<Syndication::ItemPtr>::ConstIterator it = items.begin();
00571   QList<Syndication::ItemPtr>::ConstIterator end = items.end();
00572   for ( ; it != end; ++it ) {
00573     QRegExp rx( "blog-(\\d+)" );
00574     QMap<QString,QString> blogInfo;
00575     if ( rx.indexIn( ( *it )->id() ) != -1 ) {
00576       kDebug(5323) << "QRegExp rx( 'blog-(\\d+)' matches" << rx.cap(1);
00577       blogInfo["id"] = rx.cap(1);
00578       blogInfo["title"] = ( *it )->title();
00579       blogInfo["summary"] = ( *it )->description(); //TODO fix/add more
00580       blogsList << blogInfo;
00581     } else {
00582       emit q->error( GData::Other, i18n( "Could not regexp the blog id path." ) );
00583       kError(5323) << "QRegExp rx( 'blog-(\\d+)' does not match anything in:"
00584                    << ( *it )->id();
00585     }
00586   }
00587   emit q->listedBlogs( blogsList );
00588   kDebug(5323) << "Emitting listedBlogs(); ";
00589 }
00590 
00591 void GDataPrivate::slotListComments( Syndication::Loader *loader,
00592                                      Syndication::FeedPtr feed,
00593                                      Syndication::ErrorCode status )
00594 {
00595   kDebug(5323);
00596   Q_Q( GData );
00597   if( !loader ) {
00598     kError(5323) << "loader is a null pointer.";
00599     return;
00600   }
00601   BlogPost *post = mListCommentsMap[ loader ];
00602   mListCommentsMap.remove( loader );
00603 
00604   if ( status != Syndication::Success ) {
00605     emit q->errorPost( GData::Atom, i18n( "Could not get comments." ), post );
00606     return;
00607   }
00608 
00609   QList<KBlog::BlogComment> commentList;
00610 
00611   QList<Syndication::ItemPtr> items = feed->items();
00612   QList<Syndication::ItemPtr>::ConstIterator it = items.begin();
00613   QList<Syndication::ItemPtr>::ConstIterator end = items.end();
00614   for ( ; it != end; ++it ) {
00615     BlogComment comment;
00616     QRegExp rx( "post-(\\d+)" );
00617     if ( rx.indexIn( ( *it )->id() ) == -1 ) {
00618       kError(5323) << "QRegExp rx( 'post-(\\d+)' does not match" << rx.cap(1);
00619       emit q->error( GData::Other, i18n( "Could not regexp the comment id path." ) );
00620     } else {
00621       comment.setCommentId( rx.cap(1) );
00622     }
00623     kDebug(5323) << "QRegExp rx( 'post-(\\d+)' matches" << rx.cap(1);
00624     comment.setTitle( ( *it )->title() );
00625     comment.setContent( ( *it )->content() );
00626 //  FIXME: assuming UTC for now
00627     comment.setCreationDateTime(
00628       KDateTime( QDateTime::fromTime_t( ( *it )->datePublished() ),
00629                  KDateTime::Spec::UTC() ) );
00630     comment.setModificationDateTime(
00631       KDateTime( QDateTime::fromTime_t( ( *it )->dateUpdated() ),
00632                  KDateTime::Spec::UTC() ) );
00633     commentList.append( comment );
00634   }
00635   kDebug(5323) << "Emitting listedComments()";
00636   emit q->listedComments( post, commentList );
00637 }
00638 
00639 void GDataPrivate::slotListAllComments( Syndication::Loader *loader,
00640                                         Syndication::FeedPtr feed,
00641                                         Syndication::ErrorCode status )
00642 {
00643   kDebug(5323);
00644   Q_Q( GData );
00645   if( !loader ) {
00646     kError(5323) << "loader is a null pointer.";
00647     return;
00648   }
00649 
00650   if ( status != Syndication::Success ) {
00651     emit q->error( GData::Atom, i18n( "Could not get comments." ) );
00652     return;
00653   }
00654 
00655   QList<KBlog::BlogComment> commentList;
00656 
00657   QList<Syndication::ItemPtr> items = feed->items();
00658   QList<Syndication::ItemPtr>::ConstIterator it = items.begin();
00659   QList<Syndication::ItemPtr>::ConstIterator end = items.end();
00660   for ( ; it != end; ++it ) {
00661     BlogComment comment;
00662     QRegExp rx( "post-(\\d+)" );
00663     if ( rx.indexIn( ( *it )->id() ) == -1 ) {
00664       kError(5323) << "QRegExp rx( 'post-(\\d+)' does not match"<< rx.cap(1);
00665       emit q->error( GData::Other, i18n( "Could not regexp the comment id path." ) );
00666     } else {
00667       comment.setCommentId( rx.cap(1) );
00668     }
00669 
00670     kDebug(5323) << "QRegExp rx( 'post-(\\d+)' matches" << rx.cap(1);
00671     comment.setTitle( ( *it )->title() );
00672     comment.setContent( ( *it )->content() );
00673 //  FIXME: assuming UTC for now
00674     comment.setCreationDateTime(
00675       KDateTime( QDateTime::fromTime_t( ( *it )->datePublished() ),
00676                  KDateTime::Spec::UTC() ) );
00677     comment.setModificationDateTime(
00678       KDateTime( QDateTime::fromTime_t( ( *it )->dateUpdated() ),
00679                  KDateTime::Spec::UTC() ) );
00680     commentList.append( comment );
00681   }
00682   kDebug(5323) << "Emitting listedAllComments()";
00683   emit q->listedAllComments( commentList );
00684 }
00685 
00686 void GDataPrivate::slotListRecentPosts( Syndication::Loader *loader,
00687                                         Syndication::FeedPtr feed,
00688                                         Syndication::ErrorCode status ) {
00689   kDebug(5323);
00690   Q_Q( GData );
00691   if( !loader ) {
00692     kError(5323) << "loader is a null pointer.";
00693     return;
00694   }
00695 
00696   if ( status != Syndication::Success ) {
00697     emit q->error( GData::Atom, i18n( "Could not get posts." ) );
00698     return;
00699   }
00700   int number = 0;
00701 
00702   if ( mListRecentPostsMap.contains( loader ) ) {
00703     number = mListRecentPostsMap[ loader ];
00704   }
00705   mListRecentPostsMap.remove( loader );
00706 
00707   QList<KBlog::BlogPost> postList;
00708 
00709   QList<Syndication::ItemPtr> items = feed->items();
00710   QList<Syndication::ItemPtr>::ConstIterator it = items.begin();
00711   QList<Syndication::ItemPtr>::ConstIterator end = items.end();
00712   for ( ; it != end; ++it ) {
00713     BlogPost post;
00714     QRegExp rx( "post-(\\d+)" );
00715     if ( rx.indexIn( ( *it )->id() ) == -1 ) {
00716       kError(5323) << "QRegExp rx( 'post-(\\d+)' does not match"<< rx.cap(1);
00717       emit q->error( GData::Other, i18n( "Could not regexp the post id path." ) );
00718     } else {
00719       post.setPostId( rx.cap(1) );
00720     }
00721 
00722     kDebug(5323) << "QRegExp rx( 'post-(\\d+)' matches" << rx.cap(1);
00723     post.setTitle( ( *it )->title() );
00724     post.setContent( ( *it )->content() );
00725     post.setLink( ( *it )->link() );
00726 //  FIXME: assuming UTC for now
00727     post.setCreationDateTime(
00728       KDateTime( QDateTime::fromTime_t( ( *it )->datePublished() ),
00729                  KDateTime::Spec::UTC() ) );
00730     post.setModificationDateTime(
00731       KDateTime( QDateTime::fromTime_t( ( *it )->dateUpdated() ),
00732                  KDateTime::Spec::UTC() ) );
00733     post.setStatus( BlogPost::Fetched );
00734     postList.append( post );
00735     if ( number-- == 0 ) {
00736       break;
00737     }
00738   }
00739   kDebug(5323) << "Emitting listedRecentPosts()";
00740   emit q->listedRecentPosts( postList );
00741 }
00742 
00743 void GDataPrivate::slotFetchPost( Syndication::Loader *loader,
00744                                   Syndication::FeedPtr feed,
00745                                   Syndication::ErrorCode status )
00746 {
00747   kDebug(5323);
00748   Q_Q( GData );
00749   if( !loader ) {
00750     kError(5323) << "loader is a null pointer.";
00751     return;
00752   }
00753 
00754   bool success = false;
00755 
00756   BlogPost *post = mFetchPostMap[ loader ];
00757 
00758   if ( status != Syndication::Success ) {
00759     emit q->errorPost( GData::Atom, i18n( "Could not get posts." ), post );
00760     return;
00761   }
00762   QList<Syndication::ItemPtr> items = feed->items();
00763   QList<Syndication::ItemPtr>::ConstIterator it = items.begin();
00764   QList<Syndication::ItemPtr>::ConstIterator end = items.end();
00765   for ( ; it != end; ++it ) {
00766     QRegExp rx( "post-(\\d+)" );
00767     if ( rx.indexIn( ( *it )->id() ) != -1 && rx.cap(1) == post->postId() ){
00768       kDebug(5323) << "QRegExp rx( 'post-(\\d+)' matches" << rx.cap(1);
00769       post->setPostId( rx.cap(1) );
00770       post->setTitle( ( *it )->title() );
00771       post->setContent( ( *it )->content() );
00772       post->setStatus( BlogPost::Fetched );
00773       post->setLink( ( *it )->link() );
00774 //    FIXME: assuming UTC for now
00775       post->setCreationDateTime(
00776         KDateTime( QDateTime::fromTime_t( ( *it )->datePublished() ),
00777                    KDateTime::Spec::UTC() ) );
00778       post->setModificationDateTime(
00779         KDateTime( QDateTime::fromTime_t( ( *it )->dateUpdated() ),
00780                    KDateTime::Spec::UTC() ) );
00781       emit q->fetchedPost( post );
00782       success = true;
00783       kDebug(5323) << "Emitting fetchedPost( postId=" << post->postId() << ");";
00784     }
00785   }
00786   if ( !success ) {
00787     emit q->errorPost( GData::Other, i18n( "Could not regexp the blog id path." ), post );
00788     kError(5323) << "QRegExp rx( 'post-(\\d+)' does not match"
00789                  << mFetchPostMap[ loader ]->postId() << ".";
00790   }
00791   mFetchPostMap.remove( loader );
00792 }
00793 
00794 void GDataPrivate::slotCreatePostData( KIO::Job *job, const QByteArray &data )
00795 {
00796   kDebug(5323);
00797   if( !job ) {
00798     kError(5323) << "job is a null pointer.";
00799     return;
00800   }
00801   unsigned int oldSize = mCreatePostBuffer[ job ].size();
00802   mCreatePostBuffer[ job ].resize( oldSize + data.size() );
00803   memcpy( mCreatePostBuffer[ job ].data() + oldSize, data.data(), data.size() );
00804 }
00805 
00806 void GDataPrivate::slotCreatePost( KJob *job )
00807 {
00808   kDebug(5323);
00809   if( !job ) {
00810     kError(5323) << "job is a null pointer.";
00811     return;
00812   }
00813   const QString data = QString::fromUtf8( mCreatePostBuffer[ job ].data(),
00814                                           mCreatePostBuffer[ job ].size() );
00815   mCreatePostBuffer[ job ].resize( 0 );
00816 
00817   Q_Q( GData );
00818 
00819   KBlog::BlogPost *post = mCreatePostMap[ job ];
00820   mCreatePostMap.remove( job );
00821 
00822   if ( job->error() != 0 ) {
00823     kError(5323) << "slotCreatePost error:" << job->errorString();
00824     emit q->errorPost( GData::Atom, job->errorString(), post );
00825     return;
00826   }
00827 
00828   QRegExp rxId( "post-(\\d+)" ); //FIXME check and do better handling, esp the creation date time
00829   if ( rxId.indexIn( data ) == -1 ) {
00830     kError(5323) << "Could not regexp the id out of the result:" << data;
00831     emit q->errorPost( GData::Atom,
00832                        i18n( "Could not regexp the id out of the result." ), post );
00833     return;
00834   }
00835   kDebug(5323) << "QRegExp rx( 'post-(\\d+)' ) matches" << rxId.cap(1);
00836 
00837   QRegExp rxPub( "<published>(.+)</published>" );
00838   if ( rxPub.indexIn( data ) == -1 ) {
00839     kError(5323) << "Could not regexp the published time out of the result:" << data;
00840     emit q->errorPost( GData::Atom,
00841                        i18n( "Could not regexp the published time out of the result." ), post );
00842     return;
00843   }
00844   kDebug(5323) << "QRegExp rx( '<published>(.+)</published>' ) matches" << rxPub.cap(1);
00845 
00846   QRegExp rxUp( "<updated>(.+)</updated>" );
00847   if ( rxUp.indexIn( data ) == -1 ) {
00848     kError(5323) << "Could not regexp the update time out of the result:" << data;
00849     emit q->errorPost( GData::Atom,
00850                        i18n( "Could not regexp the update time out of the result." ), post );
00851     return;
00852   }
00853   kDebug(5323) << "QRegExp rx( '<updated>(.+)</updated>' ) matches" << rxUp.cap(1);
00854 
00855   post->setPostId( rxId.cap(1) );
00856   post->setCreationDateTime( KDateTime().fromString( rxPub.cap(1) ) );
00857   post->setModificationDateTime( KDateTime().fromString( rxUp.cap(1) ) );
00858   post->setStatus( BlogPost::Created );
00859   emit q->createdPost( post );
00860   kDebug(5323) << "Emitting createdPost()";
00861 }
00862 
00863 void GDataPrivate::slotModifyPostData( KIO::Job *job, const QByteArray &data )
00864 {
00865   kDebug(5323);
00866   if( !job ) {
00867     kError(5323) << "job is a null pointer.";
00868     return;
00869   }
00870   unsigned int oldSize = mModifyPostBuffer[ job ].size();
00871   mModifyPostBuffer[ job ].resize( oldSize + data.size() );
00872   memcpy( mModifyPostBuffer[ job ].data() + oldSize, data.data(), data.size() );
00873 }
00874 
00875 void GDataPrivate::slotModifyPost( KJob *job )
00876 {
00877   kDebug(5323);
00878   if( !job ) {
00879     kError(5323) << "job is a null pointer.";
00880     return;
00881   }
00882   const QString data = QString::fromUtf8( mModifyPostBuffer[ job ].data(),
00883                                           mModifyPostBuffer[ job ].size() );
00884   mModifyPostBuffer[ job ].resize( 0 );
00885 
00886   KBlog::BlogPost *post = mModifyPostMap[ job ];
00887   mModifyPostMap.remove( job );
00888   Q_Q( GData );
00889   if ( job->error() != 0 ) {
00890     kError(5323) << "slotModifyPost error:" << job->errorString();
00891     emit q->errorPost( GData::Atom, job->errorString(), post );
00892     return;
00893   }
00894 
00895   QRegExp rxId( "post-(\\d+)" ); //FIXME check and do better handling, esp creation date time
00896   if ( rxId.indexIn( data ) == -1 ) {
00897     kError(5323) << "Could not regexp the id out of the result:" << data;
00898     emit q->errorPost( GData::Atom,
00899                        i18n( "Could not regexp the id out of the result." ), post );
00900     return;
00901   }
00902   kDebug(5323) << "QRegExp rx( 'post-(\\d+)' ) matches" << rxId.cap(1);
00903 
00904   QRegExp rxPub( "<published>(.+)</published>" );
00905   if ( rxPub.indexIn( data ) == -1 ) {
00906     kError(5323) << "Could not regexp the published time out of the result:" << data;
00907     emit q->errorPost( GData::Atom,
00908                        i18n( "Could not regexp the published time out of the result." ), post );
00909     return;
00910   }
00911   kDebug(5323) << "QRegExp rx( '<published>(.+)</published>' ) matches" << rxPub.cap(1);
00912 
00913   QRegExp rxUp( "<updated>(.+)</updated>" );
00914   if ( rxUp.indexIn( data ) == -1 ) {
00915     kError(5323) << "Could not regexp the update time out of the result:" << data;
00916     emit q->errorPost( GData::Atom,
00917                        i18n( "Could not regexp the update time out of the result." ), post );
00918     return;
00919   }
00920   kDebug(5323) << "QRegExp rx( '<updated>(.+)</updated>' ) matches" << rxUp.cap(1);
00921   post->setPostId( rxId.cap(1) );
00922   post->setCreationDateTime( KDateTime().fromString( rxPub.cap(1) ) );
00923   post->setModificationDateTime( KDateTime().fromString( rxUp.cap(1) ) );
00924   post->setStatus( BlogPost::Modified );
00925   emit q->modifiedPost( post );
00926 }
00927 
00928 void GDataPrivate::slotRemovePostData( KIO::Job *job, const QByteArray &data )
00929 {
00930   kDebug(5323);
00931   if( !job ) {
00932     kError(5323) << "job is a null pointer.";
00933     return;
00934   }
00935   unsigned int oldSize = mRemovePostBuffer[ job ].size();
00936   mRemovePostBuffer[ job ].resize( oldSize + data.size() );
00937   memcpy( mRemovePostBuffer[ job ].data() + oldSize, data.data(), data.size() );
00938 }
00939 
00940 void GDataPrivate::slotRemovePost( KJob *job )
00941 {
00942   kDebug(5323);
00943   if( !job ) {
00944     kError(5323) << "job is a null pointer.";
00945     return;
00946   }
00947   const QString data = QString::fromUtf8( mRemovePostBuffer[ job ].data(),
00948                                           mRemovePostBuffer[ job ].size() );
00949   mRemovePostBuffer[ job ].resize( 0 );
00950 
00951   KBlog::BlogPost *post = mRemovePostMap[ job ];
00952   mRemovePostMap.remove( job );
00953   Q_Q( GData );
00954   if ( job->error() != 0 ) {
00955     kError(5323) << "slotRemovePost error:" << job->errorString();
00956     emit q->errorPost( GData::Atom, job->errorString(), post );
00957     return;
00958   }
00959 
00960   post->setStatus( BlogPost::Removed );
00961   emit q->removedPost( post );
00962   kDebug(5323) << "Emitting removedPost()";
00963 }
00964 
00965 void GDataPrivate::slotCreateCommentData( KIO::Job *job, const QByteArray &data )
00966 {
00967   kDebug(5323);
00968   if( !job ) {
00969     kError(5323) << "job is a null pointer.";
00970     return;
00971   }
00972   unsigned int oldSize = mCreateCommentBuffer[ job ].size();
00973   mCreateCommentBuffer[ job ].resize( oldSize + data.size() );
00974   memcpy( mCreateCommentBuffer[ job ].data() + oldSize, data.data(), data.size() );
00975 }
00976 
00977 void GDataPrivate::slotCreateComment( KJob *job )
00978 {
00979   kDebug(5323);
00980   if( !job ) {
00981     kError(5323) << "job is a null pointer.";
00982     return;
00983   }
00984   const QString data = QString::fromUtf8( mCreateCommentBuffer[ job ].data(),
00985                                           mCreateCommentBuffer[ job ].size() );
00986   mCreateCommentBuffer[ job ].resize( 0 );
00987   kDebug(5323) << "Dump data: " << data;
00988 
00989   Q_Q( GData );
00990 
00991   KBlog::BlogComment *comment = mCreateCommentMap[ job ].values().first();
00992   KBlog::BlogPost *post = mCreateCommentMap[ job ].keys().first();
00993   mCreateCommentMap.remove( job );
00994 
00995   if ( job->error() != 0 ) {
00996     kError(5323) << "slotCreateComment error:" << job->errorString();
00997     emit q->errorComment( GData::Atom, job->errorString(), post, comment );
00998     return;
00999   }
01000 
01001 // TODO check for result and fit appropriately
01002   QRegExp rxId( "post-(\\d+)" );
01003   if ( rxId.indexIn( data ) == -1 ) {
01004     kError(5323) << "Could not regexp the id out of the result:" << data;
01005     emit q->errorPost( GData::Atom,
01006                        i18n( "Could not regexp the id out of the result." ), post );
01007     return;
01008   }
01009   kDebug(5323) << "QRegExp rx( 'post-(\\d+)' ) matches" << rxId.cap(1);
01010 
01011   QRegExp rxPub( "<published>(.+)</published>" );
01012   if ( rxPub.indexIn( data ) == -1 ) {
01013     kError(5323) << "Could not regexp the published time out of the result:" << data;
01014     emit q->errorPost( GData::Atom,
01015                        i18n( "Could not regexp the published time out of the result." ), post );
01016     return;
01017   }
01018   kDebug(5323) << "QRegExp rx( '<published>(.+)</published>' ) matches" << rxPub.cap(1);
01019 
01020   QRegExp rxUp( "<updated>(.+)</updated>" );
01021   if ( rxUp.indexIn( data ) == -1 ) {
01022     kError(5323) << "Could not regexp the update time out of the result:" << data;
01023     emit q->errorPost( GData::Atom,
01024                        i18n( "Could not regexp the update time out of the result." ), post );
01025     return;
01026   }
01027   kDebug(5323) << "QRegExp rx( '<updated>(.+)</updated>' ) matches" << rxUp.cap(1);
01028   comment->setCommentId( rxId.cap(1) );
01029   comment->setCreationDateTime( KDateTime().fromString( rxPub.cap(1) ) );
01030   comment->setModificationDateTime( KDateTime().fromString( rxUp.cap(1) ) );
01031   comment->setStatus( BlogComment::Created );
01032   emit q->createdComment( post, comment );
01033   kDebug(5323) << "Emitting createdComment()";
01034 }
01035 
01036 void GDataPrivate::slotRemoveCommentData( KIO::Job *job, const QByteArray &data )
01037 {
01038   kDebug(5323);
01039   if( !job ) {
01040     kError(5323) << "job is a null pointer.";
01041     return;
01042   }
01043   unsigned int oldSize = mRemoveCommentBuffer[ job ].size();
01044   mRemoveCommentBuffer[ job ].resize( oldSize + data.size() );
01045   memcpy( mRemoveCommentBuffer[ job ].data() + oldSize, data.data(), data.size() );
01046 }
01047 
01048 void GDataPrivate::slotRemoveComment( KJob *job )
01049 {
01050   kDebug(5323);
01051   if( !job ) {
01052     kError(5323) << "job is a null pointer.";
01053     return;
01054   }
01055   const QString data = QString::fromUtf8( mRemoveCommentBuffer[ job ].data(),
01056                                           mRemoveCommentBuffer[ job ].size() );
01057   mRemoveCommentBuffer[ job ].resize( 0 );
01058 
01059   Q_Q( GData );
01060 
01061   KBlog::BlogComment *comment = mRemoveCommentMap[ job ].values().first();
01062   KBlog::BlogPost *post = mRemoveCommentMap[ job ].keys().first();
01063   mRemoveCommentMap.remove( job );
01064 
01065   if ( job->error() != 0 ) {
01066     kError(5323) << "slotRemoveComment error:" << job->errorString();
01067     emit q->errorComment( GData::Atom, job->errorString(), post, comment );
01068     return;
01069   }
01070 
01071   comment->setStatus( BlogComment::Created );
01072   emit q->removedComment( post, comment );
01073   kDebug(5323) << "Emitting removedComment()";
01074 }
01075 
01076 #include "gdata.moc"

KBlog Client Library

Skip menu "KBlog Client Library"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

KDE-PIM Libraries

Skip menu "KDE-PIM Libraries"
  • kabc
  • kblog
  • kcal
  • kimap
  • kioslave
  •   imap4
  •   mbox
  • kldap
  • kmime
  • kpimidentities
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Generated for KDE-PIM Libraries by doxygen 1.5.5
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal