Attica

provider.cpp
1 /*
2  This file is part of KDE.
3 
4  SPDX-FileCopyrightText: 2008 Cornelius Schumacher <[email protected]>
5  SPDX-FileCopyrightText: 2010 Sebastian K├╝gler <[email protected]>
6  SPDX-FileCopyrightText: 2011 Laszlo Papp <[email protected]>
7 
8  SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
9 */
10 
11 #include "provider.h"
12 
13 #include "accountbalance.h"
14 #include "accountbalanceparser.h"
15 #include "achievement.h"
16 #include "achievementparser.h"
17 #include "activity.h"
18 #include "activityparser.h"
19 #include "buildservice.h"
20 #include "buildserviceparser.h"
21 #include "buildservicejob.h"
22 #include "buildservicejobparser.h"
23 #include "buildservicejoboutput.h"
24 #include "buildservicejoboutputparser.h"
25 #include "privatedata.h"
26 #include "privatedataparser.h"
27 #include "category.h"
28 #include "categoryparser.h"
29 #include "comment.h"
30 #include "commentparser.h"
31 #include "config.h"
32 #include "content.h"
33 #include "contentparser.h"
34 #include "distribution.h"
35 #include "distributionparser.h"
36 #include "downloaditem.h"
37 #include "downloaditemparser.h"
38 #include "event.h"
39 #include "eventparser.h"
40 #include "folder.h"
41 #include "folderparser.h"
42 #include "forum.h"
43 #include "forumparser.h"
44 #include "homepagetype.h"
45 #include "homepagetypeparser.h"
46 #include "knowledgebaseentry.h"
47 #include "knowledgebaseentryparser.h"
48 #include "license.h"
49 #include "licenseparser.h"
50 #include "message.h"
51 #include "messageparser.h"
52 #include "person.h"
53 #include "personparser.h"
54 #include "platformdependent_v2.h"
55 #include "postjob.h"
56 #include "postfiledata.h"
57 #include "project.h"
58 #include "projectparser.h"
59 #include "publisher.h"
60 #include "publisherparser.h"
61 #include "publisherfield.h"
62 #include "publisherfieldparser.h"
63 #include "remoteaccount.h"
64 #include "remoteaccountparser.h"
65 #include "topic.h"
66 #include "topicparser.h"
67 #include "itemjob.h"
68 #include "listjob.h"
69 #include "version.h"
70 
71 #include <QStringList>
72 #include <QNetworkAccessManager>
73 #include <QDebug>
74 #include <QUrl>
75 #include <QUrlQuery>
76 #include <QNetworkReply>
77 #include <QFile>
78 #include <QCoreApplication>
79 
80 using namespace Attica;
81 
83 {
84  if (prov.isValid())
85  s.nospace() << "Provider(" << prov.name() << ':' << prov.baseUrl() << ')';
86  else
87  s.nospace() << "Provider(Invalid)";
88  return s.space();
89 }
90 
91 class Provider::Private : public QSharedData
92 {
93 public:
94  QUrl m_baseUrl;
95  QUrl m_icon;
96  QString m_name;
97  QString m_credentialsUserName;
98  QString m_credentialsPassword;
99  QString m_personVersion;
100  QString m_friendVersion;
101  QString m_messageVersion;
102  QString m_achievementVersion;
103  QString m_activityVersion;
104  QString m_contentVersion;
105  QString m_fanVersion;
106  QString m_forumVersion;
107  QString m_knowledgebaseVersion;
108  QString m_eventVersion;
109  QString m_commentVersion;
110  QString m_registerUrl;
111  PlatformDependent *m_internals;
112  QString m_additionalAgentInformation;
113 
114  Private()
115  : m_internals(nullptr)
116  {}
117 
118  Private(const Private &other)
119  : QSharedData(other), m_baseUrl(other.m_baseUrl), m_name(other.m_name)
120  , m_credentialsUserName(other.m_credentialsUserName)
121  , m_credentialsPassword(other.m_credentialsPassword)
122  , m_personVersion(other.m_personVersion)
123  , m_friendVersion(other.m_friendVersion)
124  , m_messageVersion(other.m_messageVersion)
125  , m_achievementVersion(other.m_achievementVersion)
126  , m_activityVersion(other.m_activityVersion)
127  , m_contentVersion(other.m_contentVersion)
128  , m_fanVersion(other.m_fanVersion)
129  , m_forumVersion(other.m_forumVersion)
130  , m_knowledgebaseVersion(other.m_knowledgebaseVersion)
131  , m_eventVersion(other.m_eventVersion)
132  , m_commentVersion(other.m_commentVersion)
133  , m_registerUrl(other.m_registerUrl)
134  , m_internals(other.m_internals)
135  , m_additionalAgentInformation(other.m_additionalAgentInformation)
136  {
137  }
138 
139  Private(PlatformDependent *internals, const QUrl &baseUrl, const QString &name, const QUrl &icon,
140  const QString &person, const QString &friendV, const QString &message, const QString &achievement,
141  const QString &activity, const QString &content, const QString &fan, const QString &forum,
142  const QString &knowledgebase, const QString &event, const QString &comment, const QString &registerUrl,
144  : m_baseUrl(baseUrl), m_icon(icon), m_name(name)
145  , m_personVersion(person)
146  , m_friendVersion(friendV)
147  , m_messageVersion(message)
148  , m_achievementVersion(achievement)
149  , m_activityVersion(activity)
150  , m_contentVersion(content)
151  , m_fanVersion(fan)
152  , m_forumVersion(forum)
153  , m_knowledgebaseVersion(knowledgebase)
154  , m_eventVersion(event)
155  , m_commentVersion(comment)
156  , m_registerUrl(registerUrl)
157  , m_internals(internals)
158  , m_additionalAgentInformation(additionalAgentInformation)
159  {
160  if (m_baseUrl.isEmpty()) {
161  return;
162  }
163  QString user;
164  QString pass;
165  if (m_internals->hasCredentials(m_baseUrl) && m_internals->loadCredentials(m_baseUrl, user, pass)) {
166  m_credentialsUserName = user;
167  m_credentialsPassword = pass;
168  }
169  }
170 
171  ~Private()
172  {
173  }
174 };
175 
176 Provider::Provider()
177  : d(new Private)
178 {
179 }
180 
181 Provider::Provider(const Provider &other)
182  : d(other.d)
183 {
184 }
185 
186 Provider::Provider(PlatformDependent *internals, const QUrl &baseUrl, const QString &name, const QUrl &icon,
187  const QString &person, const QString &friendV, const QString &message, const QString &achievement,
188  const QString &activity, const QString &content, const QString &fan, const QString &forum,
189  const QString &knowledgebase, const QString &event, const QString &comment)
190  : d(new Private(internals, baseUrl, name, icon, person, friendV, message, achievement, activity, content,
191  fan, forum, knowledgebase, event, comment, QString(), QString()))
192 {
193 }
194 
195 Provider::Provider(PlatformDependent *internals, const QUrl &baseUrl, const QString &name, const QUrl &icon,
196  const QString &person, const QString &friendV, const QString &message, const QString &achievement,
197  const QString &activity, const QString &content, const QString &fan, const QString &forum,
198  const QString &knowledgebase, const QString &event, const QString &comment, const QString &registerUrl)
199  : d(new Private(internals, baseUrl, name, icon, person, friendV, message, achievement, activity, content,
200  fan, forum, knowledgebase, event, comment, registerUrl, QString()))
201 {
202 }
203 
204 Provider::Provider(PlatformDependent *internals, const QUrl &baseUrl, const QString &name, const QUrl &icon,
205  const QString &person, const QString &friendV, const QString &message, const QString &achievement,
206  const QString &activity, const QString &content, const QString &fan, const QString &forum,
207  const QString &knowledgebase, const QString &event, const QString &comment, const QString &registerUrl,
208  const QString &additionalAgentInformation)
209  : d(new Private(internals, baseUrl, name, icon, person, friendV, message, achievement, activity, content,
210  fan, forum, knowledgebase, event, comment, registerUrl, additionalAgentInformation))
211 {
212 }
213 
214 Provider &Provider::operator=(const Attica::Provider &other)
215 {
216  d = other.d;
217  return *this;
218 }
219 
220 Provider::~Provider()
221 {
222 }
223 
225 {
226  return d->m_baseUrl;
227 }
228 
229 bool Provider::isValid() const
230 {
231  return d->m_baseUrl.isValid();
232 }
233 
235 {
236  if (!isValid()) {
237  return false;
238  }
239 
240  return d->m_internals->isEnabled(d->m_baseUrl);
241 }
242 
243 void Provider::setEnabled(bool enabled)
244 {
245  if (!isValid()) {
246  return;
247  }
248 
249  d->m_internals->enableProvider(d->m_baseUrl, enabled);
250 }
251 
252 void Provider::setAdditionalAgentInformation(const QString& additionalInformation) {
253  d->m_additionalAgentInformation = additionalInformation;
254 }
255 
257  return d->m_additionalAgentInformation;
258 }
259 
261 {
262  return d->m_name;
263 }
264 
266 {
267  if (!isValid()) {
268  return false;
269  }
270 
271  return d->m_internals->hasCredentials(d->m_baseUrl);
272 }
273 
275 {
276  if (!isValid()) {
277  return false;
278  }
279 
280  return d->m_internals->hasCredentials(d->m_baseUrl);
281 }
282 
284 {
285  if (!isValid()) {
286  return false;
287  }
288 
289  if (d->m_internals->loadCredentials(d->m_baseUrl, user, password)) {
290  d->m_credentialsUserName = user;
291  d->m_credentialsPassword = password;
292  return true;
293  }
294  return false;
295 }
296 
297 bool Provider::saveCredentials(const QString &user, const QString &password)
298 {
299  if (!isValid()) {
300  return false;
301  }
302 
303  d->m_credentialsUserName = user;
304  d->m_credentialsPassword = password;
305  return d->m_internals->saveCredentials(d->m_baseUrl, user, password);
306 }
307 
308 PostJob *Provider::checkLogin(const QString &user, const QString &password)
309 {
310  if (!isValid()) {
311  return nullptr;
312  }
313 
314  QMap<QString, QString> postParameters;
315 
316  postParameters.insert(QLatin1String("login"), user);
317  postParameters.insert(QLatin1String("password"), password);
318 
319  return new PostJob(d->m_internals, createRequest(QLatin1String("person/check")), postParameters);
320 }
321 
322 ItemJob<Config> *Provider::requestConfig()
323 {
324  if (!isValid()) {
325  return nullptr;
326  }
327 
328  QUrl url = createUrl(QLatin1String("config"));
329  return doRequestConfig(url);
330 }
331 
332 PostJob *Provider::registerAccount(const QString &id, const QString &password, const QString &mail, const QString &firstName, const QString &lastName)
333 {
334  if (!isValid()) {
335  return nullptr;
336  }
337 
338  QMap<QString, QString> postParameters;
339 
340  postParameters.insert(QLatin1String("login"), id);
341  postParameters.insert(QLatin1String("password"), password);
342  postParameters.insert(QLatin1String("firstname"), firstName);
343  postParameters.insert(QLatin1String("lastname"), lastName);
344  postParameters.insert(QLatin1String("email"), mail);
345 
346  return new PostJob(d->m_internals, createRequest(QLatin1String("person/add")), postParameters);
347 }
348 
349 const QString &Provider::getRegisterAccountUrl() const
350 {
351  return d->m_registerUrl;
352 }
353 
354 ItemJob<Person> *Provider::requestPerson(const QString &id)
355 {
356  if (!isValid()) {
357  return nullptr;
358  }
359 
360  QUrl url = createUrl(QLatin1String("person/data/") + id);
361  return doRequestPerson(url);
362 }
363 
364 ItemJob<Person> *Provider::requestPersonSelf()
365 {
366  if (!isValid()) {
367  return nullptr;
368  }
369 
370  QUrl url = createUrl(QLatin1String("person/self"));
371  return doRequestPerson(url);
372 }
373 
374 ItemJob<AccountBalance> *Provider::requestAccountBalance()
375 {
376  if (!isValid()) {
377  return nullptr;
378  }
379 
380  QUrl url = createUrl(QLatin1String("person/balance"));
381  return doRequestAccountBalance(url);
382 }
383 
384 ListJob<Person> *Provider::requestPersonSearchByName(const QString &name)
385 {
386  if (!isValid()) {
387  return nullptr;
388  }
389 
390  QUrl url = createUrl(QStringLiteral("person/data"));
391  QUrlQuery q(url);
392  q.addQueryItem(QStringLiteral("name"), name);
393  url.setQuery(q);
394  return doRequestPersonList(url);
395 }
396 
397 ListJob<Person> *Provider::requestPersonSearchByLocation(qreal latitude, qreal longitude, qreal distance, int page, int pageSize)
398 {
399  if (!isValid()) {
400  return nullptr;
401  }
402 
403  QUrl url = createUrl(QStringLiteral("person/data"));
404  QUrlQuery q(url);
405  q.addQueryItem(QStringLiteral("latitude"), QString::number(latitude));
406  q.addQueryItem(QStringLiteral("longitude"), QString::number(longitude));
407  if (distance > 0.0) {
408  q.addQueryItem(QStringLiteral("distance"), QString::number(distance));
409  }
410  q.addQueryItem(QStringLiteral("page"), QString::number(page));
411  q.addQueryItem(QStringLiteral("pagesize"), QString::number(pageSize));
412  url.setQuery(q);
413 
414  return doRequestPersonList(url);
415 }
416 
417 ListJob<Person> *Provider::requestFriends(const QString &id, int page, int pageSize)
418 {
419  if (!isValid()) {
420  return nullptr;
421  }
422 
423  QUrl url = createUrl(QLatin1String("friend/data/") + id);
424  QUrlQuery q(url);
425  q.addQueryItem(QLatin1String("page"), QString::number(page));
426  q.addQueryItem(QLatin1String("pagesize"), QString::number(pageSize));
427  url.setQuery(q);
428 
429  return doRequestPersonList(url);
430 }
431 
432 ListJob<Person> *Provider::requestSentInvitations(int page, int pageSize)
433 {
434  if (!isValid()) {
435  return nullptr;
436  }
437 
438  QUrl url = createUrl(QStringLiteral("friend/sentinvitations"));
439  QUrlQuery q(url);
440  q.addQueryItem(QStringLiteral("page"), QString::number(page));
441  q.addQueryItem(QStringLiteral("pagesize"), QString::number(pageSize));
442  url.setQuery(q);
443 
444  return doRequestPersonList(url);
445 }
446 
447 ListJob<Person> *Provider::requestReceivedInvitations(int page, int pageSize)
448 {
449  if (!isValid()) {
450  return nullptr;
451  }
452 
453  QUrl url = createUrl(QStringLiteral("friend/receivedinvitations"));
454  QUrlQuery q(url);
455  q.addQueryItem(QStringLiteral("page"), QString::number(page));
456  q.addQueryItem(QStringLiteral("pagesize"), QString::number(pageSize));
457  url.setQuery(q);
458 
459  return doRequestPersonList(url);
460 }
461 
462 ListJob<Achievement> *Provider::requestAchievements(const QString &contentId, const QString &achievementId, const QString &userId)
463 {
464  if (!isValid()) {
465  return nullptr;
466  }
467 
468  QUrl url = createUrl(QLatin1String("achievements/content/") + contentId + achievementId);
469  QUrlQuery q(url);
470  q.addQueryItem(QStringLiteral("user_id"), userId);
471  url.setQuery(q);
472  return doRequestAchievementList(url);
473 }
474 
475 ItemPostJob<Achievement> *Provider::addNewAchievement(const QString &contentId, const Achievement &newAchievement)
476 {
477  if (!isValid()) {
478  return nullptr;
479  }
480 
481  StringMap postParameters;
482  int i = 0, j = 0;
483 
484  postParameters.insert(QLatin1String("name"), newAchievement.name());
485  postParameters.insert(QLatin1String("description"), newAchievement.description());
486  postParameters.insert(QLatin1String("explanation"), newAchievement.explanation());
487  postParameters.insert(QLatin1String("points"), QString::number(newAchievement.points()));
488  postParameters.insert(QLatin1String("image"), newAchievement.image().toLocalFile());
489  const auto dependenciesList = newAchievement.dependencies();
490  for (const QString &dependency : dependenciesList) {
491  postParameters.insert(QString::fromLatin1("dependencies[%1]").arg(QString::number(i++)), dependency);
492  }
493 
494  postParameters.insert(QLatin1String("type"), Achievement::achievementTypeToString(newAchievement.type()));
495  const auto optionsList = newAchievement.options();
496  for (const QString &option : optionsList) {
497  postParameters.insert(QString::fromLatin1("options[%1]").arg(QString::number(j++)), option);
498  }
499 
500  postParameters.insert(QLatin1String("steps"), QString::number(newAchievement.steps()));
501  postParameters.insert(QLatin1String("visibility"), Achievement::achievementVisibilityToString(newAchievement.visibility()));
502 
503  return new ItemPostJob<Achievement>(d->m_internals, createRequest(QLatin1String("achievements/content/") + contentId), postParameters);
504 }
505 
506 PutJob *Provider::editAchievement(const QString &contentId, const QString &achievementId, const Achievement &achievement)
507 {
508  if (!isValid()) {
509  return nullptr;
510  }
511 
512  if (!dynamic_cast<Attica::PlatformDependentV2 *>(d->m_internals)) {
513  return nullptr;
514  }
515 
516  StringMap postParameters;
517  int i = 0, j = 0;
518 
519  postParameters.insert(QLatin1String("name"), achievement.name());
520  postParameters.insert(QLatin1String("description"), achievement.description());
521  postParameters.insert(QLatin1String("explanation"), achievement.explanation());
522  postParameters.insert(QLatin1String("points"), QString::number(achievement.points()));
523  postParameters.insert(QLatin1String("image"), achievement.image().toLocalFile());
524  const auto dependenciesList = achievement.dependencies();
525  for (const QString &dependency : dependenciesList) {
526  postParameters.insert(QString::fromLatin1("dependencies[%1]").arg(QString::number(i++)), dependency);
527  }
528 
529  postParameters.insert(QLatin1String("type"), Achievement::achievementTypeToString(achievement.type()));
530  const auto optionsList = achievement.options();
531  for (const QString &option : optionsList) {
532  postParameters.insert(QString::fromLatin1("options[%1]").arg(QString::number(j++)), option);
533  }
534 
535  postParameters.insert(QLatin1String("steps"), QString::number(achievement.steps()));
536  postParameters.insert(QLatin1String("visibility"), Achievement::achievementVisibilityToString(achievement.visibility()));
537 
538  return new ItemPutJob<Achievement>(d->m_internals, createRequest(QLatin1String("achievement/content/") + contentId + achievementId), postParameters);
539 }
540 
541 DeleteJob *Provider::deleteAchievement(const QString &contentId, const QString &achievementId)
542 {
543  if (!isValid()) {
544  return nullptr;
545  }
546 
547  if (!dynamic_cast<Attica::PlatformDependentV2 *>(d->m_internals)) {
548  return nullptr;
549  }
550 
551  return new ItemDeleteJob<Achievement>(d->m_internals, createRequest(QLatin1String("achievements/progress/") + contentId + achievementId));
552 }
553 
554 PostJob *Provider::setAchievementProgress(const QString &id, const QVariant &progress, const QDateTime &timestamp)
555 {
556  if (!isValid()) {
557  return nullptr;
558  }
559 
560  StringMap postParameters;
561 
562  postParameters.insert(QLatin1String("progress"), progress.toString());
563  postParameters.insert(QLatin1String("timestamp"), timestamp.toString());
564 
565  return new ItemPostJob<Achievement>(d->m_internals, createRequest(QLatin1String("achievements/progress/") + id), postParameters);
566 }
567 
568 DeleteJob *Provider::resetAchievementProgress(const QString &id)
569 {
570  if (!isValid()) {
571  return nullptr;
572  }
573 
574  if (!dynamic_cast<Attica::PlatformDependentV2 *>(d->m_internals)) {
575  return nullptr;
576  }
577 
578  return new ItemDeleteJob<Achievement>(d->m_internals, createRequest(QLatin1String("achievements/progress/") + id));
579 }
580 
581 ListJob<Activity> *Provider::requestActivities()
582 {
583  if (!isValid()) {
584  return nullptr;
585  }
586 
587  //qCDebug(ATTICA) << "request activity";
588  QUrl url = createUrl(QLatin1String("activity"));
589  return doRequestActivityList(url);
590 }
591 
592 ListJob<Project> *Provider::requestProjects()
593 {
594  if (!isValid()) {
595  return nullptr;
596  }
597 
598  //qCDebug(ATTICA) << "request projects";
599  QUrl url = createUrl(QLatin1String("buildservice/project/list"));
600  return new ListJob<Project>(d->m_internals, createRequest(url));
601 }
602 
603 ItemJob<Project> *Provider::requestProject(const QString &id)
604 {
605  if (!isValid()) {
606  return nullptr;
607  }
608 
609  QUrl url = createUrl(QLatin1String("buildservice/project/get/") + id);
610  //qCDebug(ATTICA) << url;
611  return new ItemJob<Project>(d->m_internals, createRequest(url));
612 }
613 
614 QMap<QString, QString> projectPostParameters(const Project &project)
615 {
616  QMap<QString, QString> postParameters;
617 
618  if (!project.name().isEmpty()) {
619  postParameters.insert(QLatin1String("name"), project.name());
620  }
621  if (!project.summary().isEmpty()) {
622  postParameters.insert(QLatin1String("summary"), project.summary());
623  }
624  if (!project.description().isEmpty()) {
625  postParameters.insert(QLatin1String("description"), project.description());
626  }
627  if (!project.url().isEmpty()) {
628  postParameters.insert(QLatin1String("url"), project.url());
629  }
630  if (!project.developers().isEmpty()) {
631  postParameters.insert(QLatin1String("developers"), project.developers().join(QLatin1Char('\n')));
632  }
633  if (!project.version().isEmpty()) {
634  postParameters.insert(QLatin1String("version"), project.version());
635  }
636  if (!project.license().isEmpty()) {
637  postParameters.insert(QLatin1String("license"), project.license());
638  }
639  if (!project.requirements().isEmpty()) {
640  postParameters.insert(QLatin1String("requirements"), project.requirements());
641  }
642  // The specfile generator expects an empty string parameter if it is supposed to regenerate the spec file
643  // So we need to check for nullity here as opposed to an empty string.
644  if (!project.specFile().isNull()) {
645  postParameters.insert(QLatin1String("specfile"), project.specFile());
646  }
647  return postParameters;
648 }
649 
650 PostJob *Provider::createProject(const Project &project)
651 {
652  if (!isValid()) {
653  return nullptr;
654  }
655 
656  return new PostJob(d->m_internals, createRequest(QLatin1String("buildservice/project/create")),
657  projectPostParameters(project));
658 }
659 
660 PostJob *Provider::editProject(const Project &project)
661 {
662  if (!isValid()) {
663  return nullptr;
664  }
665 
666  return new PostJob(d->m_internals, createRequest(
667  QLatin1String("buildservice/project/edit/") + project.id()),
668  projectPostParameters(project));
669 }
670 
671 PostJob *Provider::deleteProject(const Project &project)
672 {
673  if (!isValid()) {
674  return nullptr;
675  }
676 
677  return new PostJob(d->m_internals, createRequest(
678  QLatin1String("buildservice/project/delete/") + project.id()),
679  projectPostParameters(project));
680 }
681 
682 ItemJob<BuildService> *Provider::requestBuildService(const QString &id)
683 {
684  if (!isValid()) {
685  return nullptr;
686  }
687 
688  QUrl url = createUrl(QLatin1String("buildservice/buildservices/get/") + id);
689  return new ItemJob<BuildService>(d->m_internals, createRequest(url));
690 }
691 
692 ItemJob<Publisher> *Provider::requestPublisher(const QString &id)
693 {
694  if (!isValid()) {
695  return nullptr;
696  }
697 
698  //qCDebug(ATTICA) << "request publisher" << id;
699  QUrl url = createUrl(QLatin1String("buildservice/publishing/getpublisher/") + id);
700  return new ItemJob<Publisher>(d->m_internals, createRequest(url));
701 }
702 
703 PostJob *Provider::savePublisherField(const Project &project, const PublisherField &field)
704 {
705  if (!isValid()) {
706  return nullptr;
707  }
708 
709  StringMap postParameters;
710  postParameters.insert(QLatin1String("fields[0][name]"), field.name());
711  postParameters.insert(QLatin1String("fields[0][fieldtype]"), field.type());
712  postParameters.insert(QLatin1String("fields[0][data]"), field.data());
713 
714  QString url = QLatin1String("buildservice/publishing/savefields/") + project.id();
715  //qCDebug(ATTICA) << "saving field values...";
716  return new PostJob(d->m_internals, createRequest(url), postParameters);
717 }
718 
719 PostJob *Provider::publishBuildJob(const BuildServiceJob &buildjob, const Publisher &publisher)
720 {
721  if (!isValid()) {
722  return nullptr;
723  }
724 
725  StringMap postParameters;
726  postParameters.insert(QLatin1String("dummyparameter"), QLatin1String("dummyvalue"));
727 
728  QString url = QLatin1String("buildservice/publishing/publishtargetresult/") +
729  buildjob.id() + QLatin1Char('/') + publisher.id();
730  //qCDebug(ATTICA) << "pub'ing";
731  return new PostJob(d->m_internals, createRequest(url), postParameters);
732 }
733 
734 // Buildservices and their jobs
735 ItemJob<BuildServiceJobOutput> *Provider::requestBuildServiceJobOutput(const QString &id)
736 {
737  if (!isValid()) {
738  return nullptr;
739  }
740 
741  QUrl url = createUrl(QLatin1String("buildservice/jobs/getoutput/") + id);
742  //qCDebug(ATTICA) << url;
743  return new ItemJob<BuildServiceJobOutput>(d->m_internals, createRequest(url));
744 }
745 
746 ItemJob<BuildServiceJob> *Provider::requestBuildServiceJob(const QString &id)
747 {
748  if (!isValid()) {
749  return nullptr;
750  }
751 
752  QUrl url = createUrl(QLatin1String("buildservice/jobs/get/") + id);
753  //qCDebug(ATTICA) << url;
754  return new ItemJob<BuildServiceJob>(d->m_internals, createRequest(url));
755 }
756 
757 QMap<QString, QString> buildServiceJobPostParameters(const BuildServiceJob &buildjob)
758 {
759  QMap<QString, QString> postParameters;
760 
761  if (!buildjob.name().isEmpty()) {
762  postParameters.insert(QLatin1String("name"), buildjob.name());
763  }
764  if (!buildjob.projectId().isEmpty()) {
765  postParameters.insert(QLatin1String("projectid"), buildjob.projectId());
766  }
767  if (!buildjob.target().isEmpty()) {
768  postParameters.insert(QLatin1String("target"), buildjob.target());
769  }
770  if (!buildjob.buildServiceId().isEmpty()) {
771  postParameters.insert(QLatin1String("buildservice"), buildjob.buildServiceId());
772  }
773 
774  return postParameters;
775 }
776 
777 PostJob *Provider::cancelBuildServiceJob(const BuildServiceJob &job)
778 {
779  if (!isValid()) {
780  return nullptr;
781  }
782 
783  StringMap postParameters;
784  postParameters.insert(QLatin1String("dummyparameter"), QLatin1String("dummyvalue"));
785  //qCDebug(ATTICA) << "b....................b";
786  return new PostJob(d->m_internals, createRequest(
787  QLatin1String("buildservice/jobs/cancel/") + job.id()), postParameters);
788 }
789 
790 PostJob *Provider::createBuildServiceJob(const BuildServiceJob &job)
791 {
792  if (!isValid()) {
793  return nullptr;
794  }
795 
796  StringMap postParameters;
797  // A postjob won't be run without parameters.
798  // so even while we don't need any in this case,
799  // we add dummy data to the request
800  postParameters.insert(QLatin1String("dummyparameter"), QLatin1String("dummyvalue"));
801  //qCDebug(ATTICA) << "Creating new BSJ on" << job.buildServiceId();
802  return new PostJob(d->m_internals, createRequest(
803  QLatin1String("buildservice/jobs/create/") +
804  job.projectId() + QLatin1Char('/') + job.buildServiceId() + QLatin1Char('/') + job.target()),
805  postParameters);
806 }
807 
808 ListJob<BuildService> *Provider::requestBuildServices()
809 {
810  if (!isValid()) {
811  return nullptr;
812  }
813 
814  //qCDebug(ATTICA) << "request projects";
815  QUrl url = createUrl(QLatin1String("buildservice/buildservices/list"));
816  return new ListJob<BuildService>(d->m_internals, createRequest(url));
817 }
818 
819 ListJob<Publisher> *Provider::requestPublishers()
820 {
821  if (!isValid()) {
822  return nullptr;
823  }
824 
825  QUrl url = createUrl(QLatin1String("buildservice/publishing/getpublishingcapabilities"));
826  //qCDebug(ATTICA) << "request publishers" << url;
827  return new ListJob<Publisher>(d->m_internals, createRequest(url));
828 }
829 
830 ListJob<BuildServiceJob> *Provider::requestBuildServiceJobs(const Project &project)
831 {
832  if (!isValid()) {
833  return nullptr;
834  }
835 
836  //qCDebug(ATTICA) << "request projects";
837  QUrl url = createUrl(QLatin1String("buildservice/jobs/list/") + project.id());
838  return new ListJob<BuildServiceJob>(d->m_internals, createRequest(url));
839 }
840 
841 ListJob<RemoteAccount> *Provider::requestRemoteAccounts()
842 {
843  if (!isValid()) {
844  return nullptr;
845  }
846 
847  //qCDebug(ATTICA) << "request remoteaccounts";
848  QUrl url = createUrl(QLatin1String("buildservice/remoteaccounts/list/"));
849  return new ListJob<RemoteAccount>(d->m_internals, createRequest(url));
850 }
851 
852 PostJob *Provider::createRemoteAccount(const RemoteAccount &account)
853 {
854  if (!isValid()) {
855  return nullptr;
856  }
857 
858  StringMap postParameters;
859  // A postjob won't be run without parameters.
860  // so even while we don't need any in this case,
861  // we add dummy data to the request
862  postParameters.insert(QLatin1String("login"), account.login());
863  postParameters.insert(QLatin1String("password"), account.password());
864  postParameters.insert(QLatin1String("type"), account.type());
865  postParameters.insert(QLatin1String("typeid"), account.remoteServiceId()); // FIXME: remoteserviceid?
866  postParameters.insert(QLatin1String("data"), account.data());
867  //qCDebug(ATTICA) << "Creating new Remoteaccount" << account.id() << account.login() << account.password();
868  return new PostJob(d->m_internals, createRequest(QLatin1String("buildservice/remoteaccounts/add")),
869  postParameters);
870 }
871 
872 PostJob *Provider::editRemoteAccount(const RemoteAccount &account)
873 {
874  if (!isValid()) {
875  return nullptr;
876  }
877 
878  StringMap postParameters;
879  // A postjob won't be run without parameters.
880  // so even while we don't need any in this case,
881  // we add dummy data to the request
882  postParameters.insert(QLatin1String("login"), account.login());
883  postParameters.insert(QLatin1String("password"), account.password());
884  postParameters.insert(QLatin1String("type"), account.type());
885  postParameters.insert(QLatin1String("typeid"), account.remoteServiceId()); // FIXME: remoteserviceid?
886  postParameters.insert(QLatin1String("data"), account.data());
887  //qCDebug(ATTICA) << "Creating new Remoteaccount" << account.id() << account.login() << account.password();
888  return new PostJob(d->m_internals, createRequest(QLatin1String("buildservice/remoteaccounts/edit/") + account.id()),
889  postParameters);
890 }
891 
892 ItemJob<RemoteAccount> *Provider::requestRemoteAccount(const QString &id)
893 {
894  if (!isValid()) {
895  return nullptr;
896  }
897 
898  QUrl url = createUrl(QLatin1String("buildservice/remoteaccounts/get/") + id);
899  //qCDebug(ATTICA) << url;
900  return new ItemJob<RemoteAccount>(d->m_internals, createRequest(url));
901 }
902 
904 {
905  if (!isValid()) {
906  return nullptr;
907  }
908 
909  StringMap postParameters;
910  return new PostJob(d->m_internals, createRequest(
911  QLatin1String("buildservice/remoteaccounts/remove/") + id),
912  postParameters);
913 }
914 
915 PostJob *Provider::uploadTarballToBuildService(const QString &projectId, const QString &fileName, const QByteArray &payload)
916 {
917  if (!isValid()) {
918  return nullptr;
919  }
920 
921  QUrl url = createUrl(QLatin1String("buildservice/project/uploadsource/") + projectId);
922  //qCDebug(ATTICA) << "Up'ing tarball" << url << projectId << fileName << payload;
923  PostFileData postRequest(url);
924  postRequest.addFile(fileName, payload, QLatin1String("application/octet-stream"), QLatin1String("source"));
925  return new PostJob(d->m_internals, postRequest.request(), postRequest.data());
926 }
927 
928 // Activity
929 
930 PostJob *Provider::postActivity(const QString &message)
931 {
932  if (!isValid()) {
933  return nullptr;
934  }
935 
936  StringMap postParameters;
937  postParameters.insert(QLatin1String("message"), message);
938  return new PostJob(d->m_internals, createRequest(QLatin1String("activity")), postParameters);
939 }
940 
941 PostJob *Provider::inviteFriend(const QString &to, const QString &message)
942 {
943  if (!isValid()) {
944  return nullptr;
945  }
946 
947  StringMap postParameters;
948  postParameters.insert(QLatin1String("message"), message);
949  return new PostJob(d->m_internals, createRequest(QLatin1String("friend/invite/") + to), postParameters);
950 }
951 
952 PostJob *Provider::approveFriendship(const QString &to)
953 {
954  if (!isValid()) {
955  return nullptr;
956  }
957 
958  return new PostJob(d->m_internals, createRequest(QLatin1String("friend/approve/") + to));
959 }
960 
961 PostJob *Provider::declineFriendship(const QString &to)
962 {
963  if (!isValid()) {
964  return nullptr;
965  }
966 
967  return new PostJob(d->m_internals, createRequest(QLatin1String("friend/decline/") + to));
968 }
969 
970 PostJob *Provider::cancelFriendship(const QString &to)
971 {
972  if (!isValid()) {
973  return nullptr;
974  }
975 
976  return new PostJob(d->m_internals, createRequest(QLatin1String("friend/cancel/") + to));
977 }
978 
979 PostJob *Provider::postLocation(qreal latitude, qreal longitude, const QString &city, const QString &country)
980 {
981  if (!isValid()) {
982  return nullptr;
983  }
984 
985  StringMap postParameters;
986  postParameters.insert(QLatin1String("latitude"), QString::number(latitude));
987  postParameters.insert(QLatin1String("longitude"), QString::number(longitude));
988  postParameters.insert(QLatin1String("city"), city);
989  postParameters.insert(QLatin1String("country"), country);
990  return new PostJob(d->m_internals, createRequest(QLatin1String("person/self")), postParameters);
991 }
992 
993 ListJob<Folder> *Provider::requestFolders()
994 {
995  if (!isValid()) {
996  return nullptr;
997  }
998 
999  return doRequestFolderList(createUrl(QLatin1String("message")));
1000 }
1001 
1002 ListJob<Message> *Provider::requestMessages(const Folder &folder)
1003 {
1004  if (!isValid()) {
1005  return nullptr;
1006  }
1007 
1008  return doRequestMessageList(createUrl(QLatin1String("message/") + folder.id()));
1009 }
1010 
1011 ListJob<Message> *Provider::requestMessages(const Folder &folder, Message::Status status)
1012 {
1013  if (!isValid()) {
1014  return nullptr;
1015  }
1016 
1017  QUrl url = createUrl(QLatin1String("message/") + folder.id());
1018  QUrlQuery q(url);
1019  q.addQueryItem(QStringLiteral("status"), QString::number(status));
1020  url.setQuery(q);
1021  return doRequestMessageList(url);
1022 }
1023 
1024 ItemJob<Message> *Provider::requestMessage(const Folder &folder, const QString &id)
1025 {
1026  if (!isValid()) {
1027  return nullptr;
1028  }
1029 
1030  return new ItemJob<Message>(d->m_internals, createRequest(QLatin1String("message/") + folder.id() + QLatin1Char('/') + id));
1031 }
1032 
1033 PostJob *Provider::postMessage(const Message &message)
1034 {
1035  if (!isValid()) {
1036  return nullptr;
1037  }
1038 
1039  StringMap postParameters;
1040  postParameters.insert(QLatin1String("message"), message.body());
1041  postParameters.insert(QLatin1String("subject"), message.subject());
1042  postParameters.insert(QLatin1String("to"), message.to());
1043  return new PostJob(d->m_internals, createRequest(QLatin1String("message/2")), postParameters);
1044 }
1045 
1046 ListJob<Category> *Provider::requestCategories()
1047 {
1048  if (!isValid()) {
1049  return nullptr;
1050  }
1051 
1052  QUrl url = createUrl(QLatin1String("content/categories"));
1053  ListJob<Category> *job = new ListJob<Category>(d->m_internals, createRequest(url));
1054  return job;
1055 }
1056 
1057 ListJob< License > *Provider::requestLicenses()
1058 {
1059  if (!isValid()) {
1060  return nullptr;
1061  }
1062 
1063  QUrl url = createUrl(QLatin1String("content/licenses"));
1064  ListJob<License> *job = new ListJob<License>(d->m_internals, createRequest(url));
1065  return job;
1066 }
1067 
1068 ListJob< Distribution > *Provider::requestDistributions()
1069 {
1070  if (!isValid()) {
1071  return nullptr;
1072  }
1073 
1074  QUrl url = createUrl(QLatin1String("content/distributions"));
1075  ListJob<Distribution> *job = new ListJob<Distribution>(d->m_internals, createRequest(url));
1076  return job;
1077 }
1078 
1079 ListJob< HomePageType > *Provider::requestHomePageTypes()
1080 {
1081  if (!isValid()) {
1082  return nullptr;
1083  }
1084 
1085  QUrl url = createUrl(QLatin1String("content/homepages"));
1086  ListJob<HomePageType> *job = new ListJob<HomePageType>(d->m_internals, createRequest(url));
1087  return job;
1088 }
1089 
1090 ListJob<Content> *Provider::searchContents(const Category::List &categories, const QString &search, SortMode sortMode, uint page, uint pageSize)
1091 {
1092  return searchContents(categories, QString(), Distribution::List(), License::List(), search, sortMode, page, pageSize);
1093 }
1094 
1095 ListJob<Content> *Provider::searchContentsByPerson(const Category::List &categories, const QString &person, const QString &search, SortMode sortMode, uint page, uint pageSize)
1096 {
1097  return searchContents(categories, person, Distribution::List(), License::List(), search, sortMode, page, pageSize);
1098 }
1099 
1100 ListJob<Content> *Provider::searchContents(const Category::List &categories, const QString &person, const Distribution::List &distributions, const License::List &licenses, const QString &search, SortMode sortMode, uint page, uint pageSize)
1101 {
1102  if (!isValid()) {
1103  return nullptr;
1104  }
1105 
1106  QUrl url = createUrl(QStringLiteral("content/data"));
1107  QUrlQuery q(url);
1108  QStringList categoryIds;
1109  categoryIds.reserve(categories.count());
1110  for (const Category &category : categories) {
1111  categoryIds.append(category.id());
1112  }
1113  q.addQueryItem(QStringLiteral("categories"), categoryIds.join(QLatin1Char('x')));
1114 
1115  QStringList distributionIds;
1116  for (const Distribution &distribution : distributions) {
1117  distributionIds.append(QString(distribution.id()));
1118  }
1119  q.addQueryItem(QStringLiteral("distribution"), distributionIds.join(QLatin1Char(',')));
1120 
1121  QStringList licenseIds;
1122  for (const License &license : licenses) {
1123  licenseIds.append(QString(license.id()));
1124  }
1125  q.addQueryItem(QStringLiteral("license"), licenseIds.join(QLatin1Char(',')));
1126 
1127  if (!person.isEmpty()) {
1128  q.addQueryItem(QStringLiteral("user"), person);
1129  }
1130 
1131  q.addQueryItem(QStringLiteral("search"), search);
1132  QString sortModeString;
1133  switch (sortMode) {
1134  case Newest:
1135  sortModeString = QLatin1String("new");
1136  break;
1137  case Alphabetical:
1138  sortModeString = QLatin1String("alpha");
1139  break;
1140  case Rating:
1141  sortModeString = QLatin1String("high");
1142  break;
1143  case Downloads:
1144  sortModeString = QLatin1String("down");
1145  break;
1146  }
1147 
1148  if (!sortModeString.isEmpty()) {
1149  q.addQueryItem(QStringLiteral("sortmode"), sortModeString);
1150  }
1151 
1152  q.addQueryItem(QStringLiteral("page"), QString::number(page));
1153  q.addQueryItem(QStringLiteral("pagesize"), QString::number(pageSize));
1154 
1155  url.setQuery(q);
1156  ListJob<Content> *job = new ListJob<Content>(d->m_internals, createRequest(url));
1157  return job;
1158 }
1159 
1160 ItemJob<Content> *Provider::requestContent(const QString &id)
1161 {
1162  if (!isValid()) {
1163  return nullptr;
1164  }
1165 
1166  QUrl url = createUrl(QLatin1String("content/data/") + id);
1167  ItemJob<Content> *job = new ItemJob<Content>(d->m_internals, createRequest(url));
1168  return job;
1169 }
1170 
1171 ItemPostJob<Content> *Provider::addNewContent(const Category &category, const Content &cont)
1172 {
1173  if (!isValid() || !category.isValid()) {
1174  return nullptr;
1175  }
1176 
1177  QUrl url = createUrl(QLatin1String("content/add"));
1178  StringMap pars(cont.attributes());
1179 
1180  pars.insert(QLatin1String("type"), category.id());
1181  pars.insert(QLatin1String("name"), cont.name());
1182 
1183  //qCDebug(ATTICA) << "Parameter map: " << pars;
1184 
1185  return new ItemPostJob<Content>(d->m_internals, createRequest(url), pars);
1186 }
1187 
1188 ItemPostJob<Content> *Provider::editContent(const Category &updatedCategory, const QString &contentId, const Content &updatedContent)
1189 {
1190  if (!isValid()) {
1191  return nullptr;
1192  }
1193 
1194  // FIXME I get a server error message here, though the name of the item is changed
1195  QUrl url = createUrl(QLatin1String("content/edit/") + contentId);
1196  StringMap pars(updatedContent.attributes());
1197 
1198  pars.insert(QLatin1String("type"), updatedCategory.id());
1199  pars.insert(QLatin1String("name"), updatedContent.name());
1200 
1201  //qCDebug(ATTICA) << "Parameter map: " << pars;
1202 
1203  return new ItemPostJob<Content>(d->m_internals, createRequest(url), pars);
1204 }
1205 
1206 /*
1207 PostJob* Provider::setDownloadFile(const QString& contentId, QIODevice* payload)
1208 {
1209  QUrl url = createUrl("content/uploaddownload/" + contentId);
1210  PostFileData postRequest(url);
1211  // FIXME mime type
1212  //postRequest.addFile("localfile", payload, "application/octet-stream");
1213  postRequest.addFile("localfile", payload, "image/jpeg");
1214  return new PostJob(d->m_internals, postRequest.request(), postRequest.data());
1215 }
1216 */
1217 
1218 PostJob *Provider::deleteContent(const QString &contentId)
1219 {
1220  if (!isValid()) {
1221  return nullptr;
1222  }
1223 
1224  QUrl url = createUrl(QLatin1String("content/delete/") + contentId);
1225  PostFileData postRequest(url);
1226  postRequest.addArgument(QLatin1String("contentid"), contentId);
1227  return new PostJob(d->m_internals, postRequest.request(), postRequest.data());
1228 }
1229 
1230 PostJob *Provider::setDownloadFile(const QString &contentId, const QString &fileName, const QByteArray &payload)
1231 {
1232  if (!isValid()) {
1233  return nullptr;
1234  }
1235 
1236  QUrl url = createUrl(QLatin1String("content/uploaddownload/") + contentId);
1237  PostFileData postRequest(url);
1238  postRequest.addArgument(QLatin1String("contentid"), contentId);
1239  // FIXME mime type
1240  postRequest.addFile(fileName, payload, QLatin1String("application/octet-stream"));
1241  return new PostJob(d->m_internals, postRequest.request(), postRequest.data());
1242 }
1243 
1244 PostJob *Provider::deleteDownloadFile(const QString &contentId)
1245 {
1246  if (!isValid()) {
1247  return nullptr;
1248  }
1249 
1250  QUrl url = createUrl(QLatin1String("content/deletedownload/") + contentId);
1251  PostFileData postRequest(url);
1252  postRequest.addArgument(QLatin1String("contentid"), contentId);
1253  return new PostJob(d->m_internals, postRequest.request(), postRequest.data());
1254 }
1255 
1256 PostJob *Provider::setPreviewImage(const QString &contentId, const QString &previewId, const QString &fileName, const QByteArray &image)
1257 {
1258  if (!isValid()) {
1259  return nullptr;
1260  }
1261 
1262  QUrl url = createUrl(QLatin1String("content/uploadpreview/") + contentId + QLatin1Char('/') + previewId);
1263 
1264  PostFileData postRequest(url);
1265  postRequest.addArgument(QLatin1String("contentid"), contentId);
1266  postRequest.addArgument(QLatin1String("previewid"), previewId);
1267  // FIXME mime type
1268  postRequest.addFile(fileName, image, QLatin1String("application/octet-stream"));
1269 
1270  return new PostJob(d->m_internals, postRequest.request(), postRequest.data());
1271 }
1272 
1273 PostJob *Provider::deletePreviewImage(const QString &contentId, const QString &previewId)
1274 {
1275  if (!isValid()) {
1276  return nullptr;
1277  }
1278 
1279  QUrl url = createUrl(QLatin1String("content/deletepreview/") + contentId + QLatin1Char('/') + previewId);
1280  PostFileData postRequest(url);
1281  postRequest.addArgument(QLatin1String("contentid"), contentId);
1282  postRequest.addArgument(QLatin1String("previewid"), previewId);
1283  return new PostJob(d->m_internals, postRequest.request(), postRequest.data());
1284 }
1285 
1286 #if ATTICA_BUILD_DEPRECATED_SINCE(0, 2)
1287 PostJob *Provider::voteForContent(const QString &contentId, bool positiveVote)
1288 {
1289  if (!isValid()) {
1290  return nullptr;
1291  }
1292 
1293  StringMap postParameters;
1294  postParameters.insert(QLatin1String("vote"), positiveVote ? QLatin1String("good") : QLatin1String("bad"));
1295  //qCDebug(ATTICA) << "vote: " << positiveVote;
1296  return new PostJob(d->m_internals, createRequest(QLatin1String("content/vote/") + contentId), postParameters);
1297 }
1298 #endif
1299 
1300 PostJob *Provider::voteForContent(const QString &contentId, uint rating)
1301 {
1302  if (!isValid()) {
1303  return nullptr;
1304  }
1305 
1306  // according to OCS API, the rating is 0..100
1307  if (rating > 100) {
1308  qWarning() << "Rating cannot be superior to 100, fallback to 100.";
1309  rating = 100;
1310  }
1311 
1312  StringMap postParameters;
1313  postParameters.insert(QLatin1String("vote"), QString::number(rating));
1314  //qCDebug(ATTICA) << "vote: " << QString::number(rating);
1315  return new PostJob(d->m_internals, createRequest(QLatin1String("content/vote/") + contentId), postParameters);
1316 }
1317 
1318 PostJob *Provider::becomeFan(const QString &contentId)
1319 {
1320  if (!isValid()) {
1321  return nullptr;
1322  }
1323 
1324  QUrl url = createUrl(QLatin1String("fan/add/") + contentId);
1325  PostFileData postRequest(url);
1326  postRequest.addArgument(QLatin1String("contentid"), contentId);
1327  return new PostJob(d->m_internals, postRequest.request(), postRequest.data());
1328 }
1329 
1330 ListJob<Person> *Provider::requestFans(const QString &contentId, uint page, uint pageSize)
1331 {
1332  if (!isValid()) {
1333  return nullptr;
1334  }
1335 
1336  QUrl url = createUrl(QLatin1String("fan/data/") + contentId);
1337  QUrlQuery q(url);
1338  q.addQueryItem(QStringLiteral("contentid"), contentId);
1339  q.addQueryItem(QStringLiteral("page"), QString::number(page));
1340  q.addQueryItem(QStringLiteral("pagesize"), QString::number(pageSize));
1341  url.setQuery(q);
1342  ListJob<Person> *job = new ListJob<Person>(d->m_internals, createRequest(url));
1343  return job;
1344 }
1345 
1346 ListJob<Forum> *Provider::requestForums(uint page, uint pageSize)
1347 {
1348  if (!isValid()) {
1349  return nullptr;
1350  }
1351 
1352  QUrl url = createUrl(QStringLiteral("forum/list"));
1353  QUrlQuery q(url);
1354  q.addQueryItem(QStringLiteral("page"), QString::number(page));
1355  q.addQueryItem(QStringLiteral("pagesize"), QString::number(pageSize));
1356  url.setQuery(q);
1357 
1358  return doRequestForumList(url);
1359 }
1360 
1361 ListJob<Topic> *Provider::requestTopics(const QString &forum, const QString &search, const QString &description, Provider::SortMode mode, int page, int pageSize)
1362 {
1363  if (!isValid()) {
1364  return nullptr;
1365  }
1366 
1367  QUrl url = createUrl(QStringLiteral("forum/topics/list"));
1368  QUrlQuery q(url);
1369  q.addQueryItem(QStringLiteral("forum"), forum);
1370  q.addQueryItem(QStringLiteral("search"), search);
1371  q.addQueryItem(QStringLiteral("description"), description);
1372  QString sortModeString;
1373  switch (mode) {
1374  case Newest:
1375  sortModeString = QLatin1String("new");
1376  break;
1377  case Alphabetical:
1378  sortModeString = QLatin1String("alpha");
1379  break;
1380  default:
1381  break;
1382  }
1383  if (!sortModeString.isEmpty()) {
1384  q.addQueryItem(QStringLiteral("sortmode"), sortModeString);
1385  }
1386  q.addQueryItem(QStringLiteral("page"), QString::number(page));
1387  q.addQueryItem(QStringLiteral("pagesize"), QString::number(pageSize));
1388  url.setQuery(q);
1389 
1390  return doRequestTopicList(url);
1391 }
1392 
1393 PostJob *Provider::postTopic(const QString &forumId, const QString &subject, const QString &content)
1394 {
1395  if (!isValid()) {
1396  return nullptr;
1397  }
1398 
1399  StringMap postParameters;
1400  postParameters.insert(QLatin1String("subject"), subject);
1401  postParameters.insert(QLatin1String("content"), content);
1402  postParameters.insert(QLatin1String("forum"), forumId);
1403  return new PostJob(d->m_internals, createRequest(QLatin1String("forum/topic/add")), postParameters);
1404 }
1405 
1406 ItemJob<DownloadItem> *Provider::downloadLink(const QString &contentId, const QString &itemId)
1407 {
1408  if (!isValid()) {
1409  return nullptr;
1410  }
1411 
1412  QUrl url = createUrl(QLatin1String("content/download/") + contentId + QLatin1Char('/') + itemId);
1413  ItemJob<DownloadItem> *job = new ItemJob<DownloadItem>(d->m_internals, createRequest(url));
1414  return job;
1415 }
1416 
1417 ItemJob<KnowledgeBaseEntry> *Provider::requestKnowledgeBaseEntry(const QString &id)
1418 {
1419  if (!isValid()) {
1420  return nullptr;
1421  }
1422 
1423  QUrl url = createUrl(QLatin1String("knowledgebase/data/") + id);
1424  ItemJob<KnowledgeBaseEntry> *job = new ItemJob<KnowledgeBaseEntry>(d->m_internals, createRequest(url));
1425  return job;
1426 }
1427 
1428 ListJob<KnowledgeBaseEntry> *Provider::searchKnowledgeBase(const Content &content, const QString &search, Provider::SortMode sortMode, int page, int pageSize)
1429 {
1430  if (!isValid()) {
1431  return nullptr;
1432  }
1433 
1434  QUrl url = createUrl(QStringLiteral("knowledgebase/data"));
1435  QUrlQuery q(url);
1436  if (content.isValid()) {
1437  q.addQueryItem(QStringLiteral("content"), content.id());
1438  }
1439 
1440  q.addQueryItem(QStringLiteral("search"), search);
1441  QString sortModeString;
1442  switch (sortMode) {
1443  case Newest:
1444  sortModeString = QLatin1String("new");
1445  break;
1446  case Alphabetical:
1447  sortModeString = QLatin1String("alpha");
1448  break;
1449  case Rating:
1450  sortModeString = QLatin1String("high");
1451  break;
1452  //FIXME: knowledge base doesn't have downloads
1453  case Downloads:
1454  sortModeString = QLatin1String("new");
1455  break;
1456  }
1457  if (!sortModeString.isEmpty()) {
1458  q.addQueryItem(QStringLiteral("sortmode"), sortModeString);
1459  }
1460 
1461  q.addQueryItem(QStringLiteral("page"), QString::number(page));
1462  q.addQueryItem(QStringLiteral("pagesize"), QString::number(pageSize));
1463  url.setQuery(q);
1464 
1465  ListJob<KnowledgeBaseEntry> *job = new ListJob<KnowledgeBaseEntry>(d->m_internals, createRequest(url));
1466  return job;
1467 }
1468 
1469 ItemJob<Event> *Provider::requestEvent(const QString &id)
1470 {
1471  if (!isValid()) {
1472  return nullptr;
1473  }
1474 
1475  ItemJob<Event> *job = new ItemJob<Event>(d->m_internals, createRequest(QLatin1String("event/data/") + id));
1476  return job;
1477 }
1478 
1479 ListJob<Event> *Provider::requestEvent(const QString &country, const QString &search, const QDate &startAt, Provider::SortMode mode, int page, int pageSize)
1480 {
1481  if (!isValid()) {
1482  return nullptr;
1483  }
1484 
1485  QUrl url = createUrl(QStringLiteral("event/data"));
1486  QUrlQuery q(url);
1487 
1488  if (!search.isEmpty()) {
1489  q.addQueryItem(QStringLiteral("search"), search);
1490  }
1491 
1492  QString sortModeString;
1493  switch (mode) {
1494  case Newest:
1495  sortModeString = QLatin1String("new");
1496  break;
1497  case Alphabetical:
1498  sortModeString = QLatin1String("alpha");
1499  break;
1500  default:
1501  break;
1502  }
1503  if (!sortModeString.isEmpty()) {
1504  q.addQueryItem(QStringLiteral("sortmode"), sortModeString);
1505  }
1506 
1507  if (!country.isEmpty()) {
1508  q.addQueryItem(QStringLiteral("country"), country);
1509  }
1510 
1511  q.addQueryItem(QStringLiteral("startat"), startAt.toString(Qt::ISODate));
1512 
1513  q.addQueryItem(QStringLiteral("page"), QString::number(page));
1514  q.addQueryItem(QStringLiteral("pagesize"), QString::number(pageSize));
1515  url.setQuery(q);
1516 
1517  ListJob<Event> *job = new ListJob<Event>(d->m_internals, createRequest(url));
1518  return job;
1519 }
1520 
1521 ListJob<Comment> *Provider::requestComments(const Comment::Type commentType, const QString &id, const QString &id2, int page, int pageSize)
1522 {
1523  if (!isValid()) {
1524  return nullptr;
1525  }
1526 
1527  QString commentTypeString;
1528  commentTypeString = Comment::commentTypeToString(commentType);
1529  if (commentTypeString.isEmpty()) {
1530  return nullptr;
1531  }
1532 
1533  QUrl url = createUrl(QLatin1String("comments/data/") + commentTypeString + QLatin1Char('/') + id + QLatin1Char('/') + id2);
1534 
1535  QUrlQuery q(url);
1536  q.addQueryItem(QStringLiteral("page"), QString::number(page));
1537  q.addQueryItem(QStringLiteral("pagesize"), QString::number(pageSize));
1538  url.setQuery(q);
1539 
1540  ListJob<Comment> *job = new ListJob<Comment>(d->m_internals, createRequest(url));
1541  return job;
1542 }
1543 
1544 ItemPostJob<Comment> *Provider::addNewComment(const Comment::Type commentType, const QString &id, const QString &id2, const QString &parentId, const QString &subject, const QString &message)
1545 {
1546  if (!isValid()) {
1547  return nullptr;
1548  }
1549 
1550  QString commentTypeString;
1551  commentTypeString = Comment::commentTypeToString(commentType);
1552  if (commentTypeString.isEmpty()) {
1553  return nullptr;
1554  }
1555 
1556  QMap<QString, QString> postParameters;
1557 
1558  postParameters.insert(QLatin1String("type"), commentTypeString);
1559  postParameters.insert(QLatin1String("content"), id);
1560  postParameters.insert(QLatin1String("content2"), id2);
1561  postParameters.insert(QLatin1String("parent"), parentId);
1562  postParameters.insert(QLatin1String("subject"), subject);
1563  postParameters.insert(QLatin1String("message"), message);
1564 
1565  return new ItemPostJob<Comment>(d->m_internals, createRequest(QLatin1String("comments/add")), postParameters);
1566 }
1567 
1568 PostJob *Provider::voteForComment(const QString &id, uint rating)
1569 {
1570  if (!isValid() || (rating > 100)) {
1571  return nullptr;
1572  }
1573 
1574  QMap<QString, QString> postParameters;
1575  postParameters.insert(QLatin1String("vote"), QString::number(rating));
1576 
1577  QUrl url = createUrl(QLatin1String("comments/vote/") + id);
1578  return new PostJob(d->m_internals, createRequest(url), postParameters);
1579 }
1580 
1581 PostJob *Provider::setPrivateData(const QString &app, const QString &key, const QString &value)
1582 {
1583  if (!isValid()) {
1584  return nullptr;
1585  }
1586 
1587  QUrl url = createUrl(QLatin1String("privatedata/setattribute/") + app + QLatin1Char('/') + key);
1588  PostFileData postRequest(url);
1589 
1590  postRequest.addArgument(QLatin1String("value"), value);
1591 
1592  return new PostJob(d->m_internals, postRequest.request(), postRequest.data());
1593 }
1594 
1595 ItemJob<PrivateData> *Provider::requestPrivateData(const QString &app, const QString &key)
1596 {
1597  if (!isValid()) {
1598  return nullptr;
1599  }
1600 
1601  ItemJob<PrivateData> *job = new ItemJob<PrivateData>(d->m_internals, createRequest(QLatin1String("privatedata/getattribute/") + app + QLatin1Char('/') + key));
1602  return job;
1603 }
1604 
1605 QUrl Provider::createUrl(const QString &path)
1606 {
1607  QUrl url(d->m_baseUrl.toString() + path);
1608  return url;
1609 }
1610 
1611 QNetworkRequest Provider::createRequest(const QUrl &url)
1612 {
1613  QNetworkRequest request(url);
1614  request.setHeader(QNetworkRequest::ContentTypeHeader,QStringLiteral("application/x-www-form-urlencoded"));
1615 
1616  QString agentHeader;
1618  agentHeader = QString::fromLocal8Bit("%1/%2").arg(QCoreApplication::instance()->applicationName(), QCoreApplication::instance()->applicationVersion());
1619  } else {
1620  agentHeader = QString::fromLocal8Bit("Attica/%1").arg(QLatin1String(LIBATTICA_VERSION_STRING));
1621  }
1622  if (!d->m_additionalAgentInformation.isEmpty()) {
1623  agentHeader = QString::fromLocal8Bit("%1 (+%2)").arg(agentHeader, d->m_additionalAgentInformation);
1624  }
1625  request.setHeader(QNetworkRequest::UserAgentHeader, agentHeader);
1626 
1627  if (!d->m_credentialsUserName.isEmpty()) {
1628  request.setAttribute((QNetworkRequest::Attribute) BaseJob::UserAttribute, QVariant(d->m_credentialsUserName));
1629  request.setAttribute((QNetworkRequest::Attribute) BaseJob::PasswordAttribute, QVariant(d->m_credentialsPassword));
1630  }
1631  return request;
1632 }
1633 
1634 QNetworkRequest Provider::createRequest(const QString &path)
1635 {
1636  return createRequest(createUrl(path));
1637 }
1638 
1639 ItemJob<Config>* Provider::doRequestConfig(const QUrl& url)
1640 {
1641  return new ItemJob<Config>(d->m_internals, createRequest(url));
1642 }
1643 
1644 ItemJob<Person> *Provider::doRequestPerson(const QUrl &url)
1645 {
1646  return new ItemJob<Person>(d->m_internals, createRequest(url));
1647 }
1648 
1649 ItemJob<AccountBalance> *Provider::doRequestAccountBalance(const QUrl &url)
1650 {
1651  return new ItemJob<AccountBalance>(d->m_internals, createRequest(url));
1652 }
1653 
1654 ListJob<Person> *Provider::doRequestPersonList(const QUrl &url)
1655 {
1656  return new ListJob<Person>(d->m_internals, createRequest(url));
1657 }
1658 
1659 ListJob<Achievement> *Provider::doRequestAchievementList(const QUrl &url)
1660 {
1661  return new ListJob<Achievement>(d->m_internals, createRequest(url));
1662 }
1663 
1664 ListJob<Activity> *Provider::doRequestActivityList(const QUrl &url)
1665 {
1666  return new ListJob<Activity>(d->m_internals, createRequest(url));
1667 }
1668 
1669 ListJob<Folder> *Provider::doRequestFolderList(const QUrl &url)
1670 {
1671  return new ListJob<Folder>(d->m_internals, createRequest(url));
1672 }
1673 
1674 ListJob<Forum> *Provider::doRequestForumList(const QUrl &url)
1675 {
1676  return new ListJob<Forum>(d->m_internals, createRequest(url));
1677 }
1678 
1679 ListJob<Topic> *Provider::doRequestTopicList(const QUrl &url)
1680 {
1681  return new ListJob<Topic>(d->m_internals, createRequest(url));
1682 }
1683 
1684 ListJob<Message> *Provider::doRequestMessageList(const QUrl &url)
1685 {
1686  return new ListJob<Message>(d->m_internals, createRequest(url));
1687 }
1688 
1690 {
1691  return d->m_achievementVersion;
1692 }
1693 
1695 {
1696  return d->m_activityVersion;
1697 }
1699 {
1700  return d->m_commentVersion;
1701 }
1703 {
1704  return d->m_contentVersion;
1705 }
1707 {
1708  return d->m_fanVersion;
1709 }
1711 {
1712  return d->m_forumVersion;
1713 }
1715 {
1716  return d->m_friendVersion;
1717 }
1719 {
1720  return d->m_knowledgebaseVersion;
1721 }
1723 {
1724  return d->m_messageVersion;
1725 }
1727 {
1728  return d->m_personVersion;
1729 }
1730 
1732 {
1733  return !d->m_achievementVersion.isEmpty();
1734 }
1735 
1737 {
1738  return !d->m_activityVersion.isEmpty();
1739 }
1741 {
1742  return !d->m_commentVersion.isEmpty();
1743 }
1745 {
1746  return !d->m_contentVersion.isEmpty();
1747 }
1749 {
1750  return !d->m_fanVersion.isEmpty();
1751 }
1753 {
1754  return !d->m_forumVersion.isEmpty();
1755 }
1757 {
1758  return !d->m_friendVersion.isEmpty();
1759 }
1761 {
1762  return !d->m_knowledgebaseVersion.isEmpty();
1763 }
1765 {
1766  return !d->m_messageVersion.isEmpty();
1767 }
1769 {
1770  return !d->m_personVersion.isEmpty();
1771 }
Represents a single content.
Definition: content.h:31
PostJob * setPreviewImage(const QString &contentId, const QString &previewId, const QString &fileName, const QByteArray &image)
Upload an image file as preview for the content.
Definition: provider.cpp:1256
QString toString(Qt::DateFormat format) const const
The Distribution class contains information about one distribution that the server offers...
Definition: distribution.h:24
bool isEnabled() const
Test if the provider is enabled by the settings.
Definition: provider.cpp:234
ListJob< Content > * searchContents(const Category::List &categories, const QString &search=QString(), SortMode mode=Rating, uint page=0, uint pageSize=10)
Request a list of Contents.
Definition: provider.cpp:1090
DeleteJob * deleteAchievement(const QString &contentId, const QString &achievementId)
Deletes an achievement on the server.
Definition: provider.cpp:541
QString name() const
A name for the provider that can be displayed to the user.
Definition: provider.cpp:260
ItemJob< RemoteAccount > * requestRemoteAccount(const QString &id)
Get a remote account by its ID.
Definition: provider.cpp:892
QString toString(Qt::DateFormat format) const const
QString id() const
Gets the id of the Folder.
Definition: folder.cpp:52
Rating
PostJob * createBuildServiceJob(const BuildServiceJob &job)
Create a new job for a given project on a given buildservice for a given target.
Definition: provider.cpp:790
void reserve(int alloc)
QString forumServiceVersion() const
Version of the forum part of the API.
Definition: provider.cpp:1710
bool hasContentService() const
Test if the server supports the content part of the API.
Definition: provider.cpp:1744
PostJob * deleteRemoteAccount(const QString &id)
Deletes a remote account stored on the OCS server.
Definition: provider.cpp:903
Represents a single content category.
Definition: category.h:22
QDebug & nospace()
ListJob< Project > * requestProjects()
Get a list of build service projects.
Definition: provider.cpp:592
QString join(const QString &separator) const const
PostJob * publishBuildJob(const BuildServiceJob &buildjob, const Publisher &publisher)
Publish the result of a completed build job to a publisher.
Definition: provider.cpp:719
QString contentServiceVersion() const
Version of the content part of the API.
Definition: provider.cpp:1702
bool isEmpty() const const
QString personServiceVersion() const
Version of the person part of the API.
Definition: provider.cpp:1726
bool hasKnowledgebaseService() const
Test if the server supports the knowledgebase part of the API.
Definition: provider.cpp:1760
ListJob< Publisher > * requestPublishers()
Get a list of publishers.
Definition: provider.cpp:819
bool hasForumService() const
Test if the server supports the forum part of the API.
Definition: provider.cpp:1752
PostJob * editRemoteAccount(const RemoteAccount &account)
Edit an existing remote account.
Definition: provider.cpp:872
ItemJob< Config > * requestConfig()
Fetches server config.
Definition: provider.cpp:322
bool saveCredentials(const QString &user, const QString &password)
Sets (and remembers) user name and password for this provider.
Definition: provider.cpp:297
void addQueryItem(const QString &key, const QString &value)
PostJob * cancelBuildServiceJob(const BuildServiceJob &job)
Cancel a job.
Definition: provider.cpp:777
QString number(int n, int base)
int count(const T &value) const const
QString fromLocal8Bit(const char *str, int size)
ItemJob< BuildServiceJobOutput > * requestBuildServiceJobOutput(const QString &id)
Get the build output for a specific build service job.
Definition: provider.cpp:735
void append(const T &value)
ItemJob< Publisher > * requestPublisher(const QString &id)
Get the information for a specific publisher.
Definition: provider.cpp:692
bool hasCommentService() const
Test if the server supports the comments part of the API.
Definition: provider.cpp:1740
bool hasFriendService() const
Test if the server supports the friend part of the API.
Definition: provider.cpp:1756
void setAdditionalAgentInformation(const QString &additionalInformation)
Set a custom identifier for your application (sent along with the requests as the http agent header i...
Definition: provider.cpp:252
bool isEmpty() const const
bool isValid() const
Returns true if the provider has been set up and can be used.
Definition: provider.cpp:229
bool isValid() const
Checks whether this Content has an id.
Definition: content.cpp:144
bool loadCredentials(QString &user, QString &password)
Load user name and password from the store.
Definition: provider.cpp:283
QCoreApplication * instance()
QString id() const
Gets the id of the Content.
Definition: content.cpp:64
PostJob * setPrivateData(const QString &app, const QString &key, const QString &value)
Sets the value of an attribute.
Definition: provider.cpp:1581
bool hasAchievementService() const
Test if the server supports the achievement part of the API.
Definition: provider.cpp:1731
ListJob< License > * requestLicenses()
Get a list of licenses (such as GPL)
Definition: provider.cpp:1057
PutJob * editAchievement(const QString &contentId, const QString &achievementId, const Achievement &achievement)
Post modifications to an Achievement on the server.
Definition: provider.cpp:506
QString commentServiceVersion() const
Version of the comments part of the API.
Definition: provider.cpp:1698
bool hasPersonService() const
Test if the server supports the person part of the API.
Definition: provider.cpp:1768
QDebug & space()
bool hasMessageService() const
Test if the server supports the message part of the API.
Definition: provider.cpp:1764
void setHeader(QNetworkRequest::KnownHeaders header, const QVariant &value)
QString achievementServiceVersion() const
Version of the achievement part of the API.
Definition: provider.cpp:1689
QString knowledgebaseServiceVersion() const
Version of the knowledgebase part of the API.
Definition: provider.cpp:1718
QString friendServiceVersion() const
Version of the friend part of the API.
Definition: provider.cpp:1714
QString id() const
Gets the id of the Category.
Definition: category.cpp:55
QString fanServiceVersion() const
Version of the fan part of the API.
Definition: provider.cpp:1706
PostJob * createProject(const Project &project)
Post modifications to a Project on the server.
Definition: provider.cpp:650
QDataStream & operator<<(QDataStream &out, const KDateTime::Spec &spec)
const char * data() const const
ListJob< BuildServiceJob > * requestBuildServiceJobs(const Project &project)
Get a list of build service projects.
Definition: provider.cpp:830
bool isValid() const
Checks whether this Category has an id.
Definition: category.cpp:80
ListJob< Distribution > * requestDistributions()
Get a list of distributions (such as Ark, Debian)
Definition: provider.cpp:1068
QString name() const
Gets the name of the Content.
Definition: content.cpp:74
PostJob * voteForComment(const QString &id, uint rating)
Vote a comment item.
Definition: provider.cpp:1568
The Provider class represents one Open Collaboration Service provider.
Definition: provider.h:95
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
Attica::PostJob * uploadTarballToBuildService(const QString &projectId, const QString &fileName, const QByteArray &payload)
Upload a tarball to the buildservice.
Definition: provider.cpp:915
The License class contains information about one license that the server offers.
Definition: license.h:21
void setAttribute(QNetworkRequest::Attribute code, const QVariant &value)
PostJob * savePublisherField(const Project &project, const PublisherField &field)
Save the value of a single publishing field.
Definition: provider.cpp:703
void setQuery(const QString &query, QUrl::ParsingMode mode)
ItemPostJob< Comment > * addNewComment(const Comment::Type commentType, const QString &id, const QString &id2, const QString &parentId, const QString &subject, const QString &message)
Add a new comment.
Definition: provider.cpp:1544
bool hasFanService() const
Test if the server supports the fan part of the API.
Definition: provider.cpp:1748
PostJob * createRemoteAccount(const RemoteAccount &account)
Create a new remote account, an account for a build service instance which is stored in the OCS servi...
Definition: provider.cpp:852
QString fromLatin1(const char *str, int size)
ListJob< Category > * requestCategories()
Get a list of categories (such as wallpaper)
Definition: provider.cpp:1046
ItemJob< BuildServiceJob > * requestBuildServiceJob(const QString &id)
Get the information for a specific build service job, such as status and progress.
Definition: provider.cpp:746
QMap::iterator insert(const Key &key, const T &value)
QMap< QString, QString > attributes() const
Get all attributes that are not included in the basis set of attributes exposed by the Content class...
Definition: content.cpp:139
bool hasCredentials() const
Test if the provider has user name/password available.
Definition: provider.cpp:274
QString messageServiceVersion() const
Version of the message part of the API.
Definition: provider.cpp:1722
ItemJob< Content > * requestContent(const QString &contentId)
Retrieve a single content.
Definition: provider.cpp:1160
PostJob * deleteProject(const Project &project)
Deletes a project on the server.
Definition: provider.cpp:671
PostJob * voteForContent(const QString &contentId, bool positiveVote)
Vote for a content item This version is for the old OCS API < 1.6.
Definition: provider.cpp:1287
PostJob * editProject(const Project &project)
Post modifications to a Project on the server.
Definition: provider.cpp:660
QUrl baseUrl() const
A url that identifies this provider.
Definition: provider.cpp:224
ItemJob< PrivateData > * requestPrivateData()
Fetches all stored private data.
Definition: provider.h:318
ListJob< Content > * searchContentsByPerson(const Category::List &categories, const QString &person, const QString &search=QString(), SortMode mode=Rating, uint page=0, uint pageSize=10)
Request a list of Contents.
Definition: provider.cpp:1095
QString toString() const const
ListJob< BuildService > * requestBuildServices()
Get a list of build service build services.
Definition: provider.cpp:808
ListJob< Achievement > * requestAchievements(const QString &contentId, const QString &achievementId, const QString &userId)
Get a list of achievements.
Definition: provider.cpp:462
ItemPostJob< Achievement > * addNewAchievement(const QString &id, const Achievement &newAchievement)
Add a new achievement.
Definition: provider.cpp:475
ListJob< RemoteAccount > * requestRemoteAccounts()
Get a list of remote accounts, account for a build service instance which is stored in the OCS servic...
Definition: provider.cpp:841
Represents a single mail folder.
Definition: folder.h:23
ListJob< HomePageType > * requestHomePageTypes()
Get a list of home page types (such as blog, Facebook)
Definition: provider.cpp:1079
bool hasActivityService() const
Test if the server supports the activity part of the API.
Definition: provider.cpp:1736
QString activityServiceVersion() const
Version of the activity part of the API.
Definition: provider.cpp:1694
ItemJob< Project > * requestProject(const QString &id)
Get a Project&#39;s data.
Definition: provider.cpp:603
ItemJob< BuildService > * requestBuildService(const QString &id)
Get the information for a specific build service instance.
Definition: provider.cpp:682
QString additionalAgentInformation() const
The custom identifier sent along with requests.
Definition: provider.cpp:256
PostJob * checkLogin(const QString &user, const QString &password)
Test if the server accepts the login/password.
Definition: provider.cpp:308
ListJob< Comment > * requestComments(const Comment::Type commentType, const QString &id, const QString &id2, int page, int pageSize)
Request a list of comments for a content / forum / knowledgebase / event.
Definition: provider.cpp:1521
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Tue Aug 11 2020 23:03:44 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.