00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "metaweblog.h"
00025 #include "metaweblog_p.h"
00026 #include "blogpost.h"
00027 #include "blogmedia.h"
00028
00029 #include <kxmlrpcclient/client.h>
00030 #include <KDebug>
00031 #include <KLocale>
00032 #include <KDateTime>
00033 #include <kstandarddirs.h>
00034
00035 #include <QtCore/QFile>
00036 #include <QtCore/QDataStream>
00037
00038 using namespace KBlog;
00039
00040 MetaWeblog::MetaWeblog( const KUrl &server, QObject *parent )
00041 : Blogger1( server, *new MetaWeblogPrivate, parent )
00042 {
00043 kDebug();
00044 }
00045
00046 MetaWeblog::MetaWeblog( const KUrl &server, MetaWeblogPrivate &dd, QObject *parent )
00047 : Blogger1( server, dd, parent )
00048 {
00049 kDebug();
00050 }
00051
00052 MetaWeblog::~MetaWeblog()
00053 {
00054 kDebug();
00055 }
00056
00057 QString MetaWeblog::interfaceName() const
00058 {
00059 return QLatin1String( "MetaWeblog" );
00060 }
00061
00062 void MetaWeblog::listCategories()
00063 {
00064 Q_D( MetaWeblog );
00065 kDebug() << "Fetching List of Categories...";
00066 QList<QVariant> args( d->defaultArgs( blogId() ) );
00067 d->mXmlRpcClient->call(
00068 "metaWeblog.getCategories", args,
00069 this, SLOT(slotListCategories(const QList<QVariant>&, const QVariant&)),
00070 this, SLOT(slotError(int, const QString&, const QVariant&)) );
00071 }
00072
00073 void MetaWeblog::createMedia( KBlog::BlogMedia *media )
00074 {
00075 Q_D( MetaWeblog );
00076 if ( !media ) {
00077 kError() << "MetaWeblog::createMedia: media is a null pointer";
00078 emit error ( Other, i18n( "Media is a null pointer." ) );
00079 return;
00080 }
00081 unsigned int i = d->mCallMediaCounter++;
00082 d->mCallMediaMap[ i ] = media;
00083 kDebug() << "MetaWeblog::createMedia: name="<< media->name();
00084 QList<QVariant> args( d->defaultArgs( blogId() ) );
00085 QMap<QString, QVariant> map;
00086 QList<QVariant> list;
00087 map["name"] = media->name();
00088 map["type"] = media->mimetype();
00089 map["bits"] = media->data();
00090 args << map;
00091 d->mXmlRpcClient->call(
00092 "metaWeblog.newMediaObject", args,
00093 this, SLOT(slotCreateMedia(const QList<QVariant>&,const QVariant&)),
00094 this, SLOT(slotError(int,const QString&,const QVariant&)),
00095 QVariant( i ) );
00096
00097 }
00098
00099 MetaWeblogPrivate::MetaWeblogPrivate()
00100 {
00101 kDebug();
00102 mCallMediaCounter=1;
00103 mCatLoaded=false;
00104 }
00105
00106 MetaWeblogPrivate::~MetaWeblogPrivate()
00107 {
00108 kDebug();
00109 }
00110
00111 QList<QVariant> MetaWeblogPrivate::defaultArgs( const QString &id )
00112 {
00113 Q_Q( MetaWeblog );
00114 QList<QVariant> args;
00115 if( !id.isEmpty() ) {
00116 args << QVariant( id );
00117 }
00118 args << QVariant( q->username() )
00119 << QVariant( q->password() );
00120 return args;
00121 }
00122
00123 void MetaWeblogPrivate::loadCategories()
00124 {
00125 kDebug();
00126
00127 if ( mCatLoaded ) {
00128 return;
00129 }
00130 mCatLoaded = true;
00131
00132 if ( mUrl.isEmpty() || mBlogId.isEmpty() || mUsername.isEmpty() ) {
00133 kDebug() << "We need at least url, blogId and the username to create a unique filename.";
00134 return;
00135 }
00136
00137 QString filename = "kblog/" + mUrl.host() + '_' + mBlogId + '_' + mUsername;
00138 filename = KStandardDirs::locateLocal( "data", filename, true );
00139
00140 QFile file( filename );
00141 if ( !file.open( QIODevice::ReadOnly ) ) {
00142 kDebug() << "Cannot open cached categories file: " << filename;
00143 return;
00144 }
00145
00146 QDataStream stream( &file );
00147 stream >> mCategoriesList;
00148 file.close();
00149 }
00150
00151 void MetaWeblogPrivate::saveCategories()
00152 {
00153 kDebug();
00154 if ( mUrl.isEmpty() || mBlogId.isEmpty() || mUsername.isEmpty() ) {
00155 kDebug() << "We need at least url, blogId and the username to create a unique filename.";
00156 return;
00157 }
00158
00159 QString filename = "kblog/" + mUrl.host() + '_' + mBlogId + '_' + mUsername;
00160 filename = KStandardDirs::locateLocal( "data", filename, true );
00161
00162 QFile file( filename );
00163 if ( !file.open( QIODevice::WriteOnly ) ) {
00164 kDebug() << "Cannot open cached categories file: " << filename;
00165 return;
00166 }
00167
00168 QDataStream stream( &file );
00169 stream << mCategoriesList;
00170 file.close();
00171 }
00172
00173
00174 void MetaWeblogPrivate::slotListCategories( const QList<QVariant> &result,
00175 const QVariant &id )
00176 {
00177 Q_Q( MetaWeblog );
00178 Q_UNUSED( id );
00179
00180 kDebug() << "MetaWeblogPrivate::slotListCategories";
00181 kDebug() << "TOP:" << result[0].typeName();
00182 if ( result[0].type() != QVariant::Map &&
00183 result[0].type() != QVariant::List ) {
00184
00185
00186 kError() << "Could not list categories out of the result from the server.";
00187 emit q->error( MetaWeblog::ParsingError,
00188 i18n( "Could not list categories out of the result "
00189 "from the server." ) );
00190 } else {
00191 if ( result[0].type() == QVariant::Map ) {
00192 const QMap<QString, QVariant> serverMap = result[0].toMap();
00193 const QList<QString> serverKeys = serverMap.keys();
00194
00195 QList<QString>::ConstIterator it = serverKeys.begin();
00196 QList<QString>::ConstIterator end = serverKeys.end();
00197 for ( ; it != end; ++it ) {
00198 kDebug() << "MIDDLE:" << ( *it );
00199 QMap<QString,QString> category;
00200 const QMap<QString, QVariant> serverCategory = serverMap[*it].toMap();
00201 category["name"]= ( *it );
00202 category["description"] = serverCategory[ "description" ].toString();
00203 category["htmlUrl"] = serverCategory[ "htmlUrl" ].toString();
00204 category["rssUrl"] = serverCategory[ "rssUrl" ].toString();
00205 category["categoryId"] = serverCategory[ "categoryId" ].toString();
00206 category["parentId"] = serverCategory[ "parentId" ].toString();
00207 mCategoriesList.append( category );
00208 }
00209 kDebug() << "Emitting listedCategories";
00210 emit q->listedCategories( mCategoriesList );
00211 }
00212 }
00213 if ( result[0].type() == QVariant::List ) {
00214
00215
00216 const QList<QVariant> serverList = result[0].toList();
00217 QList<QVariant>::ConstIterator it = serverList.begin();
00218 QList<QVariant>::ConstIterator end = serverList.end();
00219 for ( ; it != end; ++it ) {
00220 kDebug() << "MIDDLE:" << ( *it ).typeName();
00221 QMap<QString,QString> category;
00222 const QMap<QString, QVariant> serverCategory = ( *it ).toMap();
00223 category[ "name" ] = serverCategory["categoryName"].toString();
00224 category["description"] = serverCategory[ "description" ].toString();
00225 category["htmlUrl"] = serverCategory[ "htmlUrl" ].toString();
00226 category["rssUrl"] = serverCategory[ "rssUrl" ].toString();
00227 category["categoryId"] = serverCategory[ "categoryId" ].toString();
00228 category["parentId"] = serverCategory[ "parentId" ].toString();
00229 mCategoriesList.append( category );
00230 }
00231 kDebug() << "Emitting listedCategories()";
00232 emit q->listedCategories( mCategoriesList );
00233 }
00234 saveCategories();
00235 }
00236
00237 void MetaWeblogPrivate::slotCreateMedia( const QList<QVariant> &result,
00238 const QVariant &id )
00239 {
00240 Q_Q( MetaWeblog );
00241
00242 KBlog::BlogMedia *media = mCallMediaMap[ id.toInt() ];
00243 mCallMediaMap.remove( id.toInt() );
00244
00245 kDebug() << "MetaWeblogPrivate::slotCreateMedia, no error!";
00246 kDebug() << "TOP:" << result[0].typeName();
00247 if ( result[0].type() != 8 ) {
00248 kError() << "Could not read the result, not a map.";
00249 emit q->errorMedia( MetaWeblog::ParsingError,
00250 i18n( "Could not read the result, not a map." ),
00251 media );
00252 return;
00253 }
00254 const QMap<QString, QVariant> resultStruct = result[0].toMap();
00255 const QString url = resultStruct["url"].toString();
00256 kDebug() << "MetaWeblog::slotCreateMedia url=" << url;
00257
00258 if ( !url.isEmpty() ) {
00259 media->setUrl( KUrl( url ) );
00260 media->setStatus( BlogMedia::Created );
00261 kDebug() << "Emitting createdMedia( url=" << url << ");";
00262 emit q->createdMedia( media );
00263 }
00264 }
00265
00266 bool MetaWeblogPrivate::readPostFromMap( BlogPost *post,
00267 const QMap<QString, QVariant> &postInfo )
00268 {
00269
00270 kDebug() << "readPostFromMap()";
00271 if ( !post ) {
00272 return false;
00273 }
00274 QStringList mapkeys = postInfo.keys();
00275 kDebug() << endl << "Keys:" << mapkeys.join( ", " );
00276 kDebug() << endl;
00277
00278 KDateTime dt =
00279 KDateTime( postInfo["dateCreated"].toDateTime(), KDateTime::UTC );
00280 if ( dt.isValid() && !dt.isNull() ) {
00281 post->setCreationDateTime( dt.toLocalZone() );
00282 }
00283
00284 dt =
00285 KDateTime( postInfo["lastModified"].toDateTime(), KDateTime::UTC );
00286 if ( dt.isValid() && !dt.isNull() ) {
00287 post->setModificationDateTime( dt.toLocalZone() );
00288 }
00289
00290 post->setPostId( postInfo["postid"].toString().isEmpty() ? postInfo["postId"].toString() :
00291 postInfo["postid"].toString() );
00292
00293 QString title( postInfo["title"].toString() );
00294 QString description( postInfo["description"].toString() );
00295 QStringList categories( postInfo["categories"].toStringList() );
00296
00297 post->setTitle( title );
00298 post->setContent( description );
00299 if ( !categories.isEmpty() ){
00300 kDebug() << "Categories:" << categories;
00301 post->setCategories( categories );
00302 }
00303 return true;
00304 }
00305
00306 bool MetaWeblogPrivate::readArgsFromPost( QList<QVariant> *args, const BlogPost &post )
00307 {
00308 if ( !args ) {
00309 return false;
00310 }
00311 QMap<QString, QVariant> map;
00312 map["categories"] = post.categories();
00313 map["description"] = post.content();
00314 map["title"] = post.title();
00315 map["lastModified"] = post.modificationDateTime().dateTime().toUTC();
00316 map["dateCreated"] = post.creationDateTime().dateTime().toUTC();
00317 *args << map;
00318 *args << QVariant( !post.isPrivate() );
00319 return true;
00320 }
00321
00322 QString MetaWeblogPrivate::getCallFromFunction( FunctionToCall type )
00323 {
00324 switch ( type ) {
00325 case GetRecentPosts: return "metaWeblog.getRecentPosts";
00326 case CreatePost: return "metaWeblog.newPost";
00327 case ModifyPost: return "metaWeblog.editPost";
00328 case FetchPost: return "metaWeblog.getPost";
00329 default: return QString();
00330 }
00331 }
00332 #include "metaweblog.moc"