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 "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"
QString title() const
Returns the title.
KDateTime creationDateTime() const
Returns the creation date time.
virtual void listCategories()
List the categories of the blog.
void modifyPost(KBlog::BlogPost *post)
Modify a post on server.
Status of a successfully fetched post.
void setLink(const KUrl &link) const
Set the link path.
QStringList tags() const
Returns the tags list as a QStringList.
virtual void listTrackBackPings(KBlog::BlogPost *post)
Get the list of trackback pings from the server.
Status of a successfully created post.
virtual ~MovableType()
Destroy the object.
bool isCommentAllowed() const
Returns whether comments should be allowed.
bool isTrackBackAllowed() const
Returns whether track back should be allowed.
A class that can be used for access to MetaWeblog blogs.
QString summary() const
Returns the summary.
void createPost(KBlog::BlogPost *post)
Create a new post on server.
void setTitle(const QString &title)
Sets the title.
void setPostId(const QString &postId)
Sets the post id value.
void setCreationDateTime(const KDateTime &datetime)
Sets the creation time.
QString additionalContent() const
Returns the additional content, (mt_text_more of MovableType API)
void setAdditionalContent(const QString &additionalContent)
Sets the additional content, (mt_text_more of MovableType API)
This file is part of the for accessing Blog Servers and defines the MovableType class.
void setContent(const QString &content)
Sets the content.
QString error() const
Returns the last error.
Status when an error on the server side occurred.
void setModificationDateTime(const KDateTime &datetime)
Sets the modification time.
QString blogId() const
Returns the unique ID for the specific blog on the server.
void setStatus(Status status)
Sets the status.
Status of a successfully modified post.
void setTrackBackAllowed(bool allowTrackBacks)
Set whether track back should be allowed.
void setSlug(const QString &slug)
Sets the Wordpress slug property! (will use to set post's permalink) Currently just wordpress support...
QString interfaceName() const
Returns the of the inherited object.
A class that can be used for access to Movable Type blogs.
void setCommentAllowed(bool commentAllowed)
Set whether comments should be allowed.
void setPrivate(bool privatePost)
Sets the post to private viewings only.
QString content() const
Returns the content.
void fetchPost(KBlog::BlogPost *post)
Fetch a post from the server.
void setPermaLink(const KUrl &permalink) const
Set the perma link path.
A class that represents a blog post on the server.
void setCategories(const QStringList &categories)
Sets the categories.
void createPost(KBlog::BlogPost *post)
Create a new post on server.
void setSummary(const QString &summary)
Set the summary.
QStringList categories() const
Returns the categories.
void setTags(const QStringList &tags)
Set the tags list.
void listRecentPosts(int number)
List recent posts on the server.
void fetchPost(KBlog::BlogPost *post)
Fetch a post from the server.
void modifyPost(KBlog::BlogPost *post)
Modify a post on server.
bool isPrivate() const
Returns if the post is published or not.
void listedCategories(const QList< QMap< QString, QString > > &categories)
This signal is emitted when the last category of the listCategories() job has been fetched...
MovableType(const KUrl &server, QObject *parent=0)
Create an object for Movable Type.
QString postId() const
Returns the postId.
void setError(const QString &error)
Sets the error.