00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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();
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();
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
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
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
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
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+)" );
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+)" );
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
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"