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"
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.