00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "wordpressbuggy.h"
00023 #include "wordpressbuggy_p.h"
00024
00025 #include "blogpost.h"
00026
00027 #include <KDebug>
00028 #include <KLocale>
00029 #include <KDateTime>
00030
00031 #include <kio/http.h>
00032 #include <kio/job.h>
00033
00034 #include <QtCore/QStringList>
00035
00036 using namespace KBlog;
00037
00038 WordpressBuggy::WordpressBuggy( const KUrl &server, QObject *parent )
00039 : MovableType( server, *new WordpressBuggyPrivate, parent )
00040 {
00041 kDebug();
00042 }
00043
00044 WordpressBuggy::WordpressBuggy( const KUrl &server, WordpressBuggyPrivate &dd,
00045 QObject *parent )
00046 : MovableType( server, dd, parent )
00047 {
00048 kDebug();
00049 }
00050
00051 WordpressBuggy::~WordpressBuggy()
00052 {
00053 kDebug();
00054 }
00055
00056 void WordpressBuggy::createPost( KBlog::BlogPost *post )
00057 {
00058
00059
00060 kDebug();
00061 Q_D( WordpressBuggy );
00062
00063
00064
00065 d->loadCategories();
00066 if(d->mCategoriesList.isEmpty()){
00067 kDebug() << "No categories in the cache yet. Have to fetch them first.";
00068 d->mCreatePostCache << post;
00069 connect(this,SIGNAL(listedCategories(const QList<QMap<QString,QString> >&)),
00070 this,SLOT(slotTriggerCreatePost()));
00071 listCategories();
00072 }
00073 else {
00074 kDebug() << "createPost()";
00075 if ( !post ) {
00076 kError() << "WordpressBuggy::createPost: post is a null pointer";
00077 emit error ( Other, i18n( "Post is a null pointer." ) );
00078 return;
00079 }
00080 kDebug() << "Creating new Post with blogId" << blogId();
00081
00082 bool publish = post->isPrivate();
00083
00084 if( !post->categories().isEmpty() ){
00085 post->setPrivate( true );
00086 if ( d->mSilentCreationList.contains( post ) ) {
00087 kDebug()<< "Post already in mSilentCreationList, this *should* never happen!";
00088 } else {
00089 d->mSilentCreationList << post;
00090 }
00091 }
00092
00093 QString xmlMarkup = "<?xml version=\"1.0\"?>";
00094 xmlMarkup += "<methodCall>";
00095 xmlMarkup += "<methodName>metaWeblog.newPost</methodName>";
00096 xmlMarkup += "<params><param>";
00097 xmlMarkup += "<value><string><![CDATA["+blogId()+"]]></string></value>";
00098 xmlMarkup += "</param>";
00099 xmlMarkup += "<param>";
00100 xmlMarkup += "<value><string><![CDATA["+username()+"]]></string></value>";
00101 xmlMarkup += "</param><param>";
00102 xmlMarkup += "<value><string><![CDATA["+password()+"]]></string></value>";
00103 xmlMarkup += "</param>";
00104 xmlMarkup += "<param><struct>";
00105 xmlMarkup += "<member><name>description</name>";
00106 xmlMarkup += "<value><string><![CDATA["+post->content()+"]]></string></value>";
00107 xmlMarkup += "</member><member>";
00108 xmlMarkup += "<name>title</name>";
00109 xmlMarkup += "<value><string><![CDATA["+post->title()+"]]></string></value>";
00110 xmlMarkup += "</member><member>";
00111
00112 xmlMarkup += "<name>dateCreated</name>";
00113 xmlMarkup += "<value><dateTime.iso8601>" +
00114 post->creationDateTime().dateTime().toUTC().toString( "yyyyMMddThh:mm:ss" ) +
00115 "</dateTime.iso8601></value>";
00116 xmlMarkup += "</member><member>";
00117 xmlMarkup += "<name>mt_allow_comments</name>";
00118 xmlMarkup += QString( "<value><int>%1</int></value>" ).arg( (int)post->isCommentAllowed() );
00119 xmlMarkup += "</member><member>";
00120 xmlMarkup += "<name>mt_allow_pings</name>";
00121 xmlMarkup += QString( "<value><int>%1</int></value>" ).arg( (int)post->isTrackBackAllowed() );
00122 xmlMarkup += "</member><member>";
00123 if( !post->additionalContent().isEmpty() ) {
00124 xmlMarkup += "<name>mt_text_more</name>";
00125 xmlMarkup += "<value><string><![CDATA[" + post->additionalContent() + "]]></string></value>";
00126 xmlMarkup += "</member><member>";
00127 }
00128 xmlMarkup += "<name>wp_slug</name>";
00129 xmlMarkup += "<value><string><![CDATA[" + post->slug() + "]]></string></value>";
00130 xmlMarkup += "</member><member>";
00131 xmlMarkup += "<name>mt_excerpt</name>";
00132 xmlMarkup += "<value><string><![CDATA[" + post->summary() + "]]></string></value>";
00133 xmlMarkup += "</member><member>";
00134 xmlMarkup += "<name>mt_keywords</name>";
00135 xmlMarkup += "<value><string><![CDATA[" + post->tags().join(",") + "]]></string></value>";
00136 xmlMarkup += "</member></struct></param>";
00137 xmlMarkup += "<param><value><boolean>" +
00138 QString( "%1" ).arg( (int)(!post->isPrivate() ) ) +
00139 "</boolean></value></param>";
00140 xmlMarkup += "</params></methodCall>";
00141
00142 QByteArray postData;
00143 QDataStream stream( &postData, QIODevice::WriteOnly );
00144 stream.writeRawData( xmlMarkup.toUtf8(), xmlMarkup.toUtf8().length() );
00145
00146 KIO::StoredTransferJob *job = KIO::storedHttpPost( postData, url(), KIO::HideProgressInfo );
00147
00148 d->mCreatePostMap[ job ] = post;
00149
00150 if ( !job ) {
00151 kWarning() << "Failed to create job for: " << url().url();
00152 }
00153
00154 job->addMetaData(
00155 "customHTTPHeader", "X-hacker: Shame on you Wordpress, " + QString() +
00156 "you took another 4 hours of my life to work around the stupid dateTime bug." );
00157 job->addMetaData( "content-type", "Content-Type: text/xml; charset=utf-8" );
00158 job->addMetaData( "ConnectTimeout", "50" );
00159 job->addMetaData( "UserAgent", userAgent() );
00160
00161 connect( job, SIGNAL(result(KJob *)),
00162 this, SLOT(slotCreatePost(KJob *)) );
00163
00164
00165 post->setPrivate(publish);
00166 }
00167 }
00168
00169 void WordpressBuggy::modifyPost( KBlog::BlogPost *post )
00170 {
00171
00172
00173 kDebug();
00174 Q_D( WordpressBuggy );
00175
00176
00177
00178 d->loadCategories();
00179 if(d->mCategoriesList.isEmpty()){
00180 kDebug() << "No categories in the cache yet. Have to fetch them first.";
00181 d->mModifyPostCache << post;
00182 connect(this,SIGNAL(listedCategories(const QList<QMap<QString,QString> >&)),
00183 this,SLOT(slotTriggerModifyPost()));
00184 listCategories();
00185 }
00186 else {
00187 if ( !post ) {
00188 kError() << "WordpressBuggy::modifyPost: post is a null pointer";
00189 emit error ( Other, i18n( "Post is a null pointer." ) );
00190 return;
00191 }
00192
00193 kDebug() << "Uploading Post with postId" << post->postId();
00194
00195 QString xmlMarkup = "<?xml version=\"1.0\"?>";
00196 xmlMarkup += "<methodCall>";
00197 xmlMarkup += "<methodName>metaWeblog.editPost</methodName>";
00198 xmlMarkup += "<params><param>";
00199 xmlMarkup += "<value><string><![CDATA["+post->postId()+"]]></string></value>";
00200 xmlMarkup += "</param>";
00201 xmlMarkup += "<param>";
00202 xmlMarkup += "<value><string><![CDATA["+username()+"]]></string></value>";
00203 xmlMarkup += "</param><param>";
00204 xmlMarkup += "<value><string><![CDATA["+password()+"]]></string></value>";
00205 xmlMarkup += "</param>";
00206 xmlMarkup += "<param><struct>";
00207 xmlMarkup += "<member><name>description</name>";
00208 xmlMarkup += "<value><string><![CDATA["+post->content()+"]]></string></value>";
00209 xmlMarkup += "</member><member>";
00210 xmlMarkup += "<name>title</name>";
00211 xmlMarkup += "<value><string><![CDATA["+post->title()+"]]></string></value>";
00212 xmlMarkup += "</member><member>";
00213
00214 xmlMarkup += "<name>lastModified</name>";
00215 xmlMarkup += "<value><dateTime.iso8601>" +
00216 post->modificationDateTime().dateTime().toUTC().toString( "yyyyMMddThh:mm:ss" ) +
00217 "</dateTime.iso8601></value>";
00218 xmlMarkup += "</member><member>";
00219 xmlMarkup += "<name>dateCreated</name>";
00220 xmlMarkup += "<value><dateTime.iso8601>" +
00221 post->creationDateTime().dateTime().toUTC().toString( "yyyyMMddThh:mm:ss" ) +
00222 "</dateTime.iso8601></value>";
00223 xmlMarkup += "</member><member>";
00224 xmlMarkup += "<name>mt_allow_comments</name>";
00225 xmlMarkup += QString( "<value><int>%1</int></value>" ).arg( (int)post->isCommentAllowed() );
00226 xmlMarkup += "</member><member>";
00227 xmlMarkup += "<name>mt_allow_pings</name>";
00228 xmlMarkup += QString( "<value><int>%1</int></value>" ).arg( (int)post->isTrackBackAllowed() );
00229 xmlMarkup += "</member><member>";
00230 if( !post->additionalContent().isEmpty() ) {
00231 xmlMarkup += "<name>mt_text_more</name>";
00232 xmlMarkup += "<value><string><![CDATA[" + post->additionalContent() + "]]></string></value>";
00233 xmlMarkup += "</member><member>";
00234 }
00235 xmlMarkup += "<name>wp_slug</name>";
00236 xmlMarkup += "<value><string><![CDATA[" + post->slug() + "]]></string></value>";
00237 xmlMarkup += "</member><member>";
00238 xmlMarkup += "<name>mt_excerpt</name>";
00239 xmlMarkup += "<value><string><![CDATA[" + post->summary() + "]]></string></value>";
00240 xmlMarkup += "</member><member>";
00241 xmlMarkup += "<name>mt_keywords</name>";
00242 xmlMarkup += "<value><string><![CDATA[" + post->tags().join( "," ) + "]]></string></value>";
00243 xmlMarkup += "</member></struct></param>";
00244 xmlMarkup += "<param><value><boolean>" +
00245 QString( "%1" ).arg( (int)( !post->isPrivate() ) ) +
00246 "</boolean></value></param>";
00247 xmlMarkup += "</params></methodCall>";
00248
00249 QByteArray postData;
00250 QDataStream stream( &postData, QIODevice::WriteOnly );
00251 stream.writeRawData( xmlMarkup.toUtf8(), xmlMarkup.toUtf8().length() );
00252
00253 KIO::StoredTransferJob *job = KIO::storedHttpPost( postData, url(), KIO::HideProgressInfo );
00254
00255 d->mModifyPostMap[ job ] = post;
00256
00257 if ( !job ) {
00258 kWarning() << "Failed to create job for: " << url().url();
00259 }
00260
00261 job->addMetaData(
00262 "customHTTPHeader", "X-hacker: Shame on you Wordpress, " + QString() +
00263 "you took another 4 hours of my life to work around the stupid dateTime bug." );
00264 job->addMetaData( "content-type", "Content-Type: text/xml; charset=utf-8" );
00265 job->addMetaData( "ConnectTimeout", "50" );
00266 job->addMetaData( "UserAgent", userAgent() );
00267
00268 connect( job, SIGNAL(result(KJob*)),
00269 this, SLOT(slotModifyPost(KJob*)) );
00270 }
00271 }
00272
00273 QString WordpressBuggy::interfaceName() const
00274 {
00275 return QLatin1String( "Movable Type" );
00276 }
00277
00278 WordpressBuggyPrivate::WordpressBuggyPrivate()
00279 {
00280 }
00281
00282 WordpressBuggyPrivate::~WordpressBuggyPrivate()
00283 {
00284 kDebug();
00285 }
00286
00287 QList<QVariant> WordpressBuggyPrivate::defaultArgs( const QString &id )
00288 {
00289 Q_Q( WordpressBuggy );
00290 QList<QVariant> args;
00291 if ( !id.isEmpty() ) {
00292 args << QVariant( id );
00293 }
00294 args << QVariant( q->username() )
00295 << QVariant( q->password() );
00296 return args;
00297 }
00298
00299 void WordpressBuggyPrivate::slotCreatePost( KJob *job )
00300 {
00301 kDebug();
00302
00303 KIO::StoredTransferJob *stj = qobject_cast<KIO::StoredTransferJob*>(job);
00304 const QString data = QString::fromUtf8( stj->data(), stj->data().size() );
00305
00306 Q_Q( WordpressBuggy );
00307
00308 KBlog::BlogPost *post = mCreatePostMap[ job ];
00309 mCreatePostMap.remove( job );
00310
00311 if ( job->error() != 0 ) {
00312 kError() << "slotCreatePost error:" << job->errorString();
00313 emit q->errorPost( WordpressBuggy::XmlRpc, job->errorString(), post );
00314 return;
00315 }
00316
00317 QRegExp rxError( "faultString" );
00318 if ( rxError.indexIn( data ) != -1 ){
00319 rxError = QRegExp( "<string>(.+)</string>" );
00320 if ( rxError.indexIn( data ) != -1 ) {
00321 kDebug() << "RegExp of faultString failed.";
00322 }
00323 kDebug() << rxError.cap(1);
00324 emit q->errorPost( WordpressBuggy::XmlRpc, rxError.cap(1), post );
00325 return;
00326 }
00327
00328 QRegExp rxId( "<string>(.+)</string>" );
00329 if ( rxId.indexIn( data ) == -1 ){
00330 kError() << "Could not regexp the id out of the result:" << data;
00331 emit q->errorPost( WordpressBuggy::XmlRpc,
00332 i18n( "Could not regexp the id out of the result." ), post );
00333 return;
00334 }
00335 kDebug() << "QRegExp rx( \"<string>(.+)</string>\" ) matches" << rxId.cap( 1 );
00336
00337 post->setPostId( rxId.cap( 1 ) );
00338 if ( mSilentCreationList.contains( post ) )
00339 {
00340
00341 setPostCategories( post, !post->isPrivate() );
00342 } else {
00343 kDebug() << "emitting createdPost()"
00344 << "for title: \"" << post->title();
00345 emit q->createdPost( post );
00346 post->setStatus( KBlog::BlogPost::Created );
00347 }
00348 }
00349
00350 void WordpressBuggyPrivate::slotModifyPost( KJob *job )
00351 {
00352 kDebug();
00353
00354 KIO::StoredTransferJob *stj = qobject_cast<KIO::StoredTransferJob*>(job);
00355 const QString data = QString::fromUtf8( stj->data(), stj->data().size() );
00356
00357 KBlog::BlogPost *post = mModifyPostMap[ job ];
00358 mModifyPostMap.remove( job );
00359 Q_Q( WordpressBuggy );
00360 if ( job->error() != 0 ) {
00361 kError() << "slotModifyPost error:" << job->errorString();
00362 emit q->errorPost( WordpressBuggy::XmlRpc, job->errorString(), post );
00363 return;
00364 }
00365
00366 QRegExp rxError( "faultString" );
00367 if ( rxError.indexIn( data ) != -1 ){
00368 rxError = QRegExp( "<string>(.+)</string>" );
00369 if ( rxError.indexIn( data ) != -1 ) {
00370 kDebug() << "RegExp of faultString failed.";
00371 }
00372 kDebug() << rxError.cap(1);
00373 emit q->errorPost( WordpressBuggy::XmlRpc, rxError.cap(1), post );
00374 return;
00375 }
00376
00377 QRegExp rxId( "<boolean>(.+)</boolean>" );
00378 if ( rxId.indexIn( data ) == -1 ) {
00379 kError() << "Could not regexp the id out of the result:" << data;
00380 emit q->errorPost( WordpressBuggy::XmlRpc,
00381 i18n( "Could not regexp the id out of the result." ), post );
00382 return;
00383 }
00384 kDebug() << "QRegExp rx( \"<boolean>(.+)</boolean>\" ) matches" << rxId.cap( 1 );
00385
00386 if ( rxId.cap( 1 ).toInt() == 1 ) {
00387 kDebug() << "Post successfully updated.";
00388 if ( mSilentCreationList.contains( post ) ) {
00389 post->setStatus( KBlog::BlogPost::Created );
00390 emit q->createdPost( post );
00391 mSilentCreationList.removeOne( post );
00392 } else {
00393 if( !post->categories().isEmpty() ){
00394 setPostCategories( post, false );
00395 }
00396 }
00397 }
00398 }
00399
00400 #include "wordpressbuggy.moc"