• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepim API Reference
  • KDE Home
  • Contact Us
 

blogilo

  • sources
  • kde-4.14
  • kdepim
  • blogilo
  • src
blogger.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014 Daniel Vrátil <dvratil@redhat.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  *
18  */
19 
20 #include "blogger.h"
21 #include "blog_p.h"
22 #include <kblog/blogpost.h>
23 #include <kblog/blogcomment.h>
24 
25 #include <KUrl>
26 #include <KDebug>
27 #include <KLocalizedString>
28 
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>
40 
41 Q_DECLARE_METATYPE(KBlog::BlogPost*)
42 Q_DECLARE_METATYPE(KGAPI2::Job*)
43 typedef QMap<QString, QString> KBlogInfo;
44 
45 #define KBLOGPOST_PROPERTY "KBlogPostProperty"
46 #define JOB_PROPERTY "JobProperty"
47 
48 namespace KBlog
49 {
50 
51 class BloggerPrivate: public KBlog::BlogPrivate
52 {
53  public:
54  BloggerPrivate(Blogger *parent);
55  virtual ~BloggerPrivate();
56 
57  void updateKBlogPost(KBlog::BlogPost *kblog, const KGAPI2::Blogger::PostPtr &postPtr);
58  KBlog::BlogPost KGAPIPostToKBlogPost(const KGAPI2::Blogger::PostPtr &postPtr);
59  QList<KBlog::BlogPost> KGAPIPostsToKBlogPosts(const KGAPI2::ObjectsList &posts);
60  KGAPI2::Blogger::PostPtr KBlogPostToKGAPI(const BlogPost * const kblog);
61 
62  KBlogInfo KGAPIBlogToKBlogBlog(const KGAPI2::Blogger::BlogPtr &blogPtr);
63  QList<KBlogInfo> KGAPIBlogsToKBlogBlogs(const KGAPI2::ObjectsList &blogs);
64 
65  KBlog::BlogComment KGAPICommentToKBlogComment(const KGAPI2::Blogger::CommentPtr &commentPtr);
66  QList<KBlog::BlogComment> KGAPICommentsToKBlogComments(const KGAPI2::ObjectsList &comments);
67 
68  bool handleError(KGAPI2::Job *job);
69 
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);
78 
79  QString apiKey;
80  QString secretKey;
81  KGAPI2::AccountPtr account;
82 
83  private:
84  Blogger * const q_ptr;
85  Q_DECLARE_PUBLIC(Blogger)
86 };
87 
88 } // namespace KBlog
89 
90 using namespace KBlog;
91 
92 BloggerPrivate::BloggerPrivate(Blogger *parent)
93  : BlogPrivate()
94  , q_ptr(parent)
95 {
96 }
97 
98 BloggerPrivate::~BloggerPrivate()
99 {
100 }
101 
102 void BloggerPrivate::updateKBlogPost(BlogPost *kblog, const KGAPI2::Blogger::PostPtr &postPtr)
103 {
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"));
112  // TODO: Try to match more?
113 }
114 
115 KGAPI2::Blogger::PostPtr BloggerPrivate::KBlogPostToKGAPI(const BlogPost *const kblog)
116 {
117  Q_Q(Blogger);
118 
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());
128  return postPtr;
129 }
130 
131 BlogPost BloggerPrivate::KGAPIPostToKBlogPost(const KGAPI2::Blogger::PostPtr &postPtr)
132 {
133  BlogPost kblog;
134  updateKBlogPost(&kblog, postPtr);
135  return kblog;
136 }
137 
138 QList<BlogPost> BloggerPrivate::KGAPIPostsToKBlogPosts(const KGAPI2::ObjectsList &posts)
139 {
140  QList<BlogPost> blogPosts;
141  Q_FOREACH (const KGAPI2::ObjectPtr &obj, posts) {
142  blogPosts << KGAPIPostToKBlogPost(obj.dynamicCast<KGAPI2::Blogger::Post>());
143  }
144  return blogPosts;
145 }
146 
147 
148 KBlogInfo BloggerPrivate::KGAPIBlogToKBlogBlog(const KGAPI2::Blogger::BlogPtr &blogPtr)
149 {
150  KBlogInfo kblogInfo;
151  kblogInfo[QLatin1String("id")] = blogPtr->id();
152  kblogInfo[QLatin1String("title")] = blogPtr->name();
153  kblogInfo[QLatin1String("url")] = blogPtr->url().toString();
154  kblogInfo[QLatin1String("summay")] = blogPtr->description();
155  return kblogInfo;
156 }
157 
158 QList<KBlogInfo> BloggerPrivate::KGAPIBlogsToKBlogBlogs(const KGAPI2::ObjectsList &blogs)
159 {
160  QList<KBlogInfo> kblogInfos;
161  Q_FOREACH (const KGAPI2::ObjectPtr &obj, blogs) {
162  kblogInfos << KGAPIBlogToKBlogBlog(obj.dynamicCast<KGAPI2::Blogger::Blog>());
163  }
164  return kblogInfos;
165 }
166 
167 BlogComment BloggerPrivate::KGAPICommentToKBlogComment(const KGAPI2::Blogger::CommentPtr &commentPtr)
168 {
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());
175  return kblogComment;
176 }
177 
178 QList<BlogComment> BloggerPrivate::KGAPICommentsToKBlogComments(const KGAPI2::ObjectsList &comments)
179 {
180  QList<BlogComment> kblogComments;
181  Q_FOREACH (const KGAPI2::ObjectPtr &obj, comments) {
182  kblogComments << KGAPICommentToKBlogComment(obj.dynamicCast<KGAPI2::Blogger::Comment>());
183  }
184  return kblogComments;
185 }
186 
187 bool BloggerPrivate::handleError(KGAPI2::Job *job)
188 {
189  Q_Q(Blogger);
190 
191  if (!job->error()) {
192  return true;
193  }
194 
195  KBlog::BlogPost *post = job->property(KBLOGPOST_PROPERTY).value<BlogPost*>();
196 
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);
201  authJob->setProperty(JOB_PROPERTY, QVariant::fromValue(job));
202  q->connect(authJob, SIGNAL(finished(KGAPI2::Job*)),
203  q, SLOT(_k_onAuthenticateFinished(KGAPI2::Job*)));
204  return false;
205  }
206  case KGAPI2::AuthCancelled:
207  case KGAPI2::AuthError:
208  errCode = Blog::AuthenticationError;
209  break;
210 
211  case KGAPI2::BadRequest:
212  errCode = Blog::XmlRpc;
213  break;
214 
215  // Not found is handled in callers
216  case KGAPI2::NotFound:
217  return true;
218 
219  default:
220  errCode = Blog::Other;
221  break;
222  }
223 
224  if (post) {
225  Q_EMIT q->errorPost(errCode, job->errorString(), post);
226  } else {
227  Q_EMIT q->error(errCode, job->errorString());
228  }
229 
230  job->deleteLater();
231  return false;
232 }
233 
234 
235 
236 
237 Blogger::Blogger(const KUrl &server, QObject *parent)
238  : Blog(server, *new BloggerPrivate(this), parent)
239 {
240  kDebug();
241 }
242 
243 Blogger::~Blogger()
244 {
245  kDebug();
246 }
247 
248 
249 QString Blogger::interfaceName() const
250 {
251  return QLatin1String("Blogger 3.0");
252 }
253 
254 void Blogger::setApiKey(const QString &apiKey)
255 {
256  Q_D(Blogger);
257  d->apiKey = apiKey;
258 }
259 
260 void Blogger::setSecretKey(const QString &secretKey)
261 {
262  Q_D(Blogger);
263  d->secretKey = secretKey;
264 }
265 
266 void Blogger::authenticate(const QMap<QString, QString> &authData)
267 {
268  Q_D(Blogger);
269 
270  KGAPI2::AccountPtr account;
271  kDebug() << authData;
272  if (!authData.isEmpty()) {
273  QList<QUrl> scopes;
274  scopes << KGAPI2::Account::bloggerScopeUrl();
275  account = KGAPI2::AccountPtr(new KGAPI2::Account(authData[QLatin1String("account")],
276  authData[QLatin1String("accessToken")],
277  authData[QLatin1String("refreshToken")],
278  scopes));
279  d->account = account;
280  } else {
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());
287  }
288  connect(authJob, SIGNAL(finished(KGAPI2::Job*)),
289  this, SLOT(_k_onAuthenticateFinished(KGAPI2::Job*)));
290  }
291 }
292 
293 void BloggerPrivate::_k_onAuthenticateFinished(KGAPI2::Job *job)
294 {
295  Q_Q(Blogger);
296  if (!handleError(job)) {
297  return;
298  }
299 
300  KGAPI2::AuthJob *authJob = qobject_cast<KGAPI2::AuthJob*>(job);
301  account = authJob->account();
302 
303  QMap<QString, QString> authData;
304  authData[QLatin1String("account")] = account->accountName();
305  authData[QLatin1String("accessToken")] = account->accessToken();
306  authData[QLatin1String("refreshToken")] = account->refreshToken();
307 
308  Q_EMIT q->authenticated(authData);
309 
310  if (authJob->property(JOB_PROPERTY).isValid()) {
311  KGAPI2::Job *originalJob = authJob->property(JOB_PROPERTY).value<KGAPI2::Job*>();
312  if (originalJob) {
313  originalJob->restart();
314  }
315  }
316 }
317 
318 
319 void Blogger::listBlogs()
320 {
321  Q_D(Blogger);
322 
323  KGAPI2::Blogger::BlogFetchJob *fetchJob
324  = new KGAPI2::Blogger::BlogFetchJob(QLatin1String("self"),
325  KGAPI2::Blogger::BlogFetchJob::FetchByUserId,
326  d->account,
327  this);
328  connect(fetchJob, SIGNAL(finished(KGAPI2::Job*)),
329  this, SLOT(_k_onListBlogsFinished(KGAPI2::Job*)));
330 }
331 
332 void BloggerPrivate::_k_onListBlogsFinished(KGAPI2::Job *job)
333 {
334  Q_Q(Blogger);
335 
336  if (!handleError(job)) {
337  return;
338  }
339 
340  job->deleteLater();
341  KGAPI2::FetchJob *fetchJob = qobject_cast<KGAPI2::FetchJob*>(job);
342  const QList<KBlogInfo> blogs = KGAPIBlogsToKBlogBlogs(fetchJob->items());
343  Q_EMIT q->listedBlogs(blogs);
344 }
345 
346 
347 void Blogger::listRecentPosts(int number)
348 {
349  Q_D(Blogger);
350 
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*)));
356 }
357 
358 void BloggerPrivate::_k_onListRecentPostsFinished(KGAPI2::Job *job)
359 {
360  Q_Q(Blogger);
361 
362  if (!handleError(job)) {
363  return;
364  }
365 
366  job->deleteLater();
367  KGAPI2::FetchJob *fetchJob = qobject_cast<KGAPI2::FetchJob*>(job);
368  QList<BlogPost> posts = KGAPIPostsToKBlogPosts(fetchJob->items());
369  QList<BlogPost>::Iterator iter, endIter = posts.end();
370  for (iter = posts.begin(); iter != endIter; ++iter) {
371  (*iter).setStatus(BlogPost::Fetched);
372  }
373  Q_EMIT q->listedRecentPosts(posts);
374 }
375 
376 
377 void Blogger::fetchPost(KBlog::BlogPost *post)
378 {
379  Q_D(Blogger);
380 
381  KGAPI2::Blogger::PostFetchJob *fetchJob
382  = new KGAPI2::Blogger::PostFetchJob(blogId(), post->postId(), d->account, this);
383  fetchJob->setProperty(KBLOGPOST_PROPERTY, QVariant::fromValue(post));
384  connect(fetchJob, SIGNAL(finished(KGAPI2::Job*)),
385  this, SLOT(_k_onFetchPostFinished(KGAPI2::Job*)));
386 }
387 
388 void BloggerPrivate::_k_onFetchPostFinished(KGAPI2::Job *job)
389 {
390  Q_Q(Blogger);
391 
392  if (!handleError(job)) {
393  return;
394  }
395 
396  job->deleteLater();
397  KGAPI2::FetchJob *fetchJob = qobject_cast<KGAPI2::FetchJob*>(job);
398  BlogPost *kblog = fetchJob->property(KBLOGPOST_PROPERTY).value<BlogPost*>();
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);
402  return;
403  }
404 
405  updateKBlogPost(kblog, items.first().dynamicCast<KGAPI2::Blogger::Post>());
406  kblog->setStatus(BlogPost::Fetched);
407  Q_EMIT q->fetchedPost(kblog);
408 }
409 
410 
411 void Blogger::removePost(KBlog::BlogPost *post)
412 {
413  Q_D(Blogger);
414 
415  KGAPI2::Blogger::PostDeleteJob *deleteJob
416  = new KGAPI2::Blogger::PostDeleteJob(blogId(), post->postId(), d->account, this);
417  deleteJob->setProperty(KBLOGPOST_PROPERTY, QVariant::fromValue(post));
418  connect(deleteJob, SIGNAL(finished(KGAPI2::Job*)),
419  this, SLOT(_k_onRemovePostFinished(KGAPI2::Job*)));
420 }
421 
422 void BloggerPrivate::_k_onRemovePostFinished(KGAPI2::Job *job)
423 {
424  Q_Q(Blogger);
425 
426  if (!handleError(job)) {
427  return;
428  }
429 
430  job->deleteLater();
431  BlogPost *kblog = job->property(KBLOGPOST_PROPERTY).value<BlogPost*>();
432  kblog->setStatus(BlogPost::Removed);
433  Q_EMIT q->removedPost(kblog);
434 }
435 
436 
437 
438 void Blogger::createPost(KBlog::BlogPost *post)
439 {
440  Q_D(Blogger);
441 
442  KGAPI2::Blogger::PostPtr postPtr = d->KBlogPostToKGAPI(post);
443  KGAPI2::Blogger::PostCreateJob *createJob
444  = new KGAPI2::Blogger::PostCreateJob(postPtr, post->isPrivate(), d->account, this);
445  createJob->setProperty(KBLOGPOST_PROPERTY, QVariant::fromValue(post));
446  connect(createJob, SIGNAL(finished(KGAPI2::Job*)),
447  this, SLOT(_k_onCreatePostFinished(KGAPI2::Job*)));
448 }
449 
450 void BloggerPrivate::_k_onCreatePostFinished(KGAPI2::Job *job)
451 {
452  Q_Q(Blogger);
453 
454  if (!handleError(job)) {
455  return;
456  }
457 
458  job->deleteLater();
459  KGAPI2::CreateJob *createJob = qobject_cast<KGAPI2::CreateJob*>(job);
460  BlogPost* kblog = createJob->property(KBLOGPOST_PROPERTY).value<BlogPost*>();
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);
464  return;
465  }
466 
467  updateKBlogPost(kblog, items.first().dynamicCast<KGAPI2::Blogger::Post>());
468  kblog->setStatus(BlogPost::Created);
469  Q_EMIT q->createdPost(kblog);
470 }
471 
472 
473 void Blogger::modifyPost(KBlog::BlogPost *post)
474 {
475  Q_D(Blogger);
476 
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);
482  modifyJob->setProperty(KBLOGPOST_PROPERTY, QVariant::fromValue(post));
483  connect(modifyJob, SIGNAL(finished(KGAPI2::Job*)),
484  this, SLOT(_k_onModifyPostFinished(KGAPI2::Job*)));
485 }
486 
487 void BloggerPrivate::_k_onModifyPostFinished(KGAPI2::Job *job)
488 {
489  Q_Q(Blogger);
490 
491  if (!handleError(job)) {
492  return;
493  }
494 
495  job->deleteLater();
496  KGAPI2::ModifyJob *modifyJob = qobject_cast<KGAPI2::ModifyJob*>(job);
497  BlogPost *kblog = modifyJob->property(KBLOGPOST_PROPERTY).value<BlogPost*>();
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);
501  return;
502  }
503 
504  updateKBlogPost(kblog, items.first().dynamicCast<KGAPI2::Blogger::Post>());
505  kblog->setStatus(BlogPost::Modified);
506  Q_EMIT q->modifiedPost(kblog);
507 }
508 
509 
510 void Blogger::listComments(BlogPost *post)
511 {
512  Q_D(Blogger);
513 
514  KGAPI2::Blogger::CommentFetchJob *fetchJob
515  = new KGAPI2::Blogger::CommentFetchJob(blogId(), post->postId(), d->account, this);
516  fetchJob->setProperty(KBLOGPOST_PROPERTY, QVariant::fromValue(post));
517  connect(fetchJob, SIGNAL(finished(KGAPI2::Job*)),
518  this, SLOT(_k_onListCommentsFinished(KGAPI2::Job*)));
519 }
520 
521 void BloggerPrivate::_k_onListCommentsFinished(KGAPI2::Job *job)
522 {
523  Q_Q(Blogger);
524 
525  if (!handleError(job)) {
526  return;
527  }
528 
529  job->deleteLater();
530  KGAPI2::FetchJob *fetchJob = qobject_cast<KGAPI2::FetchJob*>(job);
531  BlogPost *kblog = fetchJob->property(KBLOGPOST_PROPERTY).value<BlogPost*>();
532  const QList<KBlog::BlogComment> comments = KGAPICommentsToKBlogComments(fetchJob->items());
533  Q_EMIT q->listedComments(kblog, comments);
534 }
535 
536 
537 
538 #include "moc_blogger.cpp"
539 
KBlog::Blogger::setApiKey
void setApiKey(const QString &apiKey)
Sets Google OAuth application API key.
Definition: blogger.cpp:254
KBlog::Blogger::createPost
void createPost(KBlog::BlogPost *post)
Create a new post on server.
Definition: blogger.cpp:438
blog_p.h
QMap
KBlog::Blogger::removePost
void removePost(KBlog::BlogPost *post)
Remove a post from the server.
Definition: blogger.cpp:411
KBlog::Blogger::listRecentPosts
void listRecentPosts(int number)
List recent posts on the server.
Definition: blogger.cpp:347
blogger.h
This file is part of the for accessing Blog Servers from the Google's Blogger and BlogPost service an...
QObject
KBlog::Blogger::fetchPost
void fetchPost(KBlog::BlogPost *post)
Fetch the Post with a specific id.
Definition: blogger.cpp:377
KBlog::Blogger::~Blogger
virtual ~Blogger()
Destructor.
Definition: blogger.cpp:243
JOB_PROPERTY
#define JOB_PROPERTY
Definition: blogger.cpp:46
QString
QList
KBlog::BlogPrivate
Definition: blog_p.h:31
QList::end
iterator end()
KBLOGPOST_PROPERTY
#define KBLOGPOST_PROPERTY
Definition: blogger.cpp:45
QVariant::fromValue
QVariant fromValue(const T &value)
KBlog::Blogger::interfaceName
QString interfaceName() const
Returns name of the service.
Definition: blogger.cpp:249
KBlog::Blogger::modifyPost
void modifyPost(KBlog::BlogPost *post)
Modify a post on server.
Definition: blogger.cpp:473
KBlog::Blogger::authenticate
void authenticate(const QMap< QString, QString > &authData=QMap< QString, QString >())
Authenticate this instance of Blogger against Google account.
Definition: blogger.cpp:266
QLatin1String
KBlog::Blogger
A class that can be used for access to Google blogs.
Definition: blogger.h:65
KBlog::Blogger::listComments
void listComments(KBlog::BlogPost *post)
List the comments available for this post on the server.
Definition: blogger.cpp:510
QMap::isEmpty
bool isEmpty() const
KBlog::Blogger::setSecretKey
void setSecretKey(const QString &secretKey)
Sets Google OAuth application secret key.
Definition: blogger.cpp:260
QMap::value
const T value(const Key &key) const
KBlog::Blogger::listBlogs
void listBlogs()
List the blogs available for this authentication on the server.
Definition: blogger.cpp:319
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:32:16 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

blogilo

Skip menu "blogilo"
  • Main Page
  • Namespace List
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdepim API Reference

Skip menu "kdepim API Reference"
  • akonadi_next
  • akregator
  • blogilo
  • calendarsupport
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt2
  • kjots
  • kleopatra
  • kmail
  • knode
  • knotes
  • kontact
  • korgac
  • korganizer
  • ktimetracker
  • libkdepim
  • libkleo
  • libkpgp
  • mailcommon
  • messagelist
  • messageviewer
  • pimprint

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal