KBlog Client Library
gdata.cpp
00001 /* 00002 This file is part of the kblog library. 00003 00004 Copyright (c) 2007 Christian Weilbach <christian_weilbach@web.de> 00005 00006 This library is free software; you can redistribute it and/or 00007 modify it under the terms of the GNU Library General Public 00008 License as published by the Free Software Foundation; either 00009 version 2 of the License, or (at your option) any later version. 00010 00011 This library is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 Library General Public License for more details. 00015 00016 You should have received a copy of the GNU Library General Public License 00017 along with this library; see the file COPYING.LIB. If not, write to 00018 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00019 Boston, MA 02110-1301, USA. 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( QString::fromLatin1("http://www.blogger.com/feeds/%1/blogs").arg(profileId()) ); 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( QString("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( QString::fromLatin1("http://www.blogger.com/feeds/%1/comments/default").arg(blogId()) ); 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( QString::fromLatin1("http://www.blogger.com/feeds/%1/posts/default").arg(blogId())); 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(); // FIXME check for Utf 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(); //TODO fix/add more 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 // FIXME: assuming UTC for now 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 // FIXME: assuming UTC for now 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 // FIXME: assuming UTC for now 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+)" ); //FIXME check and do better handling, esp the creation date time 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+)" ); //FIXME check and do better handling, esp creation date time 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 // TODO check for result and fit appropriately 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"
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Mon May 7 2012 23:53:43 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
Documentation copyright © 1996-2012 The KDE developers.
Generated on Mon May 7 2012 23:53:43 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
KDE's Doxygen guidelines are available online.