25 #include "movabletype_p.h"
28 #include <kxmlrpcclient/client.h>
35 #include <QtCore/QStringList>
37 using namespace KBlog;
40 :
MetaWeblog( server, *new MovableTypePrivate, parent )
59 return QLatin1String(
"Movable Type" );
66 QList<QVariant> args( d->defaultArgs(
blogId() ) );
67 args << QVariant( number );
68 d->mXmlRpcClient->call(
69 "metaWeblog.getRecentPosts", args,
70 this, SLOT(slotListRecentPosts(QList<QVariant>,QVariant)),
71 this, SLOT(slotError(
int,QString,QVariant)),
80 args << QVariant( post->
postId() );
81 unsigned int i = d->mCallCounter++;
82 d->mCallMap[ i ] = post;
83 d->mXmlRpcClient->call(
84 "mt.getTrackbackPings", args,
85 this, SLOT(slotListTrackbackPings(QList<QVariant>,QVariant)),
86 this, SLOT(slotError(
int,QString,QVariant)),
95 if ( d->mCategoriesList.isEmpty() &&
97 d->mFetchPostCache << post;
98 if ( d->mFetchPostCache.count() ) {
105 this, SLOT(slotTriggerFetchPost()) );
122 if ( d->mCategoriesList.isEmpty() &&
124 kDebug() <<
"No categories in the cache yet. Have to fetch them first.";
125 d->mCreatePostCache << post;
127 this, SLOT(slotTriggerCreatePost()) );
135 if ( d->mSilentCreationList.contains( post ) ) {
136 kDebug() <<
"Post already in mSilentCreationList, this *should* never happen!";
138 d->mSilentCreationList << post;
158 if ( d->mCategoriesList.isEmpty() &&
160 kDebug() <<
"No categories in the cache yet. Have to fetch them first.";
161 d->mModifyPostCache << post;
163 this, SLOT(slotTriggerModifyPost()) );
171 void MovableTypePrivate::slotTriggerCreatePost()
176 q->disconnect( q, SIGNAL(listedCategories(QList<QMap<QString,QString> >)),
177 q, SLOT(slotTriggerCreatePost()) );
179 QList<BlogPost*>::Iterator it = mCreatePostCache.begin();
180 QList<BlogPost*>::Iterator end = mCreatePostCache.end();
181 for ( ; it != end; it++ ) {
182 q->createPost( *it );
184 mCreatePostCache.clear();
187 void MovableTypePrivate::slotTriggerModifyPost()
192 q->disconnect( q, SIGNAL(listedCategories(QList<QMap<QString,QString> >)),
193 q, SLOT(slotTriggerModifyPost()) );
195 QList<BlogPost*>::Iterator it = mModifyPostCache.begin();
196 QList<BlogPost*>::Iterator end = mModifyPostCache.end();
197 for ( ; it != end; it++ ) {
198 q->modifyPost( *it );
200 mModifyPostCache.clear();
203 void MovableTypePrivate::slotTriggerFetchPost()
208 q->disconnect( q, SIGNAL(listedCategories(QList<QMap<QString,QString> >)),
209 q, SLOT(slotTriggerFetchPost()) );
210 QList<BlogPost*>::Iterator it = mFetchPostCache.begin();
211 QList<BlogPost*>::Iterator end = mFetchPostCache.end();
212 for ( ; it != end; it++ ) {
215 mFetchPostCache.clear();
219 MovableTypePrivate::MovableTypePrivate()
224 MovableTypePrivate::~MovableTypePrivate()
229 void MovableTypePrivate::slotCreatePost(
const QList<QVariant> &result,
const QVariant &
id )
235 mCallMap.remove(
id.toInt() );
240 kDebug () <<
"TOP:" << result[0].typeName();
241 if ( result[0].type() != QVariant::String &&
242 result[0].type() != QVariant::Int ) {
243 kError() <<
"Could not read the postId, not a string or an integer.";
245 i18n(
"Could not read the postId, not a string or an integer." ),
250 if ( result[0].type() == QVariant::String ) {
251 serverID = result[0].toString();
253 if ( result[0].type() == QVariant::Int ) {
254 serverID = QString(
"%1" ).arg( result[0].toInt() );
257 if ( mSilentCreationList.contains( post ) )
260 setPostCategories( post, !post->
isPrivate() );
262 kDebug() <<
"emitting createdPost()"
263 <<
"for title: \"" << post->
title()
264 <<
"\" server id: " << serverID;
266 emit q->createdPost( post );
270 void MovableTypePrivate::slotFetchPost(
const QList<QVariant> &result,
const QVariant &
id )
276 mCallMap.remove(
id.toInt() );
280 kDebug () <<
"TOP:" << result[0].typeName();
281 if ( result[0].type() == QVariant::Map &&
282 readPostFromMap( post, result[0].toMap() ) ) {
284 kError() <<
"Could not fetch post out of the result from the server.";
285 post->
setError( i18n(
"Could not fetch post out of the result from the server." ) );
288 i18n(
"Could not fetch post out of the result from the server." ), post );
291 QList<QVariant> args( defaultArgs( post->
postId() ) );
292 unsigned int i= mCallCounter++;
293 mCallMap[ i ] = post;
295 "mt.getPostCategories", args,
296 q, SLOT(slotGetPostCategories(QList<QVariant>,QVariant)),
297 q, SLOT(slotError(
int,QString,QVariant)),
300 kDebug() <<
"Emitting fetchedPost()";
302 emit q->fetchedPost( post );
306 void MovableTypePrivate::slotModifyPost(
const QList<QVariant> &result,
const QVariant &
id )
312 mCallMap.remove(
id.toInt() );
316 kDebug() <<
"TOP:" << result[0].typeName();
317 if ( result[0].type() != QVariant::Bool &&
318 result[0].type() != QVariant::Int ) {
319 kError() <<
"Could not read the result, not a boolean.";
321 i18n(
"Could not read the result, not a boolean." ),
325 if ( mSilentCreationList.contains( post ) ) {
327 mSilentCreationList.removeOne( post );
328 emit q->createdPost( post );
331 setPostCategories( post,
false );
336 void MovableTypePrivate::setPostCategories(
BlogPost *post,
bool publishAfterCategories )
341 unsigned int i = mCallCounter++;
342 mCallMap[ i ] = post;
343 mPublishAfterCategories[ i ] = publishAfterCategories;
344 QList<QVariant> catList;
345 QList<QVariant> args( defaultArgs( post->
postId() ) );
349 for (
int j = 0; j < categories.count(); j++ ) {
350 for (
int k = 0; k < mCategoriesList.count(); k++ ) {
351 if ( mCategoriesList[k][
"name"] == categories[j] ) {
352 kDebug() <<
"Matched category with name: " << categories[ j ] <<
" and id: " << mCategoriesList[ k ][
"categoryId" ];
353 QMap<QString,QVariant> category;
356 category[
"categoryId"] = mCategoriesList[k][
"categoryId"].toInt();
357 catList << QVariant( category );
360 if ( k == mCategoriesList.count() ) {
361 kDebug() <<
"Couldn't find categoryId for: " << categories[j];
365 args << QVariant( catList );
368 "mt.setPostCategories", args,
369 q, SLOT(slotSetPostCategories(QList<QVariant>,QVariant)),
370 q, SLOT(slotError(
int,QString,QVariant)),
374 void MovableTypePrivate::slotGetPostCategories(
const QList<QVariant>& result,
const QVariant&
id)
381 mCallMap.remove( i );
383 if ( result[ 0 ].type() != QVariant::List ) {
384 kError() <<
"Could not read the result, not a list. Category fetching failed! We will still emit fetched post now.";
386 i18n(
"Could not read the result - is not a list. Category fetching failed." ), post );
389 emit q->fetchedPost( post );
391 QList<QVariant> categoryList = result[ 0 ].toList();
392 QList<QString> newCatList;
393 QList<QVariant>::ConstIterator it = categoryList.constBegin();
394 QList<QVariant>::ConstIterator end = categoryList.constEnd();
395 for ( ; it != end; it++ ) {
396 newCatList << ( *it ).toMap()[
"categoryName" ].toString();
398 kDebug() <<
"categories list: " << newCatList;
401 emit q->fetchedPost( post );
405 void MovableTypePrivate::slotSetPostCategories(
const QList<QVariant>& result,
const QVariant&
id)
412 bool publish = mPublishAfterCategories[ i ];
413 mCallMap.remove( i );
414 mPublishAfterCategories.remove( i );
416 if ( result[0].type() != QVariant::Bool ) {
417 kError() <<
"Could not read the result, not a boolean. Category setting failed! We will still publish if now if necessary. ";
419 i18n(
"Could not read the result - is not a boolean value. Category setting failed. Will still publish now if necessary." ),
426 q->modifyPost( post );
431 if ( mSilentCreationList.contains( post ) ) {
432 kDebug() <<
"emitting createdPost() for title: \""
433 << post->
title() <<
"\"";
435 mSilentCreationList.removeOne( post );
436 emit q->createdPost( post );
438 kDebug() <<
"emitting modifiedPost() for title: \""
439 << post->
title() <<
"\"";
441 emit q->modifiedPost( post );
446 QList<QVariant> MovableTypePrivate::defaultArgs(
const QString &
id )
449 QList<QVariant> args;
450 if ( !
id.isEmpty() ) {
451 args << QVariant(
id );
453 args << QVariant( q->username() )
454 << QVariant( q->password() );
458 bool MovableTypePrivate::readPostFromMap(
BlogPost *post,
const QMap<QString, QVariant> &postInfo )
462 kDebug() <<
"readPostFromMap()";
466 QStringList mapkeys = postInfo.keys();
467 kDebug() << endl <<
"Keys:" << mapkeys.join(
", " );
471 KDateTime( postInfo[
"dateCreated"].toDateTime(), KDateTime::UTC );
472 if ( dt.isValid() && !dt.isNull() ) {
477 KDateTime( postInfo[
"lastModified"].toDateTime(), KDateTime::UTC );
478 if ( dt.isValid() && !dt.isNull() ) {
482 post->
setPostId( postInfo[
"postid"].toString().isEmpty() ? postInfo[
"postId"].toString() :
483 postInfo[
"postid"].toString() );
485 QString title( postInfo[
"title"].toString() );
486 QString description( postInfo[
"description"].toString() );
487 QStringList categoryIdList = postInfo[
"categories"].toStringList();
488 QStringList categories;
491 for (
int i = 0; i < categoryIdList.count(); i++ ) {
492 for (
int k = 0; k < mCategoriesList.count(); k++ ) {
493 if ( mCategoriesList[ k ][
"name" ] == categoryIdList[ i ] ) {
494 categories << mCategoriesList[ k ][
"name" ];
495 }
else if ( mCategoriesList[ k ][
"categoryId" ] == categoryIdList[ i ]) {
496 categories << mCategoriesList[ k ][
"name" ];
503 post->
setSlug( postInfo[
"wp_slug"].toString() );
509 post->
setSummary( postInfo[
"mt_excerpt"].toString() );
510 post->
setTags( postInfo[
"mt_keywords"].toStringList() );
511 post->
setLink( postInfo[
"link"].toString() );
513 QString postStatus = postInfo[
"post_status"].toString();
514 if ( postStatus !=
"publish" &&
515 !postStatus.isEmpty() ) {
523 if ( !categories.isEmpty() ) {
524 kDebug() <<
"Categories:" << categories;
530 void MovableTypePrivate::slotListTrackBackPings(
531 const QList<QVariant> &result,
const QVariant &
id )
534 kDebug() <<
"slotTrackbackPings()";
535 BlogPost *post = mCallMap[
id.toInt() ];
536 mCallMap.remove(
id.toInt() );
537 QList<QMap<QString,QString> > trackBackList;
538 if ( result[0].type() != QVariant::List ) {
539 kError() <<
"Could not fetch list of trackback pings out of the"
540 <<
"result from the server.";
542 i18n(
"Could not fetch list of trackback pings out of the "
543 "result from the server." ) );
546 const QList<QVariant> trackBackReceived = result[0].toList();
547 QList<QVariant>::ConstIterator it = trackBackReceived.begin();
548 QList<QVariant>::ConstIterator end = trackBackReceived.end();
549 for ( ; it != end; ++it ) {
550 QMap<QString,QString> tping;
551 kDebug() <<
"MIDDLE:" << ( *it ).typeName();
552 const QMap<QString, QVariant> trackBackInfo = ( *it ).toMap();
553 tping[
"title" ] = trackBackInfo[
"pingTitle"].toString();
554 tping[
"url" ] = trackBackInfo[
"pingURL"].toString();
555 tping[
"ip" ] = trackBackInfo[
"pingIP"].toString();
556 trackBackList << tping;
558 kDebug() <<
"Emitting listedTrackBackPings()";
559 emit q->listedTrackBackPings( post, trackBackList );
562 bool MovableTypePrivate::readArgsFromPost( QList<QVariant> *args,
const BlogPost &post )
570 QMap<QString, QVariant> map;
572 map[
"description"] = post.
content();
576 map[
"title"] = post.
title();
580 map[
"mt_excerpt"] = post.
summary();
581 map[
"mt_keywords"] = post.
tags().join(
"," );
588 #include "moc_movabletype.cpp"