/* This file is part of the kblog library. Copyright (c) 2006-2009 Christian Weilbach This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "wordpressbuggy.h" #include "wordpressbuggy_p.h" #include "blogpost.h" #include #include #include #include #include using namespace KBlog; WordpressBuggy::WordpressBuggy( const KUrl &server, QObject *parent ) : MovableType( server, *new WordpressBuggyPrivate, parent ) { kDebug(); } WordpressBuggy::WordpressBuggy( const KUrl &server, WordpressBuggyPrivate &dd, QObject *parent ) : MovableType( server, dd, parent ) { kDebug(); } WordpressBuggy::~WordpressBuggy() { kDebug(); } void WordpressBuggy::createPost( KBlog::BlogPost *post ) { // reimplemented because we do this: // http://comox.textdrive.com/pipermail/wp-testers/2005-July/000284.html kDebug(); Q_D( WordpressBuggy ); // we need mCategoriesList to be loaded first, since we cannot use the post->categories() // names later, but we need to map them to categoryId of the blog d->loadCategories(); if ( d->mCategoriesList.isEmpty() ) { kDebug() << "No categories in the cache yet. Have to fetch them first."; d->mCreatePostCache << post; connect( this,SIGNAL(listedCategories(QList >)), this,SLOT(slotTriggerCreatePost()) ); listCategories(); } else { kDebug() << "createPost()"; if ( !post ) { kError() << "WordpressBuggy::createPost: post is a null pointer"; emit error ( Other, i18n( "Post is a null pointer." ) ); return; } kDebug() << "Creating new Post with blogId" << blogId(); bool publish = post->isPrivate(); // If we do setPostCategories() later than we disable publishing first. if ( !post->categories().isEmpty() ) { post->setPrivate( true ); if ( d->mSilentCreationList.contains( post ) ) { kDebug() << "Post already in mSilentCreationList, this *should* never happen!"; } else { d->mSilentCreationList << post; } } QString xmlMarkup = QLatin1String(""); xmlMarkup += QLatin1String(""); xmlMarkup += QLatin1String("metaWeblog.newPost"); xmlMarkup += QLatin1String(""); xmlMarkup += QLatin1String(""); xmlMarkup += QLatin1String(""); xmlMarkup += QLatin1String(""); xmlMarkup += QLatin1String(""); xmlMarkup += QLatin1String(""); xmlMarkup += QLatin1String(""); xmlMarkup += QLatin1String(""); xmlMarkup += QLatin1String(""); xmlMarkup += QLatin1String("description"); xmlMarkup += QLatin1String("content()+QLatin1String("]]>"); xmlMarkup += QLatin1String(""); xmlMarkup += QLatin1String("title"); xmlMarkup += QLatin1String("title()+QLatin1String("]]>"); xmlMarkup += QLatin1String(""); xmlMarkup += QLatin1String("dateCreated"); xmlMarkup += QLatin1String("") + post->creationDateTime().dateTime().toUTC().toString( QLatin1String("yyyyMMddThh:mm:ss") ) + QLatin1String(""); xmlMarkup += QLatin1String(""); xmlMarkup += QLatin1String("mt_allow_comments"); xmlMarkup += QString::fromLatin1( "%1" ).arg( (int)post->isCommentAllowed() ); xmlMarkup += QLatin1String(""); xmlMarkup += QLatin1String("mt_allow_pings"); xmlMarkup += QString::fromLatin1( "%1" ).arg( (int)post->isTrackBackAllowed() ); xmlMarkup += QLatin1String(""); if ( !post->additionalContent().isEmpty() ) { xmlMarkup += QLatin1String("mt_text_more"); xmlMarkup += QLatin1String("additionalContent() + QLatin1String("]]>"); xmlMarkup += QLatin1String(""); } xmlMarkup += QLatin1String("wp_slug"); xmlMarkup += QLatin1String("slug() + QLatin1String("]]>"); xmlMarkup += QLatin1String(""); xmlMarkup += QLatin1String("mt_excerpt"); xmlMarkup += QLatin1String("summary() + QLatin1String("]]>"); xmlMarkup += QLatin1String(""); xmlMarkup += QLatin1String("mt_keywords"); xmlMarkup += QLatin1String("tags().join(QLatin1String(",")) + QLatin1String("]]>"); xmlMarkup += QLatin1String(""); xmlMarkup += QLatin1String("") + QString::fromLatin1( "%1" ).arg( (int)(!post->isPrivate() ) ) + QLatin1String(""); xmlMarkup += QLatin1String(""); QByteArray postData; QDataStream stream( &postData, QIODevice::WriteOnly ); stream.writeRawData( xmlMarkup.toUtf8(), xmlMarkup.toUtf8().length() ); KIO::StoredTransferJob *job = KIO::storedHttpPost( postData, url(), KIO::HideProgressInfo ); d->mCreatePostMap[ job ] = post; if ( !job ) { kWarning() << "Failed to create job for: " << url().url(); } job->addMetaData( QLatin1String("customHTTPHeader"), QLatin1String("X-hacker: Shame on you Wordpress, ") + QString() + QLatin1String("you took another 4 hours of my life to work around the stupid dateTime bug.") ); job->addMetaData( QLatin1String("content-type"), QLatin1String("Content-Type: text/xml; charset=utf-8") ); job->addMetaData( QLatin1String("ConnectTimeout"), QLatin1String("50") ); job->addMetaData( QLatin1String("UserAgent"), userAgent() ); connect( job, SIGNAL(result(KJob*)), this, SLOT(slotCreatePost(KJob*)) ); // HACK: uuh this a bit ugly now... reenable the original publish argument, // since createPost should have parsed now post->setPrivate( publish ); } } void WordpressBuggy::modifyPost( KBlog::BlogPost *post ) { // reimplemented because we do this: // http://comox.textdrive.com/pipermail/wp-testers/2005-July/000284.html kDebug(); Q_D( WordpressBuggy ); // we need mCategoriesList to be loaded first, since we cannot use the post->categories() // names later, but we need to map them to categoryId of the blog d->loadCategories(); if ( d->mCategoriesList.isEmpty() ) { kDebug() << "No categories in the cache yet. Have to fetch them first."; d->mModifyPostCache << post; connect( this,SIGNAL(listedCategories(QList >)), this,SLOT(slotTriggerModifyPost()) ); listCategories(); } else { if ( !post ) { kError() << "WordpressBuggy::modifyPost: post is a null pointer"; emit error ( Other, i18n( "Post is a null pointer." ) ); return; } kDebug() << "Uploading Post with postId" << post->postId(); QString xmlMarkup = QLatin1String(""); xmlMarkup += QLatin1String(""); xmlMarkup += QLatin1String("metaWeblog.editPost"); xmlMarkup += QLatin1String(""); xmlMarkup += QLatin1String("postId()+QLatin1String("]]>"); xmlMarkup += QLatin1String(""); xmlMarkup += QLatin1String(""); xmlMarkup += QLatin1String(""); xmlMarkup += QLatin1String(""); xmlMarkup += QLatin1String(""); xmlMarkup += QLatin1String(""); xmlMarkup += QLatin1String(""); xmlMarkup += QLatin1String("description"); xmlMarkup += QLatin1String("content()+QLatin1String("]]>"); xmlMarkup += QLatin1String(""); xmlMarkup += QLatin1String("title"); xmlMarkup += QLatin1String("title()+QLatin1String("]]>"); xmlMarkup += QLatin1String(""); xmlMarkup += QLatin1String("lastModified"); xmlMarkup += QLatin1String("") + post->modificationDateTime().dateTime().toUTC().toString( QLatin1String("yyyyMMddThh:mm:ss") ) + QLatin1String(""); xmlMarkup += QLatin1String(""); xmlMarkup += QLatin1String("dateCreated"); xmlMarkup += QLatin1String("") + post->creationDateTime().dateTime().toUTC().toString( QLatin1String("yyyyMMddThh:mm:ss") ) + QLatin1String(""); xmlMarkup += QLatin1String(""); xmlMarkup += QLatin1String("mt_allow_comments"); xmlMarkup += QString::fromLatin1( "%1" ).arg( (int)post->isCommentAllowed() ); xmlMarkup += QLatin1String(""); xmlMarkup += QLatin1String("mt_allow_pings"); xmlMarkup += QString::fromLatin1( "%1" ).arg( (int)post->isTrackBackAllowed() ); xmlMarkup += QLatin1String(""); if ( !post->additionalContent().isEmpty() ) { xmlMarkup += QLatin1String("mt_text_more"); xmlMarkup += QLatin1String("additionalContent() + QLatin1String("]]>"); xmlMarkup += QLatin1String(""); } xmlMarkup += QLatin1String("wp_slug"); xmlMarkup += QLatin1String("slug() + QLatin1String("]]>"); xmlMarkup += QLatin1String(""); xmlMarkup += QLatin1String("mt_excerpt"); xmlMarkup += QLatin1String("summary() + QLatin1String("]]>"); xmlMarkup += QLatin1String(""); xmlMarkup += QLatin1String("mt_keywords"); xmlMarkup += QLatin1String("tags().join( QLatin1String(",") ) + QLatin1String("]]>"); xmlMarkup += QLatin1String(""); xmlMarkup += QLatin1String("") + QString::fromLatin1( "%1" ).arg( (int)( !post->isPrivate() ) ) + QLatin1String(""); xmlMarkup += QLatin1String(""); QByteArray postData; QDataStream stream( &postData, QIODevice::WriteOnly ); stream.writeRawData( xmlMarkup.toUtf8(), xmlMarkup.toUtf8().length() ); KIO::StoredTransferJob *job = KIO::storedHttpPost( postData, url(), KIO::HideProgressInfo ); d->mModifyPostMap[ job ] = post; if ( !job ) { kWarning() << "Failed to create job for: " << url().url(); } job->addMetaData( QLatin1String("customHTTPHeader"), QLatin1String("X-hacker: Shame on you Wordpress, ") + QString() + QLatin1String("you took another 4 hours of my life to work around the stupid dateTime bug.") ); job->addMetaData( QLatin1String("content-type"), QLatin1String("Content-Type: text/xml; charset=utf-8") ); job->addMetaData( QLatin1String("ConnectTimeout"), QLatin1String("50") ); job->addMetaData( QLatin1String("UserAgent"), userAgent() ); connect( job, SIGNAL(result(KJob*)), this, SLOT(slotModifyPost(KJob*)) ); } } QString WordpressBuggy::interfaceName() const { return QLatin1String( "Movable Type" ); } WordpressBuggyPrivate::WordpressBuggyPrivate() { } WordpressBuggyPrivate::~WordpressBuggyPrivate() { kDebug(); } QList WordpressBuggyPrivate::defaultArgs( const QString &id ) { Q_Q( WordpressBuggy ); QList args; if ( !id.isEmpty() ) { args << QVariant( id ); } args << QVariant( q->username() ) << QVariant( q->password() ); return args; } void WordpressBuggyPrivate::slotCreatePost( KJob *job ) { kDebug(); KIO::StoredTransferJob *stj = qobject_cast( job ); const QString data = QString::fromUtf8( stj->data(), stj->data().size() ); Q_Q( WordpressBuggy ); KBlog::BlogPost *post = mCreatePostMap[ job ]; mCreatePostMap.remove( job ); if ( job->error() != 0 ) { kError() << "slotCreatePost error:" << job->errorString(); emit q->errorPost( WordpressBuggy::XmlRpc, job->errorString(), post ); return; } QRegExp rxError( QLatin1String("faultString") ); if ( rxError.indexIn( data ) != -1 ) { rxError = QRegExp( QLatin1String("(.+)") ); if ( rxError.indexIn( data ) != -1 ) { kDebug() << "RegExp of faultString failed."; } kDebug() << rxError.cap( 1 ); emit q->errorPost( WordpressBuggy::XmlRpc, rxError.cap( 1 ), post ); return; } QRegExp rxId( QLatin1String("(.+)") ); if ( rxId.indexIn( data ) == -1 ) { kError() << "Could not regexp the id out of the result:" << data; emit q->errorPost( WordpressBuggy::XmlRpc, i18n( "Could not regexp the id out of the result." ), post ); return; } kDebug() << "QRegExp rx( \"(.+)\" ) matches" << rxId.cap( 1 ); post->setPostId( rxId.cap( 1 ) ); if ( mSilentCreationList.contains( post ) ) { // set the categories and publish afterwards setPostCategories( post, !post->isPrivate() ); } else { kDebug() << "emitting createdPost()" << "for title: \"" << post->title(); emit q->createdPost( post ); post->setStatus( KBlog::BlogPost::Created ); } } void WordpressBuggyPrivate::slotModifyPost( KJob *job ) { kDebug(); KIO::StoredTransferJob *stj = qobject_cast( job ); const QString data = QString::fromUtf8( stj->data(), stj->data().size() ); KBlog::BlogPost *post = mModifyPostMap[ job ]; mModifyPostMap.remove( job ); Q_Q( WordpressBuggy ); if ( job->error() != 0 ) { kError() << "slotModifyPost error:" << job->errorString(); emit q->errorPost( WordpressBuggy::XmlRpc, job->errorString(), post ); return; } QRegExp rxError( QLatin1String("faultString") ); if ( rxError.indexIn( data ) != -1 ) { rxError = QRegExp( QLatin1String("(.+)") ); if ( rxError.indexIn( data ) != -1 ) { kDebug() << "RegExp of faultString failed."; } kDebug() << rxError.cap( 1 ); emit q->errorPost( WordpressBuggy::XmlRpc, rxError.cap( 1 ), post ); return; } QRegExp rxId( QLatin1String("(.+)") ); if ( rxId.indexIn( data ) == -1 ) { kError() << "Could not regexp the id out of the result:" << data; emit q->errorPost( WordpressBuggy::XmlRpc, i18n( "Could not regexp the id out of the result." ), post ); return; } kDebug() << "QRegExp rx( \"(.+)\" ) matches" << rxId.cap( 1 ); if ( rxId.cap( 1 ).toInt() == 1 ) { kDebug() << "Post successfully updated."; if ( mSilentCreationList.contains( post ) ) { post->setStatus( KBlog::BlogPost::Created ); emit q->createdPost( post ); mSilentCreationList.removeOne( post ); } else { if ( !post->categories().isEmpty() ) { setPostCategories( post, false ); } } } } #include "moc_wordpressbuggy.cpp"