25 #include "blogger1_p.h"
28 #include <kxmlrpcclient/client.h>
32 #include <KLocalizedString>
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 QLatin1String(
"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 QLatin1String(
"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 QLatin1String(
"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( QLatin1String(
"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( QLatin1String(
"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[QLatin1String(
"nickname")]=resultMap[QLatin1String(
"nickname")].toString();
250 userInfo[QLatin1String(
"userid")]=resultMap[QLatin1String(
"userid")].toString();
251 userInfo[QLatin1String(
"url")]=resultMap[QLatin1String(
"url")].toString();
252 userInfo[QLatin1String(
"email")]=resultMap[QLatin1String(
"email")].toString();
253 userInfo[QLatin1String(
"lastname")]=resultMap[QLatin1String(
"lastname")].toString();
254 userInfo[QLatin1String(
"firstname")]=resultMap[QLatin1String(
"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[ QLatin1String(
"id") ] = postInfo[QLatin1String(
"blogid")].toString();
283 blogInfo[ QLatin1String(
"url") ] = postInfo[QLatin1String(
"url")].toString();
284 blogInfo[ QLatin1String(
"apiUrl") ] = postInfo[QLatin1String(
"xmlrpc")].toString();
285 blogInfo[ QLatin1String(
"title") ] = postInfo[QLatin1String(
"blogName")].toString();
286 kDebug() <<
"Blog information retrieved: ID =" << blogInfo[QLatin1String(
"id")]
287 <<
", Name =" << blogInfo[QLatin1String(
"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();
385 }
else if ( result[0].type() == QVariant::Int ) {
386 serverID = QString::fromLatin1(
"%1" ).arg( result[0].toInt() );
390 kDebug() <<
"emitting createdPost()"
391 <<
"for title: \"" << post->
title()
392 <<
"\" server id: " << serverID;
393 emit q->createdPost( post );
396 void Blogger1Private::slotModifyPost(
const QList<QVariant> &result,
const QVariant &
id )
400 mCallMap.remove(
id.toInt() );
406 kDebug() <<
"TOP:" << result[0].typeName();
407 if ( result[0].type() != QVariant::Bool &&
408 result[0].type() != QVariant::Int ) {
409 kError() <<
"Could not read the result, not a boolean.";
411 i18n(
"Could not read the result, not a boolean." ),
416 kDebug() <<
"emitting modifiedPost() for title: \""
417 << post->
title() <<
"\"";
418 emit q->modifiedPost( post );
421 void Blogger1Private::slotRemovePost(
const QList<QVariant> &result,
const QVariant &
id )
425 mCallMap.remove(
id.toInt() );
427 kDebug() <<
"slotRemovePost";
431 kDebug() <<
"TOP:" << result[0].typeName();
432 if ( result[0].type() != QVariant::Bool &&
433 result[0].type() != QVariant::Int ) {
434 kError() <<
"Could not read the result, not a boolean.";
436 i18n(
"Could not read the result, not a boolean." ),
441 kDebug() <<
"emitting removedPost()";
442 emit q->removedPost( post );
445 void Blogger1Private::slotError(
int number,
446 const QString &errorString,
451 kDebug() <<
"An error occurred: " << errorString;
452 BlogPost *post = mCallMap[
id.toInt() ];
460 bool Blogger1Private::readPostFromMap(
461 BlogPost *post,
const QMap<QString, QVariant> &postInfo )
467 QStringList mapkeys = postInfo.keys();
468 kDebug() << endl <<
"Keys:" << mapkeys.join( QLatin1String(
", ") );
471 KDateTime dt( postInfo[QLatin1String(
"dateCreated")].toDateTime(), KDateTime::UTC );
472 if ( dt.isValid() && !dt.isNull() ) {
475 dt = KDateTime ( postInfo[QLatin1String(
"lastModified")].toDateTime(), KDateTime::UTC );
476 if ( dt.isValid() && !dt.isNull() ) {
479 post->
setPostId( postInfo[QLatin1String(
"postid")].toString().isEmpty() ? postInfo[QLatin1String(
"postId")].toString() :
480 postInfo[QLatin1String(
"postid")].toString() );
482 QString title( postInfo[QLatin1String(
"title")].toString() );
485 if ( postInfo[QLatin1String(
"content")].type() == QVariant::ByteArray ) {
486 QByteArray tmpContent = postInfo[QLatin1String(
"content")].toByteArray();
487 contents = QString::fromUtf8( tmpContent.data(), tmpContent.size() );
489 contents = postInfo[QLatin1String(
"content")].toString();
491 QStringList category;
494 QRegExp titleMatch = QRegExp( QLatin1String(
"<title>([^<]*)</title>") );
495 QRegExp categoryMatch = QRegExp( QLatin1String(
"<category>([^<]*)</category>") );
496 if ( contents.indexOf( titleMatch ) != -1 ) {
498 title = titleMatch.cap( 1 );
500 if ( contents.indexOf( categoryMatch ) != -1 ) {
502 category = categoryMatch.capturedTexts();
504 contents.remove( titleMatch );
505 contents.remove( categoryMatch );
513 bool Blogger1Private::readArgsFromPost( QList<QVariant> *args,
const BlogPost &post )
518 const QStringList categories = post.
categories();
519 QString content = QLatin1String(
"<title>") + post.
title() + QLatin1String(
"</title>");
520 QStringList::const_iterator it;
521 QStringList::const_iterator end(categories.constEnd());
522 for ( it = categories.constBegin(); it != end; ++it ) {
523 content += QLatin1String(
"<category>") + *it + QLatin1String(
"</category>");
526 *args << QVariant( content );
531 QString Blogger1Private::getCallFromFunction( FunctionToCall type )
534 case GetRecentPosts:
return QLatin1String(
"blogger.getRecentPosts");
535 case CreatePost:
return QLatin1String(
"blogger.newPost");
536 case ModifyPost:
return QLatin1String(
"blogger.editPost");
537 case FetchPost:
return QLatin1String(
"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.