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