25 #include "blogger1_p.h"
28 #include <kxmlrpcclient/client.h>
36 #include <QStringList>
38 using namespace KBlog;
41 :
Blog( server, *new Blogger1Private, parent )
48 :
Blog( server, dd, parent )
61 return QLatin1String(
"Blogger 1.0" );
68 delete d->mXmlRpcClient;
69 d->mXmlRpcClient =
new KXmlRpc::Client( server );
70 d->mXmlRpcClient->setUserAgent(
userAgent() );
76 kDebug() <<
"Fetch user's info...";
77 QList<QVariant> args( d->blogger1Args() );
78 d->mXmlRpcClient->call(
79 "blogger.getUserInfo", args,
80 this, SLOT(slotFetchUserInfo(QList<QVariant>,QVariant)),
81 this, SLOT(slotError(
int,QString,QVariant)) );
87 kDebug() <<
"Fetch List of Blogs...";
88 QList<QVariant> args( d->blogger1Args() );
89 d->mXmlRpcClient->call(
90 "blogger.getUsersBlogs", args,
91 this, SLOT(slotListBlogs(QList<QVariant>,QVariant)),
92 this, SLOT(slotError(
int,QString,QVariant)) );
98 kDebug() <<
"Fetching List of Posts...";
99 QList<QVariant> args( d->defaultArgs(
blogId() ) );
100 args << QVariant( number );
101 d->mXmlRpcClient->call(
102 d->getCallFromFunction( Blogger1Private::GetRecentPosts ), args,
103 this, SLOT(slotListRecentPosts(QList<QVariant>,QVariant)),
104 this, SLOT(slotError(
int,QString,QVariant)),
105 QVariant( number ) );
111 kError() <<
"Blogger1::modifyPost: post is null pointer";
116 kDebug() <<
"Fetching Post with url" << post->
postId();
117 QList<QVariant> args( d->defaultArgs( post->
postId() ) );
118 unsigned int i= d->mCallCounter++;
119 d->mCallMap[ i ] = post;
120 d->mXmlRpcClient->call(
121 d->getCallFromFunction( Blogger1Private::FetchPost ), args,
122 this, SLOT(slotFetchPost(QList<QVariant>,QVariant)),
123 this, SLOT(slotError(
int,QString,QVariant)),
132 kError() <<
"Blogger1::modifyPost: post is null pointer";
136 kDebug() <<
"Uploading Post with postId" << post->
postId();
137 unsigned int i= d->mCallCounter++;
138 d->mCallMap[ i ] = post;
139 QList<QVariant> args( d->defaultArgs( post->
postId() ) );
140 d->readArgsFromPost( &args, *post );
141 d->mXmlRpcClient->call(
142 d->getCallFromFunction( Blogger1Private::ModifyPost ), args,
143 this, SLOT(slotModifyPost(QList<QVariant>,QVariant)),
144 this, SLOT(slotError(
int,QString,QVariant)),
153 kError() <<
"Blogger1::createPost: post is null pointer";
157 unsigned int i= d->mCallCounter++;
158 d->mCallMap[ i ] = post;
159 kDebug() <<
"Creating new Post with blogid" <<
blogId();
160 QList<QVariant> args( d->defaultArgs(
blogId() ) );
161 d->readArgsFromPost( &args, *post );
162 d->mXmlRpcClient->call(
163 d->getCallFromFunction( Blogger1Private::CreatePost ), args,
164 this, SLOT(slotCreatePost(QList<QVariant>,QVariant)),
165 this, SLOT(slotError(
int,QString,QVariant)),
174 kError() <<
"Blogger1::removePost: post is null pointer";
178 unsigned int i = d->mCallCounter++;
179 d->mCallMap[ i ] = post;
180 kDebug() <<
"Blogger1::removePost: postId=" << post->
postId();
181 QList<QVariant> args( d->blogger1Args( post->
postId() ) );
182 args << QVariant(
true );
183 d->mXmlRpcClient->call(
184 "blogger.deletePost", args,
185 this, SLOT(slotRemovePost(QList<QVariant>,QVariant)),
186 this, SLOT(slotError(
int,QString,QVariant)),
190 Blogger1Private::Blogger1Private() :
197 Blogger1Private::~Blogger1Private()
200 delete mXmlRpcClient;
203 QList<QVariant> Blogger1Private::defaultArgs(
const QString &
id )
207 QList<QVariant> args;
208 args << QVariant( QString(
"0123456789ABCDEF" ) );
209 if ( !
id.isEmpty() ) {
210 args << QVariant(
id );
212 args << QVariant( q->username() )
213 << QVariant( q->password() );
218 QList<QVariant> Blogger1Private::blogger1Args(
const QString &
id )
222 QList<QVariant> args;
223 args << QVariant( QString(
"0123456789ABCDEF" ) );
224 if ( !
id.isEmpty() ) {
225 args << QVariant(
id );
227 args << QVariant( q->username() )
228 << QVariant( q->password() );
232 void Blogger1Private::slotFetchUserInfo(
const QList<QVariant> &result,
const QVariant &
id )
238 kDebug() <<
"TOP:" << result[0].typeName();
239 QMap<QString,QString> userInfo;
240 if ( result[0].type() != QVariant::Map ) {
241 kError() <<
"Could not fetch user's info out of the result from the server,"
244 i18n(
"Could not fetch user's info out of the result "
245 "from the server, not a map." ) );
248 const QMap<QString,QVariant> resultMap = result[0].toMap();
249 userInfo[
"nickname"]=resultMap[
"nickname"].toString();
250 userInfo[
"userid"]=resultMap[
"userid"].toString();
251 userInfo[
"url"]=resultMap[
"url"].toString();
252 userInfo[
"email"]=resultMap[
"email"].toString();
253 userInfo[
"lastname"]=resultMap[
"lastname"].toString();
254 userInfo[
"firstname"]=resultMap[
"firstname"].toString();
256 emit q->fetchedUserInfo( userInfo );
259 void Blogger1Private::slotListBlogs(
const QList<QVariant> &result,
const QVariant &
id )
265 kDebug() <<
"TOP:" << result[0].typeName();
266 QList<QMap<QString,QString> > blogsList;
267 if ( result[0].type() != QVariant::List ) {
268 kError() <<
"Could not fetch blogs out of the result from the server,"
271 i18n(
"Could not fetch blogs out of the result "
272 "from the server, not a list." ) );
275 const QList<QVariant> posts = result[0].toList();
276 QList<QVariant>::ConstIterator it = posts.begin();
277 QList<QVariant>::ConstIterator end = posts.end();
278 for ( ; it != end; ++it ) {
279 kDebug() <<
"MIDDLE:" << ( *it ).typeName();
280 const QMap<QString, QVariant> postInfo = ( *it ).toMap();
281 QMap<QString,QString> blogInfo;
282 blogInfo[
"id" ] = postInfo[
"blogid"].toString();
283 blogInfo[
"url" ] = postInfo[
"url"].toString();
284 blogInfo[
"apiUrl" ] = postInfo[
"xmlrpc"].toString();
285 blogInfo[
"title" ] = postInfo[
"blogName"].toString();
286 kDebug() <<
"Blog information retrieved: ID =" << blogInfo[
"id"]
287 <<
", Name =" << blogInfo[
"title"];
288 blogsList << blogInfo;
290 emit q->listedBlogs( blogsList );
293 void Blogger1Private::slotListRecentPosts(
const QList<QVariant> &result,
const QVariant &
id )
296 int count =
id.toInt();
300 kDebug() <<
"TOP:" << result[0].typeName();
302 QList <BlogPost> fetchedPostList;
304 if ( result[0].type() != QVariant::List ) {
305 kError() <<
"Could not fetch list of posts out of the"
306 <<
"result from the server, not a list.";
308 i18n(
"Could not fetch list of posts out of the result "
309 "from the server, not a list." ) );
312 const QList<QVariant> postReceived = result[0].toList();
313 QList<QVariant>::ConstIterator it = postReceived.begin();
314 QList<QVariant>::ConstIterator end = postReceived.end();
315 for ( ; it != end; ++it ) {
317 kDebug() <<
"MIDDLE:" << ( *it ).typeName();
318 const QMap<QString, QVariant> postInfo = ( *it ).toMap();
319 if ( readPostFromMap( &post, postInfo ) ) {
320 kDebug() <<
"Post with ID:"
322 <<
"appended in fetchedPostList";
324 fetchedPostList.append( post );
326 kError() <<
"readPostFromMap failed!";
329 if ( --count == 0 ) {
333 kDebug() <<
"Emitting listRecentPostsFinished()";
334 emit q->listedRecentPosts( fetchedPostList );
337 void Blogger1Private::slotFetchPost(
const QList<QVariant> &result,
const QVariant &
id )
343 mCallMap.remove(
id.toInt() );
348 kDebug () <<
"TOP:" << result[0].typeName();
349 if ( result[0].type() == QVariant::Map &&
350 readPostFromMap( post, result[0].toMap() ) ) {
351 kDebug() <<
"Emitting fetchedPost()";
353 emit q->fetchedPost( post );
355 kError() <<
"Could not fetch post out of the result from the server.";
356 post->
setError( i18n(
"Could not fetch post out of the result from the server." ) );
359 i18n(
"Could not fetch post out of the result from the server." ), post );
363 void Blogger1Private::slotCreatePost(
const QList<QVariant> &result,
const QVariant &
id )
367 mCallMap.remove(
id.toInt() );
373 kDebug () <<
"TOP:" << result[0].typeName();
374 if ( result[0].type() != QVariant::String &&
375 result[0].type() != QVariant::Int ) {
376 kError() <<
"Could not read the postId, not a string or an integer.";
378 i18n(
"Could not read the postId, not a string or an integer." ),
383 if ( result[0].type() == QVariant::String ) {
384 serverID = result[0].toString();
386 if ( result[0].type() == QVariant::Int ) {
387 serverID = QString(
"%1" ).arg( result[0].toInt() );
391 kDebug() <<
"emitting createdPost()"
392 <<
"for title: \"" << post->
title()
393 <<
"\" server id: " << serverID;
394 emit q->createdPost( post );
397 void Blogger1Private::slotModifyPost(
const QList<QVariant> &result,
const QVariant &
id )
401 mCallMap.remove(
id.toInt() );
407 kDebug() <<
"TOP:" << result[0].typeName();
408 if ( result[0].type() != QVariant::Bool &&
409 result[0].type() != QVariant::Int ) {
410 kError() <<
"Could not read the result, not a boolean.";
412 i18n(
"Could not read the result, not a boolean." ),
417 kDebug() <<
"emitting modifiedPost() for title: \""
418 << post->
title() <<
"\"";
419 emit q->modifiedPost( post );
422 void Blogger1Private::slotRemovePost(
const QList<QVariant> &result,
const QVariant &
id )
426 mCallMap.remove(
id.toInt() );
428 kDebug() <<
"slotRemovePost";
432 kDebug() <<
"TOP:" << result[0].typeName();
433 if ( result[0].type() != QVariant::Bool &&
434 result[0].type() != QVariant::Int ) {
435 kError() <<
"Could not read the result, not a boolean.";
437 i18n(
"Could not read the result, not a boolean." ),
442 kDebug() <<
"emitting removedPost()";
443 emit q->removedPost( post );
446 void Blogger1Private::slotError(
int number,
447 const QString &errorString,
452 kDebug() <<
"An error occurred: " << errorString;
453 BlogPost *post = mCallMap[
id.toInt() ];
461 bool Blogger1Private::readPostFromMap(
462 BlogPost *post,
const QMap<QString, QVariant> &postInfo )
468 QStringList mapkeys = postInfo.keys();
469 kDebug() << endl <<
"Keys:" << mapkeys.join(
", " );
472 KDateTime dt( postInfo[
"dateCreated"].toDateTime(), KDateTime::UTC );
473 if ( dt.isValid() && !dt.isNull() ) {
476 dt = KDateTime ( postInfo[
"lastModified"].toDateTime(), KDateTime::UTC );
477 if ( dt.isValid() && !dt.isNull() ) {
480 post->
setPostId( postInfo[
"postid"].toString().isEmpty() ? postInfo[
"postId"].toString() :
481 postInfo[
"postid"].toString() );
483 QString title( postInfo[
"title"].toString() );
484 QString description( postInfo[
"description"].toString() );
486 if ( postInfo[
"content"].type() == QVariant::ByteArray ) {
487 QByteArray tmpContent = postInfo[
"content"].toByteArray();
488 contents = QString::fromUtf8( tmpContent.data(), tmpContent.size() );
490 contents = postInfo[
"content"].toString();
492 QStringList category;
495 QRegExp titleMatch = QRegExp(
"<title>([^<]*)</title>" );
496 QRegExp categoryMatch = QRegExp(
"<category>([^<]*)</category>" );
497 if ( contents.indexOf( titleMatch ) != -1 ) {
499 title = titleMatch.cap( 1 );
501 if ( contents.indexOf( categoryMatch ) != -1 ) {
503 category = categoryMatch.capturedTexts();
505 contents.remove( titleMatch );
506 contents.remove( categoryMatch );
514 bool Blogger1Private::readArgsFromPost( QList<QVariant> *args,
const BlogPost &post )
520 QString content =
"<title>" + post.
title() +
"</title>";
521 QStringList::const_iterator it;
522 for ( it = categories.constBegin(); it != categories.constEnd(); ++it ) {
523 content +=
"<category>" + *it +
"</category>";
526 *args << QVariant( content );
531 QString Blogger1Private::getCallFromFunction( FunctionToCall type )
534 case GetRecentPosts:
return "blogger.getRecentPosts";
535 case CreatePost:
return "blogger.newPost";
536 case ModifyPost:
return "blogger.editPost";
537 case FetchPost:
return "blogger.getPost";
538 default:
return QString();
542 #include "moc_blogger1.cpp"
QString title() const
Returns the title.
virtual void setUrl(const KUrl &url)
Sets the URL for the blog's XML-RPC interface.
void modifyPost(KBlog::BlogPost *post)
Modify a post on server.
Status of a successfully fetched post.
virtual void fetchUserInfo()
Get information about the user from the blog.
Blogger1(const KUrl &server, QObject *parent=0)
Create an object for Blogger 1.0.
virtual ~Blogger1()
Destroy the object.
Status of a successfully created post.
void setUrl(const KUrl &server)
Set the Url of the server.
void listRecentPosts(int number)
List recent posts on the server.
This file is part of the for accessing Blog Servers and defines the Blogger1 class.
void setTitle(const QString &title)
Sets the title.
void setPostId(const QString &postId)
Sets the post id value.
void setCreationDateTime(const KDateTime &datetime)
Sets the creation time.
void setContent(const QString &content)
Sets the content.
QString error() const
Returns the last error.
Status when an error on the server side occurred.
void setModificationDateTime(const KDateTime &datetime)
Sets the modification time.
QString blogId() const
Returns the unique ID for the specific blog on the server.
void setStatus(Status status)
Sets the status.
void removePost(KBlog::BlogPost *post)
Remove a post from the server.
Status of a successfully modified post.
QString content() const
Returns the content.
void fetchPost(KBlog::BlogPost *post)
Fetch a post from the server.
A class that represents a blog post on the server.
A class that can be used for access to Blogger 1.0 blogs.
void setCategories(const QStringList &categories)
Sets the categories.
QString interfaceName() const
Returns the of the inherited object.
void createPost(KBlog::BlogPost *post)
Create a new post on server.
QStringList categories() const
Returns the categories.
A class that provides methods to call functions on a supported blog web application.
Status of a successfully removed post.
virtual void listBlogs()
List the blogs available for this authentication on the server.
bool isPrivate() const
Returns if the post is published or not.
QString postId() const
Returns the postId.
QString userAgent() const
Returns the HTTP user agent string used to make the HTTP requests.
An error in the XML-RPC client.
void setError(const QString &error)
Sets the error.