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