KBlog Client Library
wordpressbuggy.cpp
00001 /* 00002 This file is part of the kblog library. 00003 00004 Copyright (c) 2006-2009 Christian Weilbach <christian_weilbach@web.de> 00005 00006 This library is free software; you can redistribute it and/or 00007 modify it under the terms of the GNU Library General Public 00008 License as published by the Free Software Foundation; either 00009 version 2 of the License, or (at your option) any later version. 00010 00011 This library is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 Library General Public License for more details. 00015 00016 You should have received a copy of the GNU Library General Public License 00017 along with this library; see the file COPYING.LIB. If not, write to 00018 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00019 Boston, MA 02110-1301, USA. 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 // reimplemented because we do this: 00059 // http://comox.textdrive.com/pipermail/wp-testers/2005-July/000284.html 00060 kDebug(); 00061 Q_D( WordpressBuggy ); 00062 00063 // we need mCategoriesList to be loaded first, since we cannot use the post->categories() 00064 // names later, but we need to map them to categoryId of the blog 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(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 // If we do setPostCategories() later than we disable publishing first. 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 // HACK: uuh this a bit ugly now... reenable the original publish argument, 00164 // since createPost should have parsed now 00165 post->setPrivate(publish); 00166 } 00167 } 00168 00169 void WordpressBuggy::modifyPost( KBlog::BlogPost *post ) 00170 { 00171 // reimplemented because we do this: 00172 // http://comox.textdrive.com/pipermail/wp-testers/2005-July/000284.html 00173 kDebug(); 00174 Q_D( WordpressBuggy ); 00175 00176 // we need mCategoriesList to be loaded first, since we cannot use the post->categories() 00177 // names later, but we need to map them to categoryId of the blog 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(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 // set the categories and publish afterwards 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"
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Mon Aug 27 2012 22:07:42 by doxygen 1.7.5 written by Dimitri van Heesch, © 1997-2006
Documentation copyright © 1996-2012 The KDE developers.
Generated on Mon Aug 27 2012 22:07:42 by doxygen 1.7.5 written by Dimitri van Heesch, © 1997-2006
KDE's Doxygen guidelines are available online.