22 #include <kblog/blogpost.h>
23 #include <kblog/blogcomment.h>
27 #include <KLocalizedString>
29 #include <LibKGAPI2/Blogger/Blog>
30 #include <LibKGAPI2/Blogger/BlogFetchJob>
31 #include <LibKGAPI2/Blogger/Post>
32 #include <LibKGAPI2/Blogger/PostCreateJob>
33 #include <LibKGAPI2/Blogger/PostDeleteJob>
34 #include <LibKGAPI2/Blogger/PostFetchJob>
35 #include <LibKGAPI2/Blogger/PostModifyJob>
36 #include <LibKGAPI2/Blogger/Comment>
37 #include <LibKGAPI2/Blogger/CommentFetchJob>
38 #include <LibKGAPI2/Account>
39 #include <LibKGAPI2/AuthJob>
41 Q_DECLARE_METATYPE(KBlog::BlogPost*)
42 Q_DECLARE_METATYPE(KGAPI2::Job*)
45 #define KBLOGPOST_PROPERTY "KBlogPostProperty"
46 #define JOB_PROPERTY "JobProperty"
54 BloggerPrivate(
Blogger *parent);
55 virtual ~BloggerPrivate();
57 void updateKBlogPost(KBlog::BlogPost *kblog,
const KGAPI2::Blogger::PostPtr &postPtr);
58 KBlog::BlogPost KGAPIPostToKBlogPost(
const KGAPI2::Blogger::PostPtr &postPtr);
60 KGAPI2::Blogger::PostPtr KBlogPostToKGAPI(
const BlogPost *
const kblog);
62 KBlogInfo KGAPIBlogToKBlogBlog(
const KGAPI2::Blogger::BlogPtr &blogPtr);
65 KBlog::BlogComment KGAPICommentToKBlogComment(
const KGAPI2::Blogger::CommentPtr &commentPtr);
68 bool handleError(KGAPI2::Job *job);
70 void _k_onAuthenticateFinished(KGAPI2::Job *job);
71 void _k_onListBlogsFinished(KGAPI2::Job *job);
72 void _k_onListRecentPostsFinished(KGAPI2::Job *job);
73 void _k_onFetchPostFinished(KGAPI2::Job *job);
74 void _k_onCreatePostFinished(KGAPI2::Job *job);
75 void _k_onRemovePostFinished(KGAPI2::Job *job);
76 void _k_onModifyPostFinished(KGAPI2::Job *job);
77 void _k_onListCommentsFinished(KGAPI2::Job *job);
81 KGAPI2::AccountPtr account;
90 using namespace KBlog;
92 BloggerPrivate::BloggerPrivate(
Blogger *parent)
98 BloggerPrivate::~BloggerPrivate()
102 void BloggerPrivate::updateKBlogPost(BlogPost *kblog,
const KGAPI2::Blogger::PostPtr &postPtr)
104 kblog->setPostId(postPtr->id());
105 kblog->setTitle(postPtr->title());
106 kblog->setContent(postPtr->content());
107 kblog->setTags(postPtr->labels());
108 kblog->setCreationDateTime(postPtr->published());
109 kblog->setModificationDateTime(postPtr->updated());
110 kblog->setLink(postPtr->url());
111 kblog->setPrivate(postPtr->status() ==
QLatin1String(
"DRAFT"));
115 KGAPI2::Blogger::PostPtr BloggerPrivate::KBlogPostToKGAPI(
const BlogPost *
const kblog)
119 KGAPI2::Blogger::PostPtr postPtr(
new KGAPI2::Blogger::Post);
120 postPtr->setId(kblog->postId());
121 postPtr->setBlogId(q->blogId());
122 postPtr->setTitle(kblog->title());
123 postPtr->setContent(kblog->content());
124 postPtr->setLabels(kblog->tags());
125 postPtr->setPublished(kblog->creationDateTime());
126 postPtr->setUpdated(kblog->modificationDateTime());
127 postPtr->setUrl(kblog->link());
131 BlogPost BloggerPrivate::KGAPIPostToKBlogPost(
const KGAPI2::Blogger::PostPtr &postPtr)
134 updateKBlogPost(&kblog, postPtr);
138 QList<BlogPost> BloggerPrivate::KGAPIPostsToKBlogPosts(
const KGAPI2::ObjectsList &posts)
141 Q_FOREACH (
const KGAPI2::ObjectPtr &obj, posts) {
142 blogPosts << KGAPIPostToKBlogPost(obj.dynamicCast<KGAPI2::Blogger::Post>());
148 KBlogInfo BloggerPrivate::KGAPIBlogToKBlogBlog(
const KGAPI2::Blogger::BlogPtr &blogPtr)
158 QList<KBlogInfo> BloggerPrivate::KGAPIBlogsToKBlogBlogs(
const KGAPI2::ObjectsList &blogs)
161 Q_FOREACH (
const KGAPI2::ObjectPtr &obj, blogs) {
162 kblogInfos << KGAPIBlogToKBlogBlog(obj.dynamicCast<KGAPI2::Blogger::Blog>());
167 BlogComment BloggerPrivate::KGAPICommentToKBlogComment(
const KGAPI2::Blogger::CommentPtr &commentPtr)
169 BlogComment kblogComment;
170 kblogComment.setCommentId(commentPtr->id());
171 kblogComment.setContent(commentPtr->content());
172 kblogComment.setCreationDateTime(commentPtr->published());
173 kblogComment.setModificationDateTime(commentPtr->updated());
174 kblogComment.setName(commentPtr->authorName());
178 QList<BlogComment> BloggerPrivate::KGAPICommentsToKBlogComments(
const KGAPI2::ObjectsList &comments)
181 Q_FOREACH (
const KGAPI2::ObjectPtr &obj, comments) {
182 kblogComments << KGAPICommentToKBlogComment(obj.dynamicCast<KGAPI2::Blogger::Comment>());
184 return kblogComments;
187 bool BloggerPrivate::handleError(KGAPI2::Job *job)
197 KBlog::Blog::ErrorType errCode = Blog::Other;
198 switch (job->error()) {
199 case KGAPI2::Unauthorized: {
200 KGAPI2::AuthJob *authJob =
new KGAPI2::AuthJob(account, apiKey, secretKey, q);
202 q->connect(authJob, SIGNAL(finished(KGAPI2::Job*)),
203 q, SLOT(_k_onAuthenticateFinished(KGAPI2::Job*)));
206 case KGAPI2::AuthCancelled:
207 case KGAPI2::AuthError:
208 errCode = Blog::AuthenticationError;
211 case KGAPI2::BadRequest:
212 errCode = Blog::XmlRpc;
216 case KGAPI2::NotFound:
220 errCode = Blog::Other;
225 Q_EMIT q->errorPost(errCode, job->errorString(), post);
227 Q_EMIT q->error(errCode, job->errorString());
237 Blogger::Blogger(
const KUrl &server,
QObject *parent)
238 : Blog(server, *new BloggerPrivate(this), parent)
263 d->secretKey = secretKey;
270 KGAPI2::AccountPtr account;
271 kDebug() << authData;
274 scopes << KGAPI2::Account::bloggerScopeUrl();
275 account = KGAPI2::AccountPtr(
new KGAPI2::Account(authData[
QLatin1String(
"account")],
279 d->account = account;
281 account = KGAPI2::AccountPtr(
new KGAPI2::Account);
282 account->addScope(KGAPI2::Account::bloggerScopeUrl());
283 KGAPI2::AuthJob *authJob =
new KGAPI2::AuthJob(account, d->apiKey, d->secretKey,
this);
284 if (account->accessToken().isEmpty()) {
285 authJob->setUsername(username());
286 authJob->setPassword(password());
288 connect(authJob, SIGNAL(finished(KGAPI2::Job*)),
289 this, SLOT(_k_onAuthenticateFinished(KGAPI2::Job*)));
293 void BloggerPrivate::_k_onAuthenticateFinished(KGAPI2::Job *job)
296 if (!handleError(job)) {
300 KGAPI2::AuthJob *authJob = qobject_cast<KGAPI2::AuthJob*>(job);
301 account = authJob->account();
305 authData[
QLatin1String(
"accessToken")] = account->accessToken();
306 authData[
QLatin1String(
"refreshToken")] = account->refreshToken();
308 Q_EMIT q->authenticated(authData);
311 KGAPI2::Job *originalJob = authJob->property(
JOB_PROPERTY).
value<KGAPI2::Job*>();
313 originalJob->restart();
323 KGAPI2::Blogger::BlogFetchJob *fetchJob
325 KGAPI2::Blogger::BlogFetchJob::FetchByUserId,
328 connect(fetchJob, SIGNAL(finished(KGAPI2::Job*)),
329 this, SLOT(_k_onListBlogsFinished(KGAPI2::Job*)));
332 void BloggerPrivate::_k_onListBlogsFinished(KGAPI2::Job *job)
336 if (!handleError(job)) {
341 KGAPI2::FetchJob *fetchJob = qobject_cast<KGAPI2::FetchJob*>(job);
343 Q_EMIT q->listedBlogs(blogs);
351 KGAPI2::Blogger::PostFetchJob *fetchJob
352 =
new KGAPI2::Blogger::PostFetchJob(blogId(), d->account,
this);
353 fetchJob->setMaxResults(number);
354 connect(fetchJob, SIGNAL(finished(KGAPI2::Job*)),
355 this, SLOT(_k_onListRecentPostsFinished(KGAPI2::Job*)));
358 void BloggerPrivate::_k_onListRecentPostsFinished(KGAPI2::Job *job)
362 if (!handleError(job)) {
367 KGAPI2::FetchJob *fetchJob = qobject_cast<KGAPI2::FetchJob*>(job);
370 for (iter = posts.begin(); iter != endIter; ++iter) {
371 (*iter).setStatus(BlogPost::Fetched);
373 Q_EMIT q->listedRecentPosts(posts);
381 KGAPI2::Blogger::PostFetchJob *fetchJob
382 =
new KGAPI2::Blogger::PostFetchJob(blogId(), post->postId(), d->account,
this);
384 connect(fetchJob, SIGNAL(finished(KGAPI2::Job*)),
385 this, SLOT(_k_onFetchPostFinished(KGAPI2::Job*)));
388 void BloggerPrivate::_k_onFetchPostFinished(KGAPI2::Job *job)
392 if (!handleError(job)) {
397 KGAPI2::FetchJob *fetchJob = qobject_cast<KGAPI2::FetchJob*>(job);
399 const KGAPI2::ObjectsList items = fetchJob->items();
400 if (items.count() != 1) {
401 Q_EMIT q->errorPost(Blog::Other, i18n(
"Blog post not found"), kblog);
405 updateKBlogPost(kblog, items.first().dynamicCast<KGAPI2::Blogger::Post>());
406 kblog->setStatus(BlogPost::Fetched);
407 Q_EMIT q->fetchedPost(kblog);
415 KGAPI2::Blogger::PostDeleteJob *deleteJob
416 =
new KGAPI2::Blogger::PostDeleteJob(blogId(), post->postId(), d->account,
this);
418 connect(deleteJob, SIGNAL(finished(KGAPI2::Job*)),
419 this, SLOT(_k_onRemovePostFinished(KGAPI2::Job*)));
422 void BloggerPrivate::_k_onRemovePostFinished(KGAPI2::Job *job)
426 if (!handleError(job)) {
432 kblog->setStatus(BlogPost::Removed);
433 Q_EMIT q->removedPost(kblog);
442 KGAPI2::Blogger::PostPtr postPtr = d->KBlogPostToKGAPI(post);
443 KGAPI2::Blogger::PostCreateJob *createJob
444 =
new KGAPI2::Blogger::PostCreateJob(postPtr, post->isPrivate(), d->account,
this);
446 connect(createJob, SIGNAL(finished(KGAPI2::Job*)),
447 this, SLOT(_k_onCreatePostFinished(KGAPI2::Job*)));
450 void BloggerPrivate::_k_onCreatePostFinished(KGAPI2::Job *job)
454 if (!handleError(job)) {
459 KGAPI2::CreateJob *createJob = qobject_cast<KGAPI2::CreateJob*>(job);
461 const KGAPI2::ObjectsList items = createJob->items();
462 if (items.count() != 1) {
463 Q_EMIT q->errorPost(Blog::Other, i18n(
"Failed to create new post"), kblog);
467 updateKBlogPost(kblog, items.first().dynamicCast<KGAPI2::Blogger::Post>());
468 kblog->setStatus(BlogPost::Created);
469 Q_EMIT q->createdPost(kblog);
477 KGAPI2::Blogger::PostPtr postPtr = d->KBlogPostToKGAPI(post);
478 postPtr->setPublished(KDateTime());
479 postPtr->setUpdated(KDateTime());
480 KGAPI2::Blogger::PostModifyJob *modifyJob
481 =
new KGAPI2::Blogger::PostModifyJob(postPtr, d->account,
this);
483 connect(modifyJob, SIGNAL(finished(KGAPI2::Job*)),
484 this, SLOT(_k_onModifyPostFinished(KGAPI2::Job*)));
487 void BloggerPrivate::_k_onModifyPostFinished(KGAPI2::Job *job)
491 if (!handleError(job)) {
496 KGAPI2::ModifyJob *modifyJob = qobject_cast<KGAPI2::ModifyJob*>(job);
498 const KGAPI2::ObjectsList items = modifyJob->items();
499 if (items.count() != 1) {
500 Q_EMIT q->errorPost(Blog::Other, i18n(
"Failed to update post"), kblog);
504 updateKBlogPost(kblog, items.first().dynamicCast<KGAPI2::Blogger::Post>());
505 kblog->setStatus(BlogPost::Modified);
506 Q_EMIT q->modifiedPost(kblog);
514 KGAPI2::Blogger::CommentFetchJob *fetchJob
515 =
new KGAPI2::Blogger::CommentFetchJob(blogId(), post->postId(), d->account,
this);
517 connect(fetchJob, SIGNAL(finished(KGAPI2::Job*)),
518 this, SLOT(_k_onListCommentsFinished(KGAPI2::Job*)));
521 void BloggerPrivate::_k_onListCommentsFinished(KGAPI2::Job *job)
525 if (!handleError(job)) {
530 KGAPI2::FetchJob *fetchJob = qobject_cast<KGAPI2::FetchJob*>(job);
533 Q_EMIT q->listedComments(kblog, comments);
538 #include "moc_blogger.cpp"
void setApiKey(const QString &apiKey)
Sets Google OAuth application API key.
void createPost(KBlog::BlogPost *post)
Create a new post on server.
void removePost(KBlog::BlogPost *post)
Remove a post from the server.
void listRecentPosts(int number)
List recent posts on the server.
This file is part of the for accessing Blog Servers from the Google's Blogger and BlogPost service an...
void fetchPost(KBlog::BlogPost *post)
Fetch the Post with a specific id.
virtual ~Blogger()
Destructor.
#define KBLOGPOST_PROPERTY
QVariant fromValue(const T &value)
QString interfaceName() const
Returns name of the service.
void modifyPost(KBlog::BlogPost *post)
Modify a post on server.
void authenticate(const QMap< QString, QString > &authData=QMap< QString, QString >())
Authenticate this instance of Blogger against Google account.
A class that can be used for access to Google blogs.
void listComments(KBlog::BlogPost *post)
List the comments available for this post on the server.
void setSecretKey(const QString &secretKey)
Sets Google OAuth application secret key.
const T value(const Key &key) const
void listBlogs()
List the blogs available for this authentication on the server.