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 #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();
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();
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
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
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
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
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+)" );
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+)" );
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
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"