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(5323) << "WordpressBuggy()";
00042 }
00043
00044 WordpressBuggy::WordpressBuggy( const KUrl &server, WordpressBuggyPrivate &dd,
00045 QObject *parent )
00046 : MovableType( server, dd, parent )
00047 {
00048 kDebug(5323) << "WordpressBuggy()";
00049 }
00050
00051 WordpressBuggy::~WordpressBuggy()
00052 {
00053 kDebug(5323) << "~WordpressBuggy()";
00054 }
00055
00056 void WordpressBuggy::createPost( KBlog::BlogPost *post )
00057 {
00058 kDebug(5323) << "createPost()";
00059 Q_D( WordpressBuggy );
00060 if ( !post ) {
00061 kError(5323) << "WordpressBuggy::createPost: post is a null pointer";
00062 emit error ( Other, i18n( "Post is a null pointer." ) );
00063 return;
00064 }
00065 kDebug(5323) << "Creating new Post with blogId" << blogId();
00066
00067 QString xmlMarkup = "<?xml version=\"1.0\"?>";
00068 xmlMarkup += "<methodCall>";
00069 xmlMarkup += "<methodName>metaWeblog.newPost</methodName>";
00070 xmlMarkup += "<params><param>";
00071 xmlMarkup += "<value><string><![CDATA["+blogId()+"]]></string></value>";
00072 xmlMarkup += "</param>";
00073 xmlMarkup += "<param>";
00074 xmlMarkup += "<value><string><![CDATA["+username()+"]]></string></value>";
00075 xmlMarkup += "</param><param>";
00076 xmlMarkup += "<value><string><![CDATA["+password()+"]]></string></value>";
00077 xmlMarkup += "</param>";
00078 xmlMarkup += "<param><struct>";
00079 xmlMarkup += "<member><name>description</name>";
00080 xmlMarkup += "<value><string><![CDATA["+post->content()+"]]></string></value>";
00081 xmlMarkup += "</member><member>";
00082 xmlMarkup += "<name>title</name>";
00083 xmlMarkup += "<value><string><![CDATA["+post->title()+"]]></string></value>";
00084 xmlMarkup += "</member><member>";
00085
00086 QList<QString> catList = post->categories();
00087 if ( !catList.empty() ){
00088 xmlMarkup += "<name>categories</name>";
00089 xmlMarkup += "<value><array>";
00090 QList<QString>::ConstIterator it = catList.begin();
00091 QList<QString>::ConstIterator end = catList.end();
00092 for ( ; it != end; it++ ){
00093 xmlMarkup += "<data><string><![CDATA[" + ( *it ) + "]]></string></data>";
00094 }
00095 xmlMarkup += "</array></value>";
00096 xmlMarkup += "</member><member>";
00097 }
00098
00099 xmlMarkup += "<name>dateCreated</name>";
00100 xmlMarkup += "<value><dateTime.iso8601>" +
00101 post->creationDateTime().toUtc().dateTime().toString( "yyyyMMddThh:mm:ss" ) +
00102 "</dateTime.iso8601></value>";
00103 xmlMarkup += "</member><member>";
00104 xmlMarkup += "<name>mt_allow_comments</name>";
00105 xmlMarkup += QString( "<value><int>%1</int></value>" ).arg( (int)post->isCommentAllowed() );
00106 xmlMarkup += "</member><member>";
00107 xmlMarkup += "<name>mt_allow_pings</name>";
00108 xmlMarkup += QString( "<value><int>%1</int></value>" ).arg( (int)post->isTrackBackAllowed() );
00109 xmlMarkup += "</member><member>";
00110 xmlMarkup += "<name>mt_excerpt</name>";
00111 xmlMarkup += "<value><string><![CDATA[" + post->summary() + "]]></string></value>";
00112 xmlMarkup += "</member><member>";
00113 xmlMarkup += "<name>mt_keywords</name>";
00114 xmlMarkup += "<value><string><![CDATA[" + post->tags().join(" ") + "]]></string></value>";
00115 xmlMarkup += "</member></struct></param>";
00116 xmlMarkup += "<param><value><boolean>" +
00117 QString( "%1" ).arg( (int)(!post->isPrivate() ) ) +
00118 "</boolean></value></param>";
00119 xmlMarkup += "</params></methodCall>";
00120
00121 QByteArray postData;
00122 QDataStream stream( &postData, QIODevice::WriteOnly );
00123 stream.writeRawData( xmlMarkup.toUtf8(), xmlMarkup.toUtf8().length() );
00124
00125 KIO::TransferJob *job = KIO::http_post( url(), postData, KIO::HideProgressInfo );
00126
00127 d->mCreatePostMap[ job ] = post;
00128
00129 if ( !job ) {
00130 kWarning() << "Failed to create job for: " << url().url();
00131 }
00132
00133 job->addMetaData(
00134 "customHTTPHeader", "X-hacker: Shame on you Wordpress, " + QString() +
00135 "you took another 4 hours of my life to work around the stupid dateTime bug." );
00136 job->addMetaData( "content-type", "Content-Type: text/xml; charset=utf-8" );
00137 job->addMetaData( "ConnectTimeout", "50" );
00138 job->addMetaData( "UserAgent", userAgent() );
00139
00140 connect( job, SIGNAL(data(KIO::Job *,const QByteArray &)),
00141 this, SLOT(slotCreatePostData(KIO::Job *,const QByteArray &)) );
00142 connect( job, SIGNAL(result(KJob *)),
00143 this, SLOT(slotCreatePost(KJob *)) );
00144 }
00145
00146 void WordpressBuggy::modifyPost( KBlog::BlogPost *post )
00147 {
00148 kDebug(5323) << "modifyPost()";
00149 Q_D( WordpressBuggy );
00150 if ( !post ) {
00151 kError(5323) << "WordpressBuggy::modifyPost: post is a null pointer";
00152 emit error ( Other, i18n( "Post is a null pointer." ) );
00153 return;
00154 }
00155
00156 kDebug(5323) << "Uploading Post with postId" << post->postId();
00157
00158 QString xmlMarkup = "<?xml version=\"1.0\"?>";
00159 xmlMarkup += "<methodCall>";
00160 xmlMarkup += "<methodName>metaWeblog.editPost</methodName>";
00161 xmlMarkup += "<params><param>";
00162 xmlMarkup += "<value><string><![CDATA["+post->postId()+"]]></string></value>";
00163 xmlMarkup += "</param>";
00164 xmlMarkup += "<param>";
00165 xmlMarkup += "<value><string><![CDATA["+username()+"]]></string></value>";
00166 xmlMarkup += "</param><param>";
00167 xmlMarkup += "<value><string><![CDATA["+password()+"]]></string></value>";
00168 xmlMarkup += "</param>";
00169 xmlMarkup += "<param><struct>";
00170 xmlMarkup += "<member><name>description</name>";
00171 xmlMarkup += "<value><string><![CDATA["+post->content()+"]]></string></value>";
00172 xmlMarkup += "</member><member>";
00173 xmlMarkup += "<name>title</name>";
00174 xmlMarkup += "<value><string><![CDATA["+post->title()+"]]></string></value>";
00175 xmlMarkup += "</member><member>";
00176
00177 QList<QString> catList = post->categories();
00178 if ( !catList.empty() ){
00179 xmlMarkup += "<name>categories</name>";
00180 xmlMarkup += "<value><array>";
00181 QList<QString>::ConstIterator it = catList.begin();
00182 QList<QString>::ConstIterator end = catList.end();
00183 for ( ; it != end; it++ ){
00184 xmlMarkup += "<data><string><![CDATA[" + ( *it ) + "]]></string></data>";
00185 }
00186 xmlMarkup += "</array></value>";
00187 xmlMarkup += "</member><member>";
00188 }
00189
00190 xmlMarkup += "<name>lastModified</name>";
00191 xmlMarkup += "<value><dateTime.iso8601>" +
00192 post->modificationDateTime().toUtc().dateTime().toString( "yyyyMMddThh:mm:ss" ) +
00193 "</dateTime.iso8601></value>";
00194 xmlMarkup += "</member><member>";
00195 xmlMarkup += "<name>dateCreated</name>";
00196 xmlMarkup += "<value><dateTime.iso8601>" +
00197 post->creationDateTime().toUtc().dateTime().toString( "yyyyMMddThh:mm:ss" ) +
00198 "</dateTime.iso8601></value>";
00199 xmlMarkup += "</member><member>";
00200 xmlMarkup += "<name>mt_allow_comments</name>";
00201 xmlMarkup += QString( "<value><int>%1</int></value>" ).arg( (int)post->isCommentAllowed() );
00202 xmlMarkup += "</member><member>";
00203 xmlMarkup += "<name>mt_allow_pings</name>";
00204 xmlMarkup += QString( "<value><int>%1</int></value>" ).arg( (int)post->isTrackBackAllowed() );
00205 xmlMarkup += "</member><member>";
00206 xmlMarkup += "<name>mt_excerpt</name>";
00207 xmlMarkup += "<value><string><![CDATA[" + post->summary() + "]]></string></value>";
00208 xmlMarkup += "</member><member>";
00209 xmlMarkup += "<name>mt_keywords</name>";
00210 xmlMarkup += "<value><string><![CDATA[" + post->tags().join( " " ) + "]]></string></value>";
00211 xmlMarkup += "</member></struct></param>";
00212 xmlMarkup += "<param><value><boolean>" +
00213 QString( "%1" ).arg( (int)( !post->isPrivate() ) ) +
00214 "</boolean></value></param>";
00215 xmlMarkup += "</params></methodCall>";
00216
00217 QByteArray postData;
00218 QDataStream stream( &postData, QIODevice::WriteOnly );
00219 stream.writeRawData( xmlMarkup.toUtf8(), xmlMarkup.toUtf8().length() );
00220
00221 KIO::TransferJob *job = KIO::http_post( url(), postData, KIO::HideProgressInfo );
00222
00223 d->mModifyPostMap[ job ] = post;
00224
00225 if ( !job ) {
00226 kWarning() << "Failed to create job for: " << url().url();
00227 }
00228
00229 job->addMetaData(
00230 "customHTTPHeader", "X-hacker: Shame on you Wordpress, " + QString() +
00231 "you took another 4 hours of my life to work around the stupid dateTime bug." );
00232 job->addMetaData( "content-type", "Content-Type: text/xml; charset=utf-8" );
00233 job->addMetaData( "ConnectTimeout", "50" );
00234 job->addMetaData( "UserAgent", userAgent() );
00235
00236 connect( job, SIGNAL(data(KIO::Job*,const QByteArray&)),
00237 this, SLOT(slotModifyPostData(KIO::Job*,const QByteArray&)) );
00238 connect( job, SIGNAL(result(KJob*)),
00239 this, SLOT(slotModifyPost(KJob*)) );
00240 }
00241
00242 QString WordpressBuggy::interfaceName() const
00243 {
00244 return QLatin1String( "Movable Type" );
00245 }
00246
00247 WordpressBuggyPrivate::WordpressBuggyPrivate()
00248 {
00249 }
00250
00251 WordpressBuggyPrivate::~WordpressBuggyPrivate()
00252 {
00253 kDebug(5323) << "~WordpressBuggyPrivate()";
00254 }
00255
00256 QList<QVariant> WordpressBuggyPrivate::defaultArgs( const QString &id )
00257 {
00258 Q_Q( WordpressBuggy );
00259 QList<QVariant> args;
00260 if ( !id.isEmpty() ) {
00261 args << QVariant( id );
00262 }
00263 args << QVariant( q->username() )
00264 << QVariant( q->password() );
00265 return args;
00266 }
00267
00268 void WordpressBuggyPrivate::slotCreatePostData( KIO::Job *job, const QByteArray &data )
00269 {
00270 kDebug(5323) << "slotCreatePostData()";
00271 unsigned int oldSize = mCreatePostBuffer[ job ].size();
00272 mCreatePostBuffer[ job ].resize( oldSize + data.size() );
00273 memcpy( mCreatePostBuffer[ job ].data() + oldSize, data.data(), data.size() );
00274 }
00275
00276 void WordpressBuggyPrivate::slotCreatePost( KJob *job )
00277 {
00278 kDebug(5323) << "slotCreatePost()";
00279 const QString data = QString::fromUtf8( mCreatePostBuffer[ job ].data(),
00280 mCreatePostBuffer[ job ].size() );
00281 mCreatePostBuffer[ job ].resize( 0 );
00282
00283 Q_Q( WordpressBuggy );
00284
00285 KBlog::BlogPost *post = mCreatePostMap[ job ];
00286 mCreatePostMap.remove( job );
00287
00288 if ( job->error() != 0 ) {
00289 kError(5323) << "slotCreatePost error:" << job->errorString();
00290 emit q->errorPost( WordpressBuggy::Atom, job->errorString(), post );
00291 return;
00292 }
00293
00294 QRegExp rxError( "faultString" );
00295 if ( rxError.indexIn( data ) != -1 ){
00296 rxError = QRegExp( "<string>(.+)</string>" );
00297 if ( rxError.indexIn( data ) != -1 ) {
00298 kDebug(5323) << "RegExp of faultString failed.";
00299 }
00300 kDebug(5323) << rxError.cap(1);
00301 emit q->errorPost( WordpressBuggy::XmlRpc, rxError.cap(1), post );
00302 return;
00303 }
00304
00305 QRegExp rxId( "<string>(.+)</string>" );
00306 if ( rxId.indexIn( data ) == -1 ){
00307 kError(5323) << "Could not regexp the id out of the result:" << data;
00308 emit q->errorPost( WordpressBuggy::XmlRpc,
00309 i18n( "Could not regexp the id out of the result." ), post );
00310 return;
00311 }
00312 kDebug(5323) << "QRegExp rx( \"<string>(.+)</string>\" ) matches" << rxId.cap( 1 );
00313
00314 post->setPostId( rxId.cap( 1 ) );
00315 post->setStatus( BlogPost::Created );
00316 emit q->createdPost( post );
00317 kDebug(5323) << "Emitting createdPost()";
00318 }
00319
00320 void WordpressBuggyPrivate::slotModifyPostData( KIO::Job *job, const QByteArray &data )
00321 {
00322 kDebug(5323) << "slotModifyPostData()";
00323 unsigned int oldSize = mModifyPostBuffer[ job ].size();
00324 mModifyPostBuffer[ job ].resize( oldSize + data.size() );
00325 memcpy( mModifyPostBuffer[ job ].data() + oldSize, data.data(), data.size() );
00326 }
00327
00328 void WordpressBuggyPrivate::slotModifyPost( KJob *job )
00329 {
00330 kDebug(5323) << "slotModifyPost()";
00331 const QString data = QString::fromUtf8( mModifyPostBuffer[ job ].data(),
00332 mModifyPostBuffer[ job ].size() );
00333 mModifyPostBuffer[ job ].resize( 0 );
00334
00335 KBlog::BlogPost *post = mModifyPostMap[ job ];
00336 mModifyPostMap.remove( job );
00337 Q_Q( WordpressBuggy );
00338 if ( job->error() != 0 ) {
00339 kError(5323) << "slotModifyPost error:" << job->errorString();
00340 emit q->errorPost( WordpressBuggy::Atom, job->errorString(), post );
00341 return;
00342 }
00343
00344 QRegExp rxError( "faultString" );
00345 if ( rxError.indexIn( data ) != -1 ){
00346 rxError = QRegExp( "<string>(.+)</string>" );
00347 if ( rxError.indexIn( data ) != -1 ) {
00348 kDebug(5323) << "RegExp of faultString failed.";
00349 }
00350 kDebug(5323) << rxError.cap(1);
00351 emit q->errorPost( WordpressBuggy::XmlRpc, rxError.cap(1), post );
00352 return;
00353 }
00354
00355 QRegExp rxId( "<boolean>(.+)</boolean>" );
00356 if ( rxId.indexIn( data ) == -1 ) {
00357 kError(5323) << "Could not regexp the id out of the result:" << data;
00358 emit q->errorPost( WordpressBuggy::XmlRpc,
00359 i18n( "Could not regexp the id out of the result." ), post );
00360 return;
00361 }
00362 kDebug(5323) << "QRegExp rx( \"<boolean>(.+)</boolean>\" ) matches" << rxId.cap( 1 );
00363
00364 if ( rxId.cap( 1 ).toInt() == 1 ) {
00365 kDebug(5323) << "Post successfully updated.";
00366 post->setStatus( BlogPost::Modified );
00367 emit q->modifiedPost( post );
00368 }
00369 }
00370
00371 #include "wordpressbuggy.moc"