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