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() << "Job Error: "<<job->errorString();
00527 emit q->error( GData::Other, job->errorString() );
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["url"] = ( *it )->link();
00559 blogInfo["summary"] = ( *it )->description();
00560 blogsList << blogInfo;
00561 } else {
00562 kError() << "QRegExp rx( 'blog-(\\d+)' does not match anything in:"
00563 << ( *it )->id();
00564 emit q->error( GData::Other, i18n( "Could not regexp the blog id path." ) );
00565 }
00566 }
00567 kDebug() << "Emitting listedBlogs(); ";
00568 emit q->listedBlogs( blogsList );
00569 }
00570
00571 void GDataPrivate::slotListComments( Syndication::Loader *loader,
00572 Syndication::FeedPtr feed,
00573 Syndication::ErrorCode status )
00574 {
00575 kDebug();
00576 Q_Q( GData );
00577 if( !loader ) {
00578 kError() << "loader is a null pointer.";
00579 return;
00580 }
00581 BlogPost *post = mListCommentsMap[ loader ];
00582 mListCommentsMap.remove( loader );
00583
00584 if ( status != Syndication::Success ) {
00585 emit q->errorPost( GData::Atom, i18n( "Could not get comments." ), post );
00586 return;
00587 }
00588
00589 QList<KBlog::BlogComment> commentList;
00590
00591 QList<Syndication::ItemPtr> items = feed->items();
00592 QList<Syndication::ItemPtr>::ConstIterator it = items.constBegin();
00593 QList<Syndication::ItemPtr>::ConstIterator end = items.constEnd();
00594 for ( ; it != end; ++it ) {
00595 BlogComment comment;
00596 QRegExp rx( "post-(\\d+)" );
00597 if ( rx.indexIn( ( *it )->id() ) == -1 ) {
00598 kError() << "QRegExp rx( 'post-(\\d+)' does not match" << rx.cap(1);
00599 emit q->error( GData::Other, i18n( "Could not regexp the comment id path." ) );
00600 } else {
00601 comment.setCommentId( rx.cap(1) );
00602 }
00603 kDebug() << "QRegExp rx( 'post-(\\d+)' matches" << rx.cap(1);
00604 comment.setTitle( ( *it )->title() );
00605 comment.setContent( ( *it )->content() );
00606
00607 comment.setCreationDateTime(
00608 KDateTime( QDateTime::fromTime_t( ( *it )->datePublished() ),
00609 KDateTime::Spec::UTC() ) );
00610 comment.setModificationDateTime(
00611 KDateTime( QDateTime::fromTime_t( ( *it )->dateUpdated() ),
00612 KDateTime::Spec::UTC() ) );
00613 commentList.append( comment );
00614 }
00615 kDebug() << "Emitting listedComments()";
00616 emit q->listedComments( post, commentList );
00617 }
00618
00619 void GDataPrivate::slotListAllComments( Syndication::Loader *loader,
00620 Syndication::FeedPtr feed,
00621 Syndication::ErrorCode status )
00622 {
00623 kDebug();
00624 Q_Q( GData );
00625 if( !loader ) {
00626 kError() << "loader is a null pointer.";
00627 return;
00628 }
00629
00630 if ( status != Syndication::Success ) {
00631 emit q->error( GData::Atom, i18n( "Could not get comments." ) );
00632 return;
00633 }
00634
00635 QList<KBlog::BlogComment> commentList;
00636
00637 QList<Syndication::ItemPtr> items = feed->items();
00638 QList<Syndication::ItemPtr>::ConstIterator it = items.constBegin();
00639 QList<Syndication::ItemPtr>::ConstIterator end = items.constEnd();
00640 for ( ; it != end; ++it ) {
00641 BlogComment comment;
00642 QRegExp rx( "post-(\\d+)" );
00643 if ( rx.indexIn( ( *it )->id() ) == -1 ) {
00644 kError() << "QRegExp rx( 'post-(\\d+)' does not match"<< rx.cap(1);
00645 emit q->error( GData::Other, i18n( "Could not regexp the comment id path." ) );
00646 } else {
00647 comment.setCommentId( rx.cap(1) );
00648 }
00649
00650 kDebug() << "QRegExp rx( 'post-(\\d+)' matches" << rx.cap(1);
00651 comment.setTitle( ( *it )->title() );
00652 comment.setContent( ( *it )->content() );
00653
00654 comment.setCreationDateTime(
00655 KDateTime( QDateTime::fromTime_t( ( *it )->datePublished() ),
00656 KDateTime::Spec::UTC() ) );
00657 comment.setModificationDateTime(
00658 KDateTime( QDateTime::fromTime_t( ( *it )->dateUpdated() ),
00659 KDateTime::Spec::UTC() ) );
00660 commentList.append( comment );
00661 }
00662 kDebug() << "Emitting listedAllComments()";
00663 emit q->listedAllComments( commentList );
00664 }
00665
00666 void GDataPrivate::slotListRecentPosts( Syndication::Loader *loader,
00667 Syndication::FeedPtr feed,
00668 Syndication::ErrorCode status ) {
00669 kDebug();
00670 Q_Q( GData );
00671 if( !loader ) {
00672 kError() << "loader is a null pointer.";
00673 return;
00674 }
00675
00676 if ( status != Syndication::Success ) {
00677 emit q->error( GData::Atom, i18n( "Could not get posts." ) );
00678 return;
00679 }
00680 int number = 0;
00681
00682 if ( mListRecentPostsMap.contains( loader ) ) {
00683 number = mListRecentPostsMap[ loader ];
00684 }
00685 mListRecentPostsMap.remove( loader );
00686
00687 QList<KBlog::BlogPost> postList;
00688
00689 QList<Syndication::ItemPtr> items = feed->items();
00690 QList<Syndication::ItemPtr>::ConstIterator it = items.constBegin();
00691 QList<Syndication::ItemPtr>::ConstIterator end = items.constEnd();
00692 for ( ; it != end; ++it ) {
00693 BlogPost post;
00694 QRegExp rx( "post-(\\d+)" );
00695 if ( rx.indexIn( ( *it )->id() ) == -1 ) {
00696 kError() << "QRegExp rx( 'post-(\\d+)' does not match"<< rx.cap(1);
00697 emit q->error( GData::Other, i18n( "Could not regexp the post id path." ) );
00698 } else {
00699 post.setPostId( rx.cap(1) );
00700 }
00701
00702 kDebug() << "QRegExp rx( 'post-(\\d+)' matches" << rx.cap(1);
00703 post.setTitle( ( *it )->title() );
00704 post.setContent( ( *it )->content() );
00705 post.setLink( ( *it )->link() );
00706 QStringList labels;
00707 int catCount = ( *it )->categories().count();
00708 QList< Syndication::CategoryPtr > cats = ( *it )->categories();
00709 for(int i=0; i < catCount; ++i) {
00710 if(cats[i].get()->label().isEmpty()){
00711 labels.append(cats[i].get()->term());
00712 } else {
00713 labels.append(cats[i].get()->label());
00714 }
00715 }
00716 post.setTags(labels);
00717
00718 post.setCreationDateTime(
00719 KDateTime( QDateTime::fromTime_t( ( *it )->datePublished() ),
00720 KDateTime::Spec::UTC() ).toLocalZone() );
00721 post.setModificationDateTime(
00722 KDateTime( QDateTime::fromTime_t( ( *it )->dateUpdated() ),
00723 KDateTime::Spec::UTC() ).toLocalZone() );
00724 post.setStatus( BlogPost::Fetched );
00725 postList.append( post );
00726 if ( number-- == 0 ) {
00727 break;
00728 }
00729 }
00730 kDebug() << "Emitting listedRecentPosts()";
00731 emit q->listedRecentPosts( postList );
00732 }
00733
00734 void GDataPrivate::slotFetchPost( Syndication::Loader *loader,
00735 Syndication::FeedPtr feed,
00736 Syndication::ErrorCode status )
00737 {
00738 kDebug();
00739 Q_Q( GData );
00740 if( !loader ) {
00741 kError() << "loader is a null pointer.";
00742 return;
00743 }
00744
00745 bool success = false;
00746
00747 BlogPost *post = mFetchPostMap.take( loader );
00748 kError() << "Post" << post;
00749 post->postId();
00750
00751 if ( status != Syndication::Success ) {
00752 emit q->errorPost( GData::Atom, i18n( "Could not get posts." ), post );
00753 return;
00754 }
00755
00756 QString postId = post->postId();
00757 QList<Syndication::ItemPtr> items = feed->items();
00758 QList<Syndication::ItemPtr>::ConstIterator it = items.constBegin();
00759 QList<Syndication::ItemPtr>::ConstIterator end = items.constEnd();
00760 for ( ; it != end; ++it ) {
00761 QRegExp rx( "post-(\\d+)" );
00762 if ( rx.indexIn( ( *it )->id() ) != -1 && rx.cap(1) == postId ){
00763 kDebug() << "QRegExp rx( 'post-(\\d+)' matches" << rx.cap(1);
00764 post->setPostId( rx.cap(1) );
00765 post->setTitle( ( *it )->title() );
00766 post->setContent( ( *it )->content() );
00767 post->setStatus( BlogPost::Fetched );
00768 post->setLink( ( *it )->link() );
00769 post->setCreationDateTime(
00770 KDateTime( QDateTime::fromTime_t( ( *it )->datePublished() ),
00771 KDateTime::Spec::UTC() ).toLocalZone() );
00772 post->setModificationDateTime(
00773 KDateTime( QDateTime::fromTime_t( ( *it )->dateUpdated() ),
00774 KDateTime::Spec::UTC() ).toLocalZone() );
00775 kDebug() << "Emitting fetchedPost( postId=" << postId << ");";
00776 success = true;
00777 emit q->fetchedPost( post );
00778 break;
00779 }
00780 }
00781 if ( !success ) {
00782 kError() << "QRegExp rx( 'post-(\\d+)' does not match"
00783 << mFetchPostMap[ loader ]->postId() << ".";
00784 emit q->errorPost( GData::Other, i18n( "Could not regexp the blog id path." ), post );
00785 }
00786 }
00787
00788 void GDataPrivate::slotCreatePost( KJob *job )
00789 {
00790 kDebug();
00791 if( !job ) {
00792 kError() << "job is a null pointer.";
00793 return;
00794 }
00795 KIO::StoredTransferJob *stj = qobject_cast<KIO::StoredTransferJob*>(job);
00796 const QString data = QString::fromUtf8( stj->data(), stj->data().size() );
00797
00798 Q_Q( GData );
00799
00800 KBlog::BlogPost *post = mCreatePostMap[ job ];
00801 mCreatePostMap.remove( job );
00802
00803 if ( job->error() != 0 ) {
00804 kError() << "slotCreatePost error:" << job->errorString();
00805 emit q->errorPost( GData::Atom, job->errorString(), post );
00806 return;
00807 }
00808
00809 QRegExp rxId( "post-(\\d+)" );
00810 if ( rxId.indexIn( data ) == -1 ) {
00811 kError() << "Could not regexp the id out of the result:" << data;
00812 emit q->errorPost( GData::Atom,
00813 i18n( "Could not regexp the id out of the result." ), post );
00814 return;
00815 }
00816 kDebug() << "QRegExp rx( 'post-(\\d+)' ) matches" << rxId.cap(1);
00817
00818 QRegExp rxPub( "<published>(.+)</published>" );
00819 if ( rxPub.indexIn( data ) == -1 ) {
00820 kError() << "Could not regexp the published time out of the result:" << data;
00821 emit q->errorPost( GData::Atom,
00822 i18n( "Could not regexp the published time out of the result." ), post );
00823 return;
00824 }
00825 kDebug() << "QRegExp rx( '<published>(.+)</published>' ) matches" << rxPub.cap(1);
00826
00827 QRegExp rxUp( "<updated>(.+)</updated>" );
00828 if ( rxUp.indexIn( data ) == -1 ) {
00829 kError() << "Could not regexp the update time out of the result:" << data;
00830 emit q->errorPost( GData::Atom,
00831 i18n( "Could not regexp the update time out of the result." ), post );
00832 return;
00833 }
00834 kDebug() << "QRegExp rx( '<updated>(.+)</updated>' ) matches" << rxUp.cap(1);
00835
00836 post->setPostId( rxId.cap(1) );
00837 post->setCreationDateTime( KDateTime().fromString( rxPub.cap(1) ).toLocalZone() );
00838 post->setModificationDateTime( KDateTime().fromString( rxUp.cap(1) ) );
00839 post->setStatus( BlogPost::Created );
00840 kDebug() << "Emitting createdPost()";
00841 emit q->createdPost( post );
00842 }
00843
00844 void GDataPrivate::slotModifyPost( KJob *job )
00845 {
00846 kDebug();
00847 if( !job ) {
00848 kError() << "job is a null pointer.";
00849 return;
00850 }
00851 KIO::StoredTransferJob *stj = qobject_cast<KIO::StoredTransferJob*>(job);
00852 const QString data = QString::fromUtf8( stj->data(), stj->data().size() );
00853
00854 KBlog::BlogPost *post = mModifyPostMap[ job ];
00855 mModifyPostMap.remove( job );
00856 Q_Q( GData );
00857 if ( job->error() != 0 ) {
00858 kError() << "slotModifyPost error:" << job->errorString();
00859 emit q->errorPost( GData::Atom, job->errorString(), post );
00860 return;
00861 }
00862
00863 QRegExp rxId( "post-(\\d+)" );
00864 if ( rxId.indexIn( data ) == -1 ) {
00865 kError() << "Could not regexp the id out of the result:" << data;
00866 emit q->errorPost( GData::Atom,
00867 i18n( "Could not regexp the id out of the result." ), post );
00868 return;
00869 }
00870 kDebug() << "QRegExp rx( 'post-(\\d+)' ) matches" << rxId.cap(1);
00871
00872 QRegExp rxPub( "<published>(.+)</published>" );
00873 if ( rxPub.indexIn( data ) == -1 ) {
00874 kError() << "Could not regexp the published time out of the result:" << data;
00875 emit q->errorPost( GData::Atom,
00876 i18n( "Could not regexp the published time out of the result." ), post );
00877 return;
00878 }
00879 kDebug() << "QRegExp rx( '<published>(.+)</published>' ) matches" << rxPub.cap(1);
00880
00881 QRegExp rxUp( "<updated>(.+)</updated>" );
00882 if ( rxUp.indexIn( data ) == -1 ) {
00883 kError() << "Could not regexp the update time out of the result:" << data;
00884 emit q->errorPost( GData::Atom,
00885 i18n( "Could not regexp the update time out of the result." ), post );
00886 return;
00887 }
00888 kDebug() << "QRegExp rx( '<updated>(.+)</updated>' ) matches" << rxUp.cap(1);
00889 post->setPostId( rxId.cap(1) );
00890 post->setCreationDateTime( KDateTime().fromString( rxPub.cap(1) ) );
00891 post->setModificationDateTime( KDateTime().fromString( rxUp.cap(1) ) );
00892 post->setStatus( BlogPost::Modified );
00893 emit q->modifiedPost( post );
00894 }
00895
00896 void GDataPrivate::slotRemovePost( KJob *job )
00897 {
00898 kDebug();
00899 if( !job ) {
00900 kError() << "job is a null pointer.";
00901 return;
00902 }
00903 KIO::StoredTransferJob *stj = qobject_cast<KIO::StoredTransferJob*>(job);
00904 const QString data = QString::fromUtf8( stj->data(), stj->data().size() );
00905
00906 KBlog::BlogPost *post = mRemovePostMap[ job ];
00907 mRemovePostMap.remove( job );
00908 Q_Q( GData );
00909 if ( job->error() != 0 ) {
00910 kError() << "slotRemovePost error:" << job->errorString();
00911 emit q->errorPost( GData::Atom, job->errorString(), post );
00912 return;
00913 }
00914
00915 post->setStatus( BlogPost::Removed );
00916 kDebug() << "Emitting removedPost()";
00917 emit q->removedPost( post );
00918 }
00919
00920 void GDataPrivate::slotCreateComment( KJob *job )
00921 {
00922 kDebug();
00923 if( !job ) {
00924 kError() << "job is a null pointer.";
00925 return;
00926 }
00927 KIO::StoredTransferJob *stj = qobject_cast<KIO::StoredTransferJob*>(job);
00928 const QString data = QString::fromUtf8( stj->data(), stj->data().size() );
00929 kDebug() << "Dump data: " << data;
00930
00931 Q_Q( GData );
00932
00933 KBlog::BlogComment *comment = mCreateCommentMap[ job ].values().first();
00934 KBlog::BlogPost *post = mCreateCommentMap[ job ].keys().first();
00935 mCreateCommentMap.remove( job );
00936
00937 if ( job->error() != 0 ) {
00938 kError() << "slotCreateComment error:" << job->errorString();
00939 emit q->errorComment( GData::Atom, job->errorString(), post, comment );
00940 return;
00941 }
00942
00943
00944 QRegExp rxId( "post-(\\d+)" );
00945 if ( rxId.indexIn( data ) == -1 ) {
00946 kError() << "Could not regexp the id out of the result:" << data;
00947 emit q->errorPost( GData::Atom,
00948 i18n( "Could not regexp the id out of the result." ), post );
00949 return;
00950 }
00951 kDebug() << "QRegExp rx( 'post-(\\d+)' ) matches" << rxId.cap(1);
00952
00953 QRegExp rxPub( "<published>(.+)</published>" );
00954 if ( rxPub.indexIn( data ) == -1 ) {
00955 kError() << "Could not regexp the published time out of the result:" << data;
00956 emit q->errorPost( GData::Atom,
00957 i18n( "Could not regexp the published time out of the result." ), post );
00958 return;
00959 }
00960 kDebug() << "QRegExp rx( '<published>(.+)</published>' ) matches" << rxPub.cap(1);
00961
00962 QRegExp rxUp( "<updated>(.+)</updated>" );
00963 if ( rxUp.indexIn( data ) == -1 ) {
00964 kError() << "Could not regexp the update time out of the result:" << data;
00965 emit q->errorPost( GData::Atom,
00966 i18n( "Could not regexp the update time out of the result." ), post );
00967 return;
00968 }
00969 kDebug() << "QRegExp rx( '<updated>(.+)</updated>' ) matches" << rxUp.cap(1);
00970 comment->setCommentId( rxId.cap(1) );
00971 comment->setCreationDateTime( KDateTime().fromString( rxPub.cap(1) ) );
00972 comment->setModificationDateTime( KDateTime().fromString( rxUp.cap(1) ) );
00973 comment->setStatus( BlogComment::Created );
00974 kDebug() << "Emitting createdComment()";
00975 emit q->createdComment( post, comment );
00976 }
00977
00978 void GDataPrivate::slotRemoveComment( KJob *job )
00979 {
00980 kDebug();
00981 if( !job ) {
00982 kError() << "job is a null pointer.";
00983 return;
00984 }
00985 KIO::StoredTransferJob *stj = qobject_cast<KIO::StoredTransferJob*>(job);
00986 const QString data = QString::fromUtf8( stj->data(), stj->data().size() );
00987
00988 Q_Q( GData );
00989
00990 KBlog::BlogComment *comment = mRemoveCommentMap[ job ].values().first();
00991 KBlog::BlogPost *post = mRemoveCommentMap[ job ].keys().first();
00992 mRemoveCommentMap.remove( job );
00993
00994 if ( job->error() != 0 ) {
00995 kError() << "slotRemoveComment error:" << job->errorString();
00996 emit q->errorComment( GData::Atom, job->errorString(), post, comment );
00997 return;
00998 }
00999
01000 comment->setStatus( BlogComment::Created );
01001 kDebug() << "Emitting removedComment()";
01002 emit q->removedComment( post, comment );
01003 }
01004
01005 #include "gdata.moc"