25 #include "blogger1_p.h"
28 #include <kxmlrpcclient/client.h>
32 #include <KLocalizedString>
36 #include <QStringList>
38 using namespace KBlog;
41 :
Blog( server, *new Blogger1Private, parent )
48 :
Blog( server, dd, parent )
61 return QLatin1String(
"Blogger 1.0" );
68 delete d->mXmlRpcClient;
69 d->mXmlRpcClient =
new KXmlRpc::Client( server );
70 d->mXmlRpcClient->setUserAgent(
userAgent() );
76 kDebug() <<
"Fetch user's info...";
77 QList<QVariant> args( d->blogger1Args() );
78 d->mXmlRpcClient->call(
79 "blogger.getUserInfo", args,
80 this, SLOT(slotFetchUserInfo(QList<QVariant>,QVariant)),
81 this, SLOT(slotError(
int,QString,QVariant)) );
87 kDebug() <<
"Fetch List of Blogs...";
88 QList<QVariant> args( d->blogger1Args() );
89 d->mXmlRpcClient->call(
90 "blogger.getUsersBlogs", args,
91 this, SLOT(slotListBlogs(QList<QVariant>,QVariant)),
92 this, SLOT(slotError(
int,QString,QVariant)) );
98 kDebug() <<
"Fetching List of Posts...";
99 QList<QVariant> args( d->defaultArgs(
blogId() ) );
100 args << QVariant( number );
101 d->mXmlRpcClient->call(
102 d->getCallFromFunction( Blogger1Private::GetRecentPosts ), args,
103 this, SLOT(slotListRecentPosts(QList<QVariant>,QVariant)),
104 this, SLOT(slotError(
int,QString,QVariant)),
105 QVariant( number ) );
111 kError() <<
"Blogger1::modifyPost: post is null pointer";
116 kDebug() <<
"Fetching Post with url" << post->
postId();
117 QList<QVariant> args( d->defaultArgs( post->
postId() ) );
118 unsigned int i= d->mCallCounter++;
119 d->mCallMap[ i ] = post;
120 d->mXmlRpcClient->call(
121 d->getCallFromFunction( Blogger1Private::FetchPost ), args,
122 this, SLOT(slotFetchPost(QList<QVariant>,QVariant)),
123 this, SLOT(slotError(
int,QString,QVariant)),
132 kError() <<
"Blogger1::modifyPost: post is null pointer";
136 kDebug() <<
"Uploading Post with postId" << post->
postId();
137 unsigned int i= d->mCallCounter++;
138 d->mCallMap[ i ] = post;
139 QList<QVariant> args( d->defaultArgs( post->
postId() ) );
140 d->readArgsFromPost( &args, *post );
141 d->mXmlRpcClient->call(
142 d->getCallFromFunction( Blogger1Private::ModifyPost ), args,
143 this, SLOT(slotModifyPost(QList<QVariant>,QVariant)),
144 this, SLOT(slotError(
int,QString,QVariant)),
153 kError() <<
"Blogger1::createPost: post is null pointer";
157 unsigned int i= d->mCallCounter++;
158 d->mCallMap[ i ] = post;
159 kDebug() <<
"Creating new Post with blogid" <<
blogId();
160 QList<QVariant> args( d->defaultArgs(
blogId() ) );
161 d->readArgsFromPost( &args, *post );
162 d->mXmlRpcClient->call(
163 d->getCallFromFunction( Blogger1Private::CreatePost ), args,
164 this, SLOT(slotCreatePost(QList<QVariant>,QVariant)),
165 this, SLOT(slotError(
int,QString,QVariant)),
174 kError() <<
"Blogger1::removePost: post is null pointer";
178 unsigned int i = d->mCallCounter++;
179 d->mCallMap[ i ] = post;
180 kDebug() <<
"Blogger1::removePost: postId=" << post->
postId();
181 QList<QVariant> args( d->blogger1Args( post->
postId() ) );
182 args << QVariant(
true );
183 d->mXmlRpcClient->call(
184 "blogger.deletePost", args,
185 this, SLOT(slotRemovePost(QList<QVariant>,QVariant)),
186 this, SLOT(slotError(
int,QString,QVariant)),
190 Blogger1Private::Blogger1Private() :
197 Blogger1Private::~Blogger1Private()
200 delete mXmlRpcClient;
203 QList<QVariant> Blogger1Private::defaultArgs(
const QString &
id )
207 QList<QVariant> args;
208 args << QVariant( QString(
"0123456789ABCDEF" ) );
209 if ( !
id.isEmpty() ) {
210 args << QVariant(
id );
212 args << QVariant( q->username() )
213 << QVariant( q->password() );
218 QList<QVariant> Blogger1Private::blogger1Args(
const QString &
id )
222 QList<QVariant> args;
223 args << QVariant( QString(
"0123456789ABCDEF" ) );
224 if ( !
id.isEmpty() ) {
225 args << QVariant(
id );
227 args << QVariant( q->username() )
228 << QVariant( q->password() );
232 void Blogger1Private::slotFetchUserInfo(
const QList<QVariant> &result,
const QVariant &
id )
238 kDebug() <<
"TOP:" << result[0].typeName();
239 QMap<QString,QString> userInfo;
240 if ( result[0].type() != QVariant::Map ) {
241 kError() <<
"Could not fetch user's info out of the result from the server,"
244 i18n(
"Could not fetch user's info out of the result "
245 "from the server, not a map." ) );
248 const QMap<QString,QVariant> resultMap = result[0].toMap();
249 userInfo[
"nickname"]=resultMap[
"nickname"].toString();
250 userInfo[
"userid"]=resultMap[
"userid"].toString();
251 userInfo[
"url"]=resultMap[
"url"].toString();
252 userInfo[
"email"]=resultMap[
"email"].toString();
253 userInfo[
"lastname"]=resultMap[
"lastname"].toString();
254 userInfo[
"firstname"]=resultMap[
"firstname"].toString();
256 emit q->fetchedUserInfo( userInfo );
259 void Blogger1Private::slotListBlogs(
const QList<QVariant> &result,
const QVariant &
id )
265 kDebug() <<
"TOP:" << result[0].typeName();
266 QList<QMap<QString,QString> > blogsList;
267 if ( result[0].type() != QVariant::List ) {
268 kError() <<
"Could not fetch blogs out of the result from the server,"
271 i18n(
"Could not fetch blogs out of the result "
272 "from the server, not a list." ) );
275 const QList<QVariant> posts = result[0].toList();
276 QList<QVariant>::ConstIterator it = posts.begin();
277 QList<QVariant>::ConstIterator end = posts.end();
278 for ( ; it != end; ++it ) {
279 kDebug() <<
"MIDDLE:" << ( *it ).typeName();
280 const QMap<QString, QVariant> postInfo = ( *it ).toMap();
281 QMap<QString,QString> blogInfo;
282 blogInfo[
"id" ] = postInfo[
"blogid"].toString();
283 blogInfo[
"url" ] = postInfo[
"url"].toString();
284 blogInfo[
"apiUrl" ] = postInfo[
"xmlrpc"].toString();
285 blogInfo[
"title" ] = postInfo[
"blogName"].toString();
286 kDebug() <<
"Blog information retrieved: ID =" << blogInfo[
"id"]
287 <<
", Name =" << blogInfo[
"title"];
288 blogsList << blogInfo;
290 emit q->listedBlogs( blogsList );
293 void Blogger1Private::slotListRecentPosts(
const QList<QVariant> &result,
const QVariant &
id )
296 int count =
id.toInt();
300 kDebug() <<
"TOP:" << result[0].typeName();
302 QList <BlogPost> fetchedPostList;
304 if ( result[0].type() != QVariant::List ) {
305 kError() <<
"Could not fetch list of posts out of the"
306 <<
"result from the server, not a list.";
308 i18n(
"Could not fetch list of posts out of the result "
309 "from the server, not a list." ) );
312 const QList<QVariant> postReceived = result[0].toList();
313 QList<QVariant>::ConstIterator it = postReceived.begin();
314 QList<QVariant>::ConstIterator end = postReceived.end();
315 for ( ; it != end; ++it ) {
317 kDebug() <<
"MIDDLE:" << ( *it ).typeName();
318 const QMap<QString, QVariant> postInfo = ( *it ).toMap();
319 if ( readPostFromMap( &post, postInfo ) ) {
320 kDebug() <<
"Post with ID:"
322 <<
"appended in fetchedPostList";
324 fetchedPostList.append( post );
326 kError() <<
"readPostFromMap failed!";
329 if ( --count == 0 ) {
333 kDebug() <<
"Emitting listRecentPostsFinished()";
334 emit q->listedRecentPosts( fetchedPostList );
337 void Blogger1Private::slotFetchPost(
const QList<QVariant> &result,
const QVariant &
id )
343 mCallMap.remove(
id.toInt() );
348 kDebug () <<
"TOP:" << result[0].typeName();
349 if ( result[0].type() == QVariant::Map &&
350 readPostFromMap( post, result[0].toMap() ) ) {
351 kDebug() <<
"Emitting fetchedPost()";
353 emit q->fetchedPost( post );
355 kError() <<
"Could not fetch post out of the result from the server.";
356 post->
setError( i18n(
"Could not fetch post out of the result from the server." ) );
359 i18n(
"Could not fetch post out of the result from the server." ), post );
363 void Blogger1Private::slotCreatePost(
const QList<QVariant> &result,
const QVariant &
id )
367 mCallMap.remove(
id.toInt() );
373 kDebug () <<
"TOP:" << result[0].typeName();
374 if ( result[0].type() != QVariant::String &&
375 result[0].type() != QVariant::Int ) {
376 kError() <<
"Could not read the postId, not a string or an integer.";
378 i18n(
"Could not read the postId, not a string or an integer." ),
383 if ( result[0].type() == QVariant::String ) {
384 serverID = result[0].toString();
385 }
else if ( result[0].type() == QVariant::Int ) {
386 serverID = QString::fromLatin1(
"%1" ).arg( result[0].toInt() );
390 kDebug() <<
"emitting createdPost()"
391 <<
"for title: \"" << post->
title()
392 <<
"\" server id: " << serverID;
393 emit q->createdPost( post );
396 void Blogger1Private::slotModifyPost(
const QList<QVariant> &result,
const QVariant &
id )
400 mCallMap.remove(
id.toInt() );
406 kDebug() <<
"TOP:" << result[0].typeName();
407 if ( result[0].type() != QVariant::Bool &&
408 result[0].type() != QVariant::Int ) {
409 kError() <<
"Could not read the result, not a boolean.";
411 i18n(
"Could not read the result, not a boolean." ),
416 kDebug() <<
"emitting modifiedPost() for title: \""
417 << post->
title() <<
"\"";
418 emit q->modifiedPost( post );
421 void Blogger1Private::slotRemovePost(
const QList<QVariant> &result,
const QVariant &
id )
425 mCallMap.remove(
id.toInt() );
427 kDebug() <<
"slotRemovePost";
431 kDebug() <<
"TOP:" << result[0].typeName();
432 if ( result[0].type() != QVariant::Bool &&
433 result[0].type() != QVariant::Int ) {
434 kError() <<
"Could not read the result, not a boolean.";
436 i18n(
"Could not read the result, not a boolean." ),
441 kDebug() <<
"emitting removedPost()";
442 emit q->removedPost( post );
445 void Blogger1Private::slotError(
int number,
446 const QString &errorString,
451 kDebug() <<
"An error occurred: " << errorString;
452 BlogPost *post = mCallMap[
id.toInt() ];
460 bool Blogger1Private::readPostFromMap(
461 BlogPost *post,
const QMap<QString, QVariant> &postInfo )
467 QStringList mapkeys = postInfo.keys();
468 kDebug() << endl <<
"Keys:" << mapkeys.join(
", " );
471 KDateTime dt( postInfo[
"dateCreated"].toDateTime(), KDateTime::UTC );
472 if ( dt.isValid() && !dt.isNull() ) {
475 dt = KDateTime ( postInfo[
"lastModified"].toDateTime(), KDateTime::UTC );
476 if ( dt.isValid() && !dt.isNull() ) {
479 post->
setPostId( postInfo[
"postid"].toString().isEmpty() ? postInfo[
"postId"].toString() :
480 postInfo[
"postid"].toString() );
482 QString title( postInfo[
"title"].toString() );
483 QString description( postInfo[
"description"].toString() );
485 if ( postInfo[
"content"].type() == QVariant::ByteArray ) {
486 QByteArray tmpContent = postInfo[
"content"].toByteArray();
487 contents = QString::fromUtf8( tmpContent.data(), tmpContent.size() );
489 contents = postInfo[
"content"].toString();
491 QStringList category;
494 QRegExp titleMatch = QRegExp(
"<title>([^<]*)</title>" );
495 QRegExp categoryMatch = QRegExp(
"<category>([^<]*)</category>" );
496 if ( contents.indexOf( titleMatch ) != -1 ) {
498 title = titleMatch.cap( 1 );
500 if ( contents.indexOf( categoryMatch ) != -1 ) {
502 category = categoryMatch.capturedTexts();
504 contents.remove( titleMatch );
505 contents.remove( categoryMatch );
513 bool Blogger1Private::readArgsFromPost( QList<QVariant> *args,
const BlogPost &post )
519 QString content =
"<title>" + post.
title() +
"</title>";
520 QStringList::const_iterator it;
521 for ( it = categories.constBegin(); it != categories.constEnd(); ++it ) {
522 content +=
"<category>" + *it +
"</category>";
525 *args << QVariant( content );
530 QString Blogger1Private::getCallFromFunction( FunctionToCall type )
533 case GetRecentPosts:
return "blogger.getRecentPosts";
534 case CreatePost:
return "blogger.newPost";
535 case ModifyPost:
return "blogger.editPost";
536 case FetchPost:
return "blogger.getPost";
537 default:
return QString();
541 #include "moc_blogger1.cpp"