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 atomMarkup += "<author>";
00292 if ( !fullName().isEmpty() ) {
00293 atomMarkup += "<name>" + fullName() + "</name>";
00294 }
00295 atomMarkup += "<email>" + username() + "</email>";
00296 atomMarkup += "</author>";
00297 atomMarkup += "</entry>";
00298
00299 QByteArray postData;
00300 QDataStream stream( &postData, QIODevice::WriteOnly );
00301 stream.writeRawData( atomMarkup.toUtf8(), atomMarkup.toUtf8().length() );
00302
00303 KIO::TransferJob *job = KIO::http_post(
00304 KUrl( "http://www.blogger.com/feeds/" + blogId() + "/posts/default" ),
00305 postData, KIO::HideProgressInfo );
00306
00307 Q_ASSERT ( job );
00308 d->mCreatePostMap[ job ] = post;
00309
00310 job->addMetaData( "content-type", "Content-Type: application/atom+xml; charset=utf-8" );
00311 job->addMetaData( "ConnectTimeout", "50" );
00312 job->addMetaData( "UserAgent", userAgent() );
00313 job->addMetaData( "customHTTPHeader",
00314 "Authorization: GoogleLogin auth=" + d->mAuthenticationString );
00315
00316 connect( job, SIGNAL(data(KIO::Job*,const QByteArray&)),
00317 this, SLOT(slotCreatePostData(KIO::Job*,const QByteArray&)) );
00318 connect( job, SIGNAL(result(KJob*)),
00319 this, SLOT(slotCreatePost(KJob*)) );
00320 }
00321
00322 void GData::removePost( KBlog::BlogPost *post )
00323 {
00324 kDebug();
00325 Q_D( GData );
00326
00327 if ( !post ) {
00328 kError() << "post is null pointer";
00329 return;
00330 }
00331
00332 if ( !d->authenticate() ){
00333 kError() << "Authentication failed.";
00334 emit errorPost( Atom, i18n( "Authentication failed." ), post );
00335 return;
00336 }
00337
00338 QByteArray postData;
00339
00340 KIO::TransferJob *job = KIO::http_post(
00341 KUrl( "http://www.blogger.com/feeds/" + blogId() + "/posts/default/" + post->postId() ),
00342 postData, KIO::HideProgressInfo );
00343
00344 d->mRemovePostMap[ job ] = post;
00345
00346 if ( !job ) {
00347 kWarning() << "Unable to create KIO job for http://www.blogger.com/feeds/"
00348 << blogId() << "/posts/default/" + post->postId();
00349 }
00350
00351 job->addMetaData( "ConnectTimeout", "50" );
00352 job->addMetaData( "UserAgent", userAgent() );
00353 job->addMetaData( "customHTTPHeader",
00354 "Authorization: GoogleLogin auth=" + d->mAuthenticationString +
00355 "\r\nX-HTTP-Method-Override: DELETE" );
00356
00357 connect( job, SIGNAL(data(KIO::Job*,const QByteArray&)),
00358 this, SLOT(slotRemovePostData(KIO::Job*,const QByteArray&)) );
00359 connect( job, SIGNAL(result(KJob*)),
00360 this, SLOT(slotRemovePost(KJob*)) );
00361 }
00362
00363 void GData::createComment( KBlog::BlogPost *post, KBlog::BlogComment *comment )
00364 {
00365 kDebug();
00366
00367 if ( !comment ) {
00368 kError() << "comment is null pointer";
00369 return;
00370 }
00371
00372 if ( !post ) {
00373 kError() << "post is null pointer";
00374 return;
00375 }
00376
00377 Q_D( GData );
00378 if ( !d->authenticate() ){
00379 kError() << "Authentication failed.";
00380 emit errorComment( Atom, i18n( "Authentication failed." ), post, comment );
00381 return;
00382 }
00383 QString atomMarkup = "<entry xmlns='http://www.w3.org/2005/Atom'>";
00384 atomMarkup += "<title type=\"text\">" + comment->title() + "</title>";
00385 atomMarkup += "<content type=\"html\">" + comment->content() + "</content>";
00386 atomMarkup += "<author>";
00387 atomMarkup += "<name>" + comment->name() + "</name>";
00388 atomMarkup += "<email>" + comment->email() + "</email>";
00389 atomMarkup += "</author></entry>";
00390
00391 QByteArray postData;
00392 kDebug() << postData;
00393 QDataStream stream( &postData, QIODevice::WriteOnly );
00394 stream.writeRawData( atomMarkup.toUtf8(), atomMarkup.toUtf8().length() );
00395
00396 KIO::TransferJob *job = KIO::http_post(
00397 KUrl( "http://www.blogger.com/feeds/" + blogId() + "/" + post->postId() + "/comments/default" ),
00398 postData, KIO::HideProgressInfo );
00399
00400 d->mCreateCommentMap[ job ][post] = comment;
00401
00402 if ( !job ) {
00403 kWarning() << "Unable to create KIO job for http://www.blogger.com/feeds/"
00404 << blogId() << "/" << post->postId() << "/comments/default";
00405 }
00406
00407 job->addMetaData( "content-type", "Content-Type: application/atom+xml; charset=utf-8" );
00408 job->addMetaData( "ConnectTimeout", "50" );
00409 job->addMetaData( "customHTTPHeader",
00410 "Authorization: GoogleLogin auth=" + d->mAuthenticationString );
00411 job->addMetaData( "UserAgent", userAgent() );
00412
00413 connect( job, SIGNAL(data(KIO::Job*,const QByteArray&)),
00414 this, SLOT(slotCreateCommentData(KIO::Job*,const QByteArray&)) );
00415 connect( job, SIGNAL(result(KJob*)),
00416 this, SLOT(slotCreateComment(KJob*)) );
00417 }
00418
00419 void GData::removeComment( KBlog::BlogPost *post, KBlog::BlogComment *comment )
00420 {
00421 kDebug();
00422 Q_D( GData );
00423 kDebug();
00424
00425 if ( !comment ) {
00426 kError() << "comment is null pointer";
00427 return;
00428 }
00429
00430 if ( !post ) {
00431 kError() << "post is null pointer";
00432 return;
00433 }
00434
00435 if ( !d->authenticate() ){
00436 kError() << "Authentication failed.";
00437 emit errorComment( Atom, i18n( "Authentication failed." ), post, comment );
00438 return;
00439 }
00440
00441 QByteArray postData;
00442
00443 KIO::TransferJob *job = KIO::http_post(
00444 KUrl( "http://www.blogger.com/feeds/" + blogId() + "/" + post->postId() +
00445 "/comments/default/" + comment->commentId() ),
00446 postData, 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(data(KIO::Job*,const QByteArray&)),
00462 this, SLOT(slotRemoveCommentData(KIO::Job*,const QByteArray&)) );
00463 connect( job, SIGNAL(result(KJob*)),
00464 this, SLOT(slotRemoveComment(KJob*)) );
00465 }
00466
00467 GDataPrivate::GDataPrivate():mAuthenticationString(), mAuthenticationTime()
00468 {
00469 kDebug();
00470 }
00471
00472 GDataPrivate::~GDataPrivate()
00473 {
00474 kDebug();
00475 }
00476
00477 bool GDataPrivate::authenticate()
00478 {
00479 kDebug();
00480 Q_Q( GData );
00481 QByteArray data;
00482 KUrl authGateway( "https://www.google.com/accounts/ClientLogin" );
00483 authGateway.addQueryItem( "Email", q->username() );
00484 authGateway.addQueryItem( "Passwd", q->password() );
00485 authGateway.addQueryItem( "source", q->userAgent() );
00486 authGateway.addQueryItem( "service", "blogger" );
00487 if ( !mAuthenticationTime.isValid() ||
00488 QDateTime::currentDateTime().toTime_t() - mAuthenticationTime.toTime_t() > TIMEOUT ||
00489 mAuthenticationString.isEmpty() ) {
00490 KIO::Job *job = KIO::http_post( authGateway, QByteArray(), KIO::HideProgressInfo );
00491 if ( KIO::NetAccess::synchronousRun( job, (QWidget*)0, &data, &authGateway ) ) {
00492 kDebug() << "Fetched authentication result for"
00493 << authGateway.prettyUrl() << ".";
00494 kDebug() << "Authentication response:" << data;
00495 QRegExp rx( "Auth=(.+)" );
00496 if ( rx.indexIn( data ) != -1 ) {
00497 kDebug() << "RegExp got authentication string:" << rx.cap(1);
00498 mAuthenticationString = rx.cap(1);
00499 mAuthenticationTime = QDateTime::currentDateTime();
00500 return true;
00501 }
00502 }
00503 return false;
00504 }
00505 return true;
00506 }
00507
00508 void GDataPrivate::slotFetchProfileIdData( KIO::Job *job, const QByteArray &data )
00509 {
00510 kDebug();
00511 if( !job ){
00512 kError() << "job is a null pointer.";
00513 return;
00514 }
00515 unsigned int oldSize = mFetchProfileIdBuffer[ job ].size();
00516 mFetchProfileIdBuffer[ job ].resize( oldSize + data.size() );
00517 memcpy( mFetchProfileIdBuffer[ job ].data() + oldSize, data.data(), data.size() );
00518 }
00519
00520 void GDataPrivate::slotFetchProfileId( KJob *job )
00521 {
00522 kDebug();
00523 if( !job ){
00524 kError() << "job is a null pointer.";
00525 return;
00526 }
00527 Q_Q( GData );
00528 if ( !job->error() ) {
00529 QRegExp pid( "http://www.blogger.com/profile/(\\d+)" );
00530 if ( pid.indexIn( mFetchProfileIdBuffer[ job ] ) != -1 ) {
00531 q->setProfileId( pid.cap(1) );
00532 kDebug() << "QRegExp bid( 'http://www.blogger.com/profile/(\\d+)' matches" << pid.cap(1);
00533 emit q->fetchedProfileId( pid.cap(1) );
00534 } else {
00535 kError() << "QRegExp bid( 'http://www.blogger.com/profile/(\\d+)' "
00536 << " could not regexp the Profile ID";
00537 emit q->error( GData::Other, i18n( "Could not regexp the Profile ID." ) );
00538 emit q->fetchedProfileId( QString() );
00539 }
00540 } else {
00541 kError() << "Could not fetch the homepage data.";
00542 emit q->error( GData::Other, i18n( "Could not fetch the homepage data." ) );
00543 emit q->fetchedProfileId( QString() );
00544 }
00545 mFetchProfileIdBuffer[ job ].resize( 0 );
00546 mFetchProfileIdBuffer.remove( job );
00547 }
00548
00549 void GDataPrivate::slotListBlogs( Syndication::Loader *loader,
00550 Syndication::FeedPtr feed,
00551 Syndication::ErrorCode status ) {
00552 kDebug();
00553 Q_Q( GData );
00554 if( !loader ) {
00555 kError() << "loader is a null pointer.";
00556 return;
00557 }
00558 if ( status != Syndication::Success ) {
00559 emit q->error( GData::Atom, i18n( "Could not get blogs." ) );
00560 return;
00561 }
00562
00563 QList<QMap<QString,QString> > blogsList;
00564
00565 QList<Syndication::ItemPtr> items = feed->items();
00566 QList<Syndication::ItemPtr>::ConstIterator it = items.begin();
00567 QList<Syndication::ItemPtr>::ConstIterator end = items.end();
00568 for ( ; it != end; ++it ) {
00569 QRegExp rx( "blog-(\\d+)" );
00570 QMap<QString,QString> blogInfo;
00571 if ( rx.indexIn( ( *it )->id() ) != -1 ) {
00572 kDebug() << "QRegExp rx( 'blog-(\\d+)' matches" << rx.cap(1);
00573 blogInfo["id"] = rx.cap(1);
00574 blogInfo["title"] = ( *it )->title();
00575 blogInfo["summary"] = ( *it )->description();
00576 blogsList << blogInfo;
00577 } else {
00578 kError() << "QRegExp rx( 'blog-(\\d+)' does not match anything in:"
00579 << ( *it )->id();
00580 emit q->error( GData::Other, i18n( "Could not regexp the blog id path." ) );
00581 }
00582 }
00583 kDebug() << "Emitting listedBlogs(); ";
00584 emit q->listedBlogs( blogsList );
00585 }
00586
00587 void GDataPrivate::slotListComments( Syndication::Loader *loader,
00588 Syndication::FeedPtr feed,
00589 Syndication::ErrorCode status )
00590 {
00591 kDebug();
00592 Q_Q( GData );
00593 if( !loader ) {
00594 kError() << "loader is a null pointer.";
00595 return;
00596 }
00597 BlogPost *post = mListCommentsMap[ loader ];
00598 mListCommentsMap.remove( loader );
00599
00600 if ( status != Syndication::Success ) {
00601 emit q->errorPost( GData::Atom, i18n( "Could not get comments." ), post );
00602 return;
00603 }
00604
00605 QList<KBlog::BlogComment> commentList;
00606
00607 QList<Syndication::ItemPtr> items = feed->items();
00608 QList<Syndication::ItemPtr>::ConstIterator it = items.begin();
00609 QList<Syndication::ItemPtr>::ConstIterator end = items.end();
00610 for ( ; it != end; ++it ) {
00611 BlogComment comment;
00612 QRegExp rx( "post-(\\d+)" );
00613 if ( rx.indexIn( ( *it )->id() ) == -1 ) {
00614 kError() << "QRegExp rx( 'post-(\\d+)' does not match" << rx.cap(1);
00615 emit q->error( GData::Other, i18n( "Could not regexp the comment id path." ) );
00616 } else {
00617 comment.setCommentId( rx.cap(1) );
00618 }
00619 kDebug() << "QRegExp rx( 'post-(\\d+)' matches" << rx.cap(1);
00620 comment.setTitle( ( *it )->title() );
00621 comment.setContent( ( *it )->content() );
00622
00623 comment.setCreationDateTime(
00624 KDateTime( QDateTime::fromTime_t( ( *it )->datePublished() ),
00625 KDateTime::Spec::UTC() ) );
00626 comment.setModificationDateTime(
00627 KDateTime( QDateTime::fromTime_t( ( *it )->dateUpdated() ),
00628 KDateTime::Spec::UTC() ) );
00629 commentList.append( comment );
00630 }
00631 kDebug() << "Emitting listedComments()";
00632 emit q->listedComments( post, commentList );
00633 }
00634
00635 void GDataPrivate::slotListAllComments( Syndication::Loader *loader,
00636 Syndication::FeedPtr feed,
00637 Syndication::ErrorCode status )
00638 {
00639 kDebug();
00640 Q_Q( GData );
00641 if( !loader ) {
00642 kError() << "loader is a null pointer.";
00643 return;
00644 }
00645
00646 if ( status != Syndication::Success ) {
00647 emit q->error( GData::Atom, i18n( "Could not get comments." ) );
00648 return;
00649 }
00650
00651 QList<KBlog::BlogComment> commentList;
00652
00653 QList<Syndication::ItemPtr> items = feed->items();
00654 QList<Syndication::ItemPtr>::ConstIterator it = items.begin();
00655 QList<Syndication::ItemPtr>::ConstIterator end = items.end();
00656 for ( ; it != end; ++it ) {
00657 BlogComment comment;
00658 QRegExp rx( "post-(\\d+)" );
00659 if ( rx.indexIn( ( *it )->id() ) == -1 ) {
00660 kError() << "QRegExp rx( 'post-(\\d+)' does not match"<< rx.cap(1);
00661 emit q->error( GData::Other, i18n( "Could not regexp the comment id path." ) );
00662 } else {
00663 comment.setCommentId( rx.cap(1) );
00664 }
00665
00666 kDebug() << "QRegExp rx( 'post-(\\d+)' matches" << rx.cap(1);
00667 comment.setTitle( ( *it )->title() );
00668 comment.setContent( ( *it )->content() );
00669
00670 comment.setCreationDateTime(
00671 KDateTime( QDateTime::fromTime_t( ( *it )->datePublished() ),
00672 KDateTime::Spec::UTC() ) );
00673 comment.setModificationDateTime(
00674 KDateTime( QDateTime::fromTime_t( ( *it )->dateUpdated() ),
00675 KDateTime::Spec::UTC() ) );
00676 commentList.append( comment );
00677 }
00678 kDebug() << "Emitting listedAllComments()";
00679 emit q->listedAllComments( commentList );
00680 }
00681
00682 void GDataPrivate::slotListRecentPosts( Syndication::Loader *loader,
00683 Syndication::FeedPtr feed,
00684 Syndication::ErrorCode status ) {
00685 kDebug();
00686 Q_Q( GData );
00687 if( !loader ) {
00688 kError() << "loader is a null pointer.";
00689 return;
00690 }
00691
00692 if ( status != Syndication::Success ) {
00693 emit q->error( GData::Atom, i18n( "Could not get posts." ) );
00694 return;
00695 }
00696 int number = 0;
00697
00698 if ( mListRecentPostsMap.contains( loader ) ) {
00699 number = mListRecentPostsMap[ loader ];
00700 }
00701 mListRecentPostsMap.remove( loader );
00702
00703 QList<KBlog::BlogPost> postList;
00704
00705 QList<Syndication::ItemPtr> items = feed->items();
00706 QList<Syndication::ItemPtr>::ConstIterator it = items.begin();
00707 QList<Syndication::ItemPtr>::ConstIterator end = items.end();
00708 for ( ; it != end; ++it ) {
00709 BlogPost post;
00710 QRegExp rx( "post-(\\d+)" );
00711 if ( rx.indexIn( ( *it )->id() ) == -1 ) {
00712 kError() << "QRegExp rx( 'post-(\\d+)' does not match"<< rx.cap(1);
00713 emit q->error( GData::Other, i18n( "Could not regexp the post id path." ) );
00714 } else {
00715 post.setPostId( rx.cap(1) );
00716 }
00717
00718 kDebug() << "QRegExp rx( 'post-(\\d+)' matches" << rx.cap(1);
00719 post.setTitle( ( *it )->title() );
00720 post.setContent( ( *it )->content() );
00721 post.setLink( ( *it )->link() );
00722
00723 post.setCreationDateTime(
00724 KDateTime( QDateTime::fromTime_t( ( *it )->datePublished() ),
00725 KDateTime::Spec::UTC() ) );
00726 post.setModificationDateTime(
00727 KDateTime( QDateTime::fromTime_t( ( *it )->dateUpdated() ),
00728 KDateTime::Spec::UTC() ) );
00729 post.setStatus( BlogPost::Fetched );
00730 postList.append( post );
00731 if ( number-- == 0 ) {
00732 break;
00733 }
00734 }
00735 kDebug() << "Emitting listedRecentPosts()";
00736 emit q->listedRecentPosts( postList );
00737 }
00738
00739 void GDataPrivate::slotFetchPost( Syndication::Loader *loader,
00740 Syndication::FeedPtr feed,
00741 Syndication::ErrorCode status )
00742 {
00743 kDebug();
00744 Q_Q( GData );
00745 if( !loader ) {
00746 kError() << "loader is a null pointer.";
00747 return;
00748 }
00749
00750 bool success = false;
00751
00752 BlogPost *post = mFetchPostMap[ loader ];
00753
00754 if ( status != Syndication::Success ) {
00755 emit q->errorPost( GData::Atom, i18n( "Could not get posts." ), post );
00756 return;
00757 }
00758 QList<Syndication::ItemPtr> items = feed->items();
00759 QList<Syndication::ItemPtr>::ConstIterator it = items.begin();
00760 QList<Syndication::ItemPtr>::ConstIterator end = items.end();
00761 for ( ; it != end; ++it ) {
00762 QRegExp rx( "post-(\\d+)" );
00763 if ( rx.indexIn( ( *it )->id() ) != -1 && rx.cap(1) == post->postId() ){
00764 kDebug() << "QRegExp rx( 'post-(\\d+)' matches" << rx.cap(1);
00765 post->setPostId( rx.cap(1) );
00766 post->setTitle( ( *it )->title() );
00767 post->setContent( ( *it )->content() );
00768 post->setStatus( BlogPost::Fetched );
00769 post->setLink( ( *it )->link() );
00770
00771 post->setCreationDateTime(
00772 KDateTime( QDateTime::fromTime_t( ( *it )->datePublished() ),
00773 KDateTime::Spec::UTC() ) );
00774 post->setModificationDateTime(
00775 KDateTime( QDateTime::fromTime_t( ( *it )->dateUpdated() ),
00776 KDateTime::Spec::UTC() ) );
00777 kDebug() << "Emitting fetchedPost( postId=" << post->postId() << ");";
00778 success = true;
00779 emit q->fetchedPost( post );
00780 }
00781 }
00782 if ( !success ) {
00783 kError() << "QRegExp rx( 'post-(\\d+)' does not match"
00784 << mFetchPostMap[ loader ]->postId() << ".";
00785 emit q->errorPost( GData::Other, i18n( "Could not regexp the blog id path." ), post );
00786 }
00787 mFetchPostMap.remove( loader );
00788 }
00789
00790 void GDataPrivate::slotCreatePostData( KIO::Job *job, const QByteArray &data )
00791 {
00792 kDebug();
00793 if( !job ) {
00794 kError() << "job is a null pointer.";
00795 return;
00796 }
00797 unsigned int oldSize = mCreatePostBuffer[ job ].size();
00798 mCreatePostBuffer[ job ].resize( oldSize + data.size() );
00799 memcpy( mCreatePostBuffer[ job ].data() + oldSize, data.data(), data.size() );
00800 }
00801
00802 void GDataPrivate::slotCreatePost( KJob *job )
00803 {
00804 kDebug();
00805 if( !job ) {
00806 kError() << "job is a null pointer.";
00807 return;
00808 }
00809 const QString data = QString::fromUtf8( mCreatePostBuffer[ job ].data(),
00810 mCreatePostBuffer[ job ].size() );
00811 mCreatePostBuffer[ job ].resize( 0 );
00812
00813 Q_Q( GData );
00814
00815 KBlog::BlogPost *post = mCreatePostMap[ job ];
00816 mCreatePostMap.remove( job );
00817
00818 if ( job->error() != 0 ) {
00819 kError() << "slotCreatePost error:" << job->errorString();
00820 emit q->errorPost( GData::Atom, job->errorString(), post );
00821 return;
00822 }
00823
00824 QRegExp rxId( "post-(\\d+)" );
00825 if ( rxId.indexIn( data ) == -1 ) {
00826 kError() << "Could not regexp the id out of the result:" << data;
00827 emit q->errorPost( GData::Atom,
00828 i18n( "Could not regexp the id out of the result." ), post );
00829 return;
00830 }
00831 kDebug() << "QRegExp rx( 'post-(\\d+)' ) matches" << rxId.cap(1);
00832
00833 QRegExp rxPub( "<published>(.+)</published>" );
00834 if ( rxPub.indexIn( data ) == -1 ) {
00835 kError() << "Could not regexp the published time out of the result:" << data;
00836 emit q->errorPost( GData::Atom,
00837 i18n( "Could not regexp the published time out of the result." ), post );
00838 return;
00839 }
00840 kDebug() << "QRegExp rx( '<published>(.+)</published>' ) matches" << rxPub.cap(1);
00841
00842 QRegExp rxUp( "<updated>(.+)</updated>" );
00843 if ( rxUp.indexIn( data ) == -1 ) {
00844 kError() << "Could not regexp the update time out of the result:" << data;
00845 emit q->errorPost( GData::Atom,
00846 i18n( "Could not regexp the update time out of the result." ), post );
00847 return;
00848 }
00849 kDebug() << "QRegExp rx( '<updated>(.+)</updated>' ) matches" << rxUp.cap(1);
00850
00851 post->setPostId( rxId.cap(1) );
00852 post->setCreationDateTime( KDateTime().fromString( rxPub.cap(1) ) );
00853 post->setModificationDateTime( KDateTime().fromString( rxUp.cap(1) ) );
00854 post->setStatus( BlogPost::Created );
00855 kDebug() << "Emitting createdPost()";
00856 emit q->createdPost( post );
00857 }
00858
00859 void GDataPrivate::slotModifyPostData( KIO::Job *job, const QByteArray &data )
00860 {
00861 kDebug();
00862 if( !job ) {
00863 kError() << "job is a null pointer.";
00864 return;
00865 }
00866 unsigned int oldSize = mModifyPostBuffer[ job ].size();
00867 mModifyPostBuffer[ job ].resize( oldSize + data.size() );
00868 memcpy( mModifyPostBuffer[ job ].data() + oldSize, data.data(), data.size() );
00869 }
00870
00871 void GDataPrivate::slotModifyPost( KJob *job )
00872 {
00873 kDebug();
00874 if( !job ) {
00875 kError() << "job is a null pointer.";
00876 return;
00877 }
00878 const QString data = QString::fromUtf8( mModifyPostBuffer[ job ].data(),
00879 mModifyPostBuffer[ job ].size() );
00880 mModifyPostBuffer[ job ].resize( 0 );
00881
00882 KBlog::BlogPost *post = mModifyPostMap[ job ];
00883 mModifyPostMap.remove( job );
00884 Q_Q( GData );
00885 if ( job->error() != 0 ) {
00886 kError() << "slotModifyPost error:" << job->errorString();
00887 emit q->errorPost( GData::Atom, job->errorString(), post );
00888 return;
00889 }
00890
00891 QRegExp rxId( "post-(\\d+)" );
00892 if ( rxId.indexIn( data ) == -1 ) {
00893 kError() << "Could not regexp the id out of the result:" << data;
00894 emit q->errorPost( GData::Atom,
00895 i18n( "Could not regexp the id out of the result." ), post );
00896 return;
00897 }
00898 kDebug() << "QRegExp rx( 'post-(\\d+)' ) matches" << rxId.cap(1);
00899
00900 QRegExp rxPub( "<published>(.+)</published>" );
00901 if ( rxPub.indexIn( data ) == -1 ) {
00902 kError() << "Could not regexp the published time out of the result:" << data;
00903 emit q->errorPost( GData::Atom,
00904 i18n( "Could not regexp the published time out of the result." ), post );
00905 return;
00906 }
00907 kDebug() << "QRegExp rx( '<published>(.+)</published>' ) matches" << rxPub.cap(1);
00908
00909 QRegExp rxUp( "<updated>(.+)</updated>" );
00910 if ( rxUp.indexIn( data ) == -1 ) {
00911 kError() << "Could not regexp the update time out of the result:" << data;
00912 emit q->errorPost( GData::Atom,
00913 i18n( "Could not regexp the update time out of the result." ), post );
00914 return;
00915 }
00916 kDebug() << "QRegExp rx( '<updated>(.+)</updated>' ) matches" << rxUp.cap(1);
00917 post->setPostId( rxId.cap(1) );
00918 post->setCreationDateTime( KDateTime().fromString( rxPub.cap(1) ) );
00919 post->setModificationDateTime( KDateTime().fromString( rxUp.cap(1) ) );
00920 post->setStatus( BlogPost::Modified );
00921 emit q->modifiedPost( post );
00922 }
00923
00924 void GDataPrivate::slotRemovePostData( KIO::Job *job, const QByteArray &data )
00925 {
00926 kDebug();
00927 if( !job ) {
00928 kError() << "job is a null pointer.";
00929 return;
00930 }
00931 unsigned int oldSize = mRemovePostBuffer[ job ].size();
00932 mRemovePostBuffer[ job ].resize( oldSize + data.size() );
00933 memcpy( mRemovePostBuffer[ job ].data() + oldSize, data.data(), data.size() );
00934 }
00935
00936 void GDataPrivate::slotRemovePost( KJob *job )
00937 {
00938 kDebug();
00939 if( !job ) {
00940 kError() << "job is a null pointer.";
00941 return;
00942 }
00943 const QString data = QString::fromUtf8( mRemovePostBuffer[ job ].data(),
00944 mRemovePostBuffer[ job ].size() );
00945 mRemovePostBuffer[ job ].resize( 0 );
00946
00947 KBlog::BlogPost *post = mRemovePostMap[ job ];
00948 mRemovePostMap.remove( job );
00949 Q_Q( GData );
00950 if ( job->error() != 0 ) {
00951 kError() << "slotRemovePost error:" << job->errorString();
00952 emit q->errorPost( GData::Atom, job->errorString(), post );
00953 return;
00954 }
00955
00956 post->setStatus( BlogPost::Removed );
00957 kDebug() << "Emitting removedPost()";
00958 emit q->removedPost( post );
00959 }
00960
00961 void GDataPrivate::slotCreateCommentData( KIO::Job *job, const QByteArray &data )
00962 {
00963 kDebug();
00964 if( !job ) {
00965 kError() << "job is a null pointer.";
00966 return;
00967 }
00968 unsigned int oldSize = mCreateCommentBuffer[ job ].size();
00969 mCreateCommentBuffer[ job ].resize( oldSize + data.size() );
00970 memcpy( mCreateCommentBuffer[ job ].data() + oldSize, data.data(), data.size() );
00971 }
00972
00973 void GDataPrivate::slotCreateComment( KJob *job )
00974 {
00975 kDebug();
00976 if( !job ) {
00977 kError() << "job is a null pointer.";
00978 return;
00979 }
00980 const QString data = QString::fromUtf8( mCreateCommentBuffer[ job ].data(),
00981 mCreateCommentBuffer[ job ].size() );
00982 mCreateCommentBuffer[ job ].resize( 0 );
00983 kDebug() << "Dump data: " << data;
00984
00985 Q_Q( GData );
00986
00987 KBlog::BlogComment *comment = mCreateCommentMap[ job ].values().first();
00988 KBlog::BlogPost *post = mCreateCommentMap[ job ].keys().first();
00989 mCreateCommentMap.remove( job );
00990
00991 if ( job->error() != 0 ) {
00992 kError() << "slotCreateComment error:" << job->errorString();
00993 emit q->errorComment( GData::Atom, job->errorString(), post, comment );
00994 return;
00995 }
00996
00997
00998 QRegExp rxId( "post-(\\d+)" );
00999 if ( rxId.indexIn( data ) == -1 ) {
01000 kError() << "Could not regexp the id out of the result:" << data;
01001 emit q->errorPost( GData::Atom,
01002 i18n( "Could not regexp the id out of the result." ), post );
01003 return;
01004 }
01005 kDebug() << "QRegExp rx( 'post-(\\d+)' ) matches" << rxId.cap(1);
01006
01007 QRegExp rxPub( "<published>(.+)</published>" );
01008 if ( rxPub.indexIn( data ) == -1 ) {
01009 kError() << "Could not regexp the published time out of the result:" << data;
01010 emit q->errorPost( GData::Atom,
01011 i18n( "Could not regexp the published time out of the result." ), post );
01012 return;
01013 }
01014 kDebug() << "QRegExp rx( '<published>(.+)</published>' ) matches" << rxPub.cap(1);
01015
01016 QRegExp rxUp( "<updated>(.+)</updated>" );
01017 if ( rxUp.indexIn( data ) == -1 ) {
01018 kError() << "Could not regexp the update time out of the result:" << data;
01019 emit q->errorPost( GData::Atom,
01020 i18n( "Could not regexp the update time out of the result." ), post );
01021 return;
01022 }
01023 kDebug() << "QRegExp rx( '<updated>(.+)</updated>' ) matches" << rxUp.cap(1);
01024 comment->setCommentId( rxId.cap(1) );
01025 comment->setCreationDateTime( KDateTime().fromString( rxPub.cap(1) ) );
01026 comment->setModificationDateTime( KDateTime().fromString( rxUp.cap(1) ) );
01027 comment->setStatus( BlogComment::Created );
01028 kDebug() << "Emitting createdComment()";
01029 emit q->createdComment( post, comment );
01030 }
01031
01032 void GDataPrivate::slotRemoveCommentData( KIO::Job *job, const QByteArray &data )
01033 {
01034 kDebug();
01035 if( !job ) {
01036 kError() << "job is a null pointer.";
01037 return;
01038 }
01039 unsigned int oldSize = mRemoveCommentBuffer[ job ].size();
01040 mRemoveCommentBuffer[ job ].resize( oldSize + data.size() );
01041 memcpy( mRemoveCommentBuffer[ job ].data() + oldSize, data.data(), data.size() );
01042 }
01043
01044 void GDataPrivate::slotRemoveComment( KJob *job )
01045 {
01046 kDebug();
01047 if( !job ) {
01048 kError() << "job is a null pointer.";
01049 return;
01050 }
01051 const QString data = QString::fromUtf8( mRemoveCommentBuffer[ job ].data(),
01052 mRemoveCommentBuffer[ job ].size() );
01053 mRemoveCommentBuffer[ job ].resize( 0 );
01054
01055 Q_Q( GData );
01056
01057 KBlog::BlogComment *comment = mRemoveCommentMap[ job ].values().first();
01058 KBlog::BlogPost *post = mRemoveCommentMap[ job ].keys().first();
01059 mRemoveCommentMap.remove( job );
01060
01061 if ( job->error() != 0 ) {
01062 kError() << "slotRemoveComment error:" << job->errorString();
01063 emit q->errorComment( GData::Atom, job->errorString(), post, comment );
01064 return;
01065 }
01066
01067 comment->setStatus( BlogComment::Created );
01068 kDebug() << "Emitting removedComment()";
01069 emit q->removedComment( post, comment );
01070 }
01071
01072 #include "gdata.moc"