25 #include "movabletype_p.h"
28 #include <kxmlrpcclient/client.h>
32 #include <KLocalizedString>
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 QLatin1String(
"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 QLatin1String(
"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();
218 MovableTypePrivate::MovableTypePrivate()
223 MovableTypePrivate::~MovableTypePrivate()
228 void MovableTypePrivate::slotCreatePost(
const QList<QVariant> &result,
const QVariant &
id )
234 mCallMap.remove(
id.toInt() );
239 kDebug () <<
"TOP:" << result[0].typeName();
240 if ( result[0].type() != QVariant::String &&
241 result[0].type() != QVariant::Int ) {
242 kError() <<
"Could not read the postId, not a string or an integer.";
244 i18n(
"Could not read the postId, not a string or an integer." ),
249 if ( result[0].type() == QVariant::String ) {
250 serverID = result[0].toString();
252 if ( result[0].type() == QVariant::Int ) {
253 serverID = QString::fromLatin1(
"%1" ).arg( result[0].toInt() );
256 if ( mSilentCreationList.contains( post ) )
259 setPostCategories( post, !post->
isPrivate() );
261 kDebug() <<
"emitting createdPost()"
262 <<
"for title: \"" << post->
title()
263 <<
"\" server id: " << serverID;
265 emit q->createdPost( post );
269 void MovableTypePrivate::slotFetchPost(
const QList<QVariant> &result,
const QVariant &
id )
275 mCallMap.remove(
id.toInt() );
279 kDebug () <<
"TOP:" << result[0].typeName();
280 if ( result[0].type() == QVariant::Map &&
281 readPostFromMap( post, result[0].toMap() ) ) {
283 kError() <<
"Could not fetch post out of the result from the server.";
284 post->
setError( i18n(
"Could not fetch post out of the result from the server." ) );
287 i18n(
"Could not fetch post out of the result from the server." ), post );
290 QList<QVariant> args( defaultArgs( post->
postId() ) );
291 unsigned int i= mCallCounter++;
292 mCallMap[ i ] = post;
294 QLatin1String(
"mt.getPostCategories"), args,
295 q, SLOT(slotGetPostCategories(QList<QVariant>,QVariant)),
296 q, SLOT(slotError(
int,QString,QVariant)),
299 kDebug() <<
"Emitting fetchedPost()";
301 emit q->fetchedPost( post );
305 void MovableTypePrivate::slotModifyPost(
const QList<QVariant> &result,
const QVariant &
id )
311 mCallMap.remove(
id.toInt() );
315 kDebug() <<
"TOP:" << result[0].typeName();
316 if ( result[0].type() != QVariant::Bool &&
317 result[0].type() != QVariant::Int ) {
318 kError() <<
"Could not read the result, not a boolean.";
320 i18n(
"Could not read the result, not a boolean." ),
324 if ( mSilentCreationList.contains( post ) ) {
326 mSilentCreationList.removeOne( post );
327 emit q->createdPost( post );
330 setPostCategories( post,
false );
335 void MovableTypePrivate::setPostCategories(
BlogPost *post,
bool publishAfterCategories )
340 unsigned int i = mCallCounter++;
341 mCallMap[ i ] = post;
342 mPublishAfterCategories[ i ] = publishAfterCategories;
343 QList<QVariant> catList;
344 QList<QVariant> args( defaultArgs( post->
postId() ) );
348 for (
int j = 0; j < categories.count(); j++ ) {
349 for (
int k = 0; k < mCategoriesList.count(); k++ ) {
350 if ( mCategoriesList[k][QLatin1String(
"name")] == categories[j] ) {
351 kDebug() <<
"Matched category with name: " << categories[ j ] <<
" and id: " << mCategoriesList[ k ][ QLatin1String(
"categoryId") ];
352 QMap<QString,QVariant> category;
355 category[QLatin1String(
"categoryId")] = mCategoriesList[k][QLatin1String(
"categoryId")].toInt();
356 catList << QVariant( category );
359 if ( k == mCategoriesList.count() ) {
360 kDebug() <<
"Couldn't find categoryId for: " << categories[j];
364 args << QVariant( catList );
367 QLatin1String(
"mt.setPostCategories"), args,
368 q, SLOT(slotSetPostCategories(QList<QVariant>,QVariant)),
369 q, SLOT(slotError(
int,QString,QVariant)),
373 void MovableTypePrivate::slotGetPostCategories(
const QList<QVariant>& result,
const QVariant&
id)
380 mCallMap.remove( i );
382 if ( result[ 0 ].type() != QVariant::List ) {
383 kError() <<
"Could not read the result, not a list. Category fetching failed! We will still emit fetched post now.";
385 i18n(
"Could not read the result - is not a list. Category fetching failed." ), post );
388 emit q->fetchedPost( post );
390 QList<QVariant> categoryList = result[ 0 ].toList();
391 QList<QString> newCatList;
392 QList<QVariant>::ConstIterator it = categoryList.constBegin();
393 QList<QVariant>::ConstIterator end = categoryList.constEnd();
394 for ( ; it != end; it++ ) {
395 newCatList << ( *it ).toMap()[ QLatin1String(
"categoryName") ].toString();
397 kDebug() <<
"categories list: " << newCatList;
400 emit q->fetchedPost( post );
404 void MovableTypePrivate::slotSetPostCategories(
const QList<QVariant>& result,
const QVariant&
id)
411 bool publish = mPublishAfterCategories[ i ];
412 mCallMap.remove( i );
413 mPublishAfterCategories.remove( i );
415 if ( result[0].type() != QVariant::Bool ) {
416 kError() <<
"Could not read the result, not a boolean. Category setting failed! We will still publish if now if necessary. ";
418 i18n(
"Could not read the result - is not a boolean value. Category setting failed. Will still publish now if necessary." ),
425 q->modifyPost( post );
430 if ( mSilentCreationList.contains( post ) ) {
431 kDebug() <<
"emitting createdPost() for title: \""
432 << post->
title() <<
"\"";
434 mSilentCreationList.removeOne( post );
435 emit q->createdPost( post );
437 kDebug() <<
"emitting modifiedPost() for title: \""
438 << post->
title() <<
"\"";
440 emit q->modifiedPost( post );
445 QList<QVariant> MovableTypePrivate::defaultArgs(
const QString &
id )
448 QList<QVariant> args;
449 if ( !
id.isEmpty() ) {
450 args << QVariant(
id );
452 args << QVariant( q->username() )
453 << QVariant( q->password() );
457 bool MovableTypePrivate::readPostFromMap(
BlogPost *post,
const QMap<QString, QVariant> &postInfo )
461 kDebug() <<
"readPostFromMap()";
465 QStringList mapkeys = postInfo.keys();
466 kDebug() << endl <<
"Keys:" << mapkeys.join( QLatin1String(
", ") );
470 KDateTime( postInfo[QLatin1String(
"dateCreated")].toDateTime(), KDateTime::UTC );
471 if ( dt.isValid() && !dt.isNull() ) {
476 KDateTime( postInfo[QLatin1String(
"lastModified")].toDateTime(), KDateTime::UTC );
477 if ( dt.isValid() && !dt.isNull() ) {
481 post->
setPostId( postInfo[QLatin1String(
"postid")].toString().isEmpty() ? postInfo[QLatin1String(
"postId")].toString() :
482 postInfo[QLatin1String(
"postid")].toString() );
484 QString title( postInfo[QLatin1String(
"title")].toString() );
485 QString description( postInfo[QLatin1String(
"description")].toString() );
486 QStringList categoryIdList = postInfo[QLatin1String(
"categories")].toStringList();
487 QStringList categories;
490 for (
int i = 0; i < categoryIdList.count(); i++ ) {
491 for (
int k = 0; k < mCategoriesList.count(); k++ ) {
492 if ( mCategoriesList[ k ][ QLatin1String(
"name") ] == categoryIdList[ i ] ) {
493 categories << mCategoriesList[ k ][ QLatin1String(
"name") ];
494 }
else if ( mCategoriesList[ k ][ QLatin1String(
"categoryId") ] == categoryIdList[ i ]) {
495 categories << mCategoriesList[ k ][ QLatin1String(
"name") ];
502 post->
setSlug( postInfo[QLatin1String(
"wp_slug")].toString() );
506 post->
setCommentAllowed( (
bool)postInfo[QLatin1String(
"mt_allow_comments")].toInt() );
508 post->
setSummary( postInfo[QLatin1String(
"mt_excerpt")].toString() );
509 post->
setTags( postInfo[QLatin1String(
"mt_keywords")].toStringList() );
510 post->
setLink( postInfo[QLatin1String(
"link")].toString() );
511 post->
setPermaLink( postInfo[QLatin1String(
"permaLink")].toString() );
512 QString postStatus = postInfo[QLatin1String(
"post_status")].toString();
513 if ( postStatus != QLatin1String(
"publish") &&
514 !postStatus.isEmpty() ) {
522 if ( !categories.isEmpty() ) {
523 kDebug() <<
"Categories:" << categories;
529 void MovableTypePrivate::slotListTrackBackPings(
530 const QList<QVariant> &result,
const QVariant &
id )
533 kDebug() <<
"slotTrackbackPings()";
534 BlogPost *post = mCallMap[
id.toInt() ];
535 mCallMap.remove(
id.toInt() );
536 QList<QMap<QString,QString> > trackBackList;
537 if ( result[0].type() != QVariant::List ) {
538 kError() <<
"Could not fetch list of trackback pings out of the"
539 <<
"result from the server.";
541 i18n(
"Could not fetch list of trackback pings out of the "
542 "result from the server." ) );
545 const QList<QVariant> trackBackReceived = result[0].toList();
546 QList<QVariant>::ConstIterator it = trackBackReceived.begin();
547 QList<QVariant>::ConstIterator end = trackBackReceived.end();
548 for ( ; it != end; ++it ) {
549 QMap<QString,QString> tping;
550 kDebug() <<
"MIDDLE:" << ( *it ).typeName();
551 const QMap<QString, QVariant> trackBackInfo = ( *it ).toMap();
552 tping[ QLatin1String(
"title") ] = trackBackInfo[ QLatin1String(
"pingTitle")].toString();
553 tping[ QLatin1String(
"url") ] = trackBackInfo[ QLatin1String(
"pingURL")].toString();
554 tping[ QLatin1String(
"ip") ] = trackBackInfo[ QLatin1String(
"pingIP")].toString();
555 trackBackList << tping;
557 kDebug() <<
"Emitting listedTrackBackPings()";
558 emit q->listedTrackBackPings( post, trackBackList );
561 bool MovableTypePrivate::readArgsFromPost( QList<QVariant> *args,
const BlogPost &post )
569 QMap<QString, QVariant> map;
570 map[QLatin1String(
"categories")] = post.
categories();
571 map[QLatin1String(
"description")] = post.
content();
575 map[QLatin1String(
"title")] = post.
title();
576 map[QLatin1String(
"dateCreated")] = post.
creationDateTime().dateTime().toUTC();
579 map[QLatin1String(
"mt_excerpt")] = post.
summary();
580 map[QLatin1String(
"mt_keywords")] = post.
tags().join( QLatin1String(
",") );
587 #include "moc_movabletype.cpp"