Kgapi

contactcreatejob.cpp
1 /*
2  * This file is part of LibKGAPI library
3  *
4  * SPDX-FileCopyrightText: 2013 Daniel Vrátil <[email protected]>
5  *
6  * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
7  */
8 
9 #include "contactcreatejob.h"
10 #include "contact.h"
11 #include "contactsservice.h"
12 #include "utils.h"
13 #include "../debug.h"
14 #include "account.h"
15 #include "private/queuehelper_p.h"
16 
17 #include <QNetworkRequest>
18 #include <QNetworkReply>
19 
20 using namespace KGAPI2;
21 
22 class Q_DECL_HIDDEN ContactCreateJob::Private
23 {
24  public:
25  Private(ContactCreateJob *parent);
26  void processNextContact();
27  void setPhoto(const KContacts::Picture &photo, const QString &uid);
28 
29  QueueHelper<ContactPtr> contacts;
30  ContactPtr lastContact;
31  QPair<QByteArray, QString> pendingPhoto;
32  private:
33  ContactCreateJob * const q;
34 };
35 
36 ContactCreateJob::Private::Private(ContactCreateJob *parent):
37  q(parent)
38 {
39 }
40 
41 void ContactCreateJob::Private::processNextContact()
42 {
43  if (contacts.atEnd()) {
44  if (pendingPhoto.first.isEmpty()) {
45  q->emitFinished();
46  }
47  return;
48  }
49 
50  const ContactPtr contact = contacts.current();
51  const QUrl url = ContactsService::createContactUrl(q->account()->accountName());
52  QNetworkRequest request(url);
53  request.setRawHeader("GData-Version", ContactsService::APIVersion().toLatin1());
54 
55  QByteArray rawData = ContactsService::contactToXML(contact);
56  rawData.prepend("<atom:entry xmlns:atom=\"http://www.w3.org/2005/Atom\" "
57  "xmlns:gd=\"http://schemas.google.com/g/2005\" "
58  "xmlns:gContact=\"http://schemas.google.com/contact/2008\">"
59  "<atom:category scheme=\"http://schemas.google.com/g/2005#kind\" "
60  "term=\"http://schemas.google.com/contact/2008#contact\"/>");
61  rawData.append("</atom:entry>");
62 
63  QStringList headers;
64  auto rawHeaderList = request.rawHeaderList();
65  headers.reserve(rawHeaderList.size());
66  for (const QByteArray &str : qAsConst(rawHeaderList)) {
67  headers << QLatin1String(str) + QLatin1String(": ") + QLatin1String(request.rawHeader(str));
68  }
69 
70  q->enqueueRequest(request, rawData, QStringLiteral("application/atom+xml"));
71 }
72 
73 void ContactCreateJob::Private::setPhoto(const KContacts::Picture &photo, const QString &uid)
74 {
75  const QUrl url = ContactsService::photoUrl(q->account()->accountName(), uid);
76  QNetworkRequest photoRequest(url);
77  photoRequest.setHeader(QNetworkRequest::ContentTypeHeader, QLatin1String("image/*"));
78  pendingPhoto.first = photo.rawData();
79  pendingPhoto.second = photo.type();
80  q->enqueueRequest(photoRequest, pendingPhoto.first, QStringLiteral("modifyImage"));
81 }
82 
83 ContactCreateJob::ContactCreateJob(const ContactsList& contacts, const AccountPtr& account, QObject* parent):
84  CreateJob(account, parent),
85  d(new Private(this))
86 {
87  d->contacts = contacts;
88 }
89 
91  CreateJob(account, parent),
92  d(new Private(this))
93 {
94  d->contacts << contact;
95 }
96 
98 {
99  delete d;
100 }
101 
103 {
104  d->processNextContact();
105 }
106 
107 void ContactCreateJob::dispatchRequest(QNetworkAccessManager *accessManager, const QNetworkRequest &request, const QByteArray &data, const QString &contentType)
108 {
109  QNetworkRequest r = request;
110 
111  if (contentType == QLatin1String("modifyImage")) {
112  accessManager->put(r, data);
113  } else {
115  accessManager->post(r, data);
116  }
117 }
118 
120 {
122  if (!reply->url().path().contains(QLatin1String("/photos/media/"))) {
123  const QString contentType = reply->header(QNetworkRequest::ContentTypeHeader).toString();
124  ContentType ct = Utils::stringToContentType(contentType);
125  if (ct == KGAPI2::JSON) {
126  d->lastContact = ContactsService::JSONToContact(rawData);
127  items << d->lastContact.dynamicCast<Object>();
128  } else if (ct == KGAPI2::XML) {
129  d->lastContact = ContactsService::XMLToContact(rawData);
130  items << d->lastContact.dynamicCast<Object>();
131  } else {
133  setErrorString(tr("Invalid response content type"));
134  emitFinished();
135  return items;
136  }
137  if (!d->contacts.current()->photo().isEmpty()) {
138  // current contact does not have uid populated
139  d->setPhoto(d->contacts.current()->photo(), d->lastContact->uid());
140  d->contacts.currentProcessed();
141  } else {
142  d->contacts.currentProcessed();
143  d->processNextContact();
144  }
145  } else {
146  if (d->lastContact) {
147  KContacts::Picture picture;
148  picture.setRawData(d->pendingPhoto.first, d->pendingPhoto.second);
149  d->lastContact->setPhoto(picture);
150  d->pendingPhoto.first.clear();
151  d->pendingPhoto.second.clear();
152  }
153  // Enqueue next item or finish
154  d->processNextContact();
155  }
156  return items;
157 }
158 
159 
QNetworkReply * put(const QNetworkRequest &request, QIODevice *data)
AccountPtr account() const
Returns account used to authenticate requests.
Definition: job.cpp:425
QString type() const
virtual ObjectsList items() const
Definition: createjob.cpp:40
ContactPtr XMLToContact(const QByteArray &xmlData)
Parses XML data into Contact object.
Base class for all objects.
Definition: object.h:30
Abstract superclass for all jobs that create new objects on the server.
Definition: createjob.h:24
void reserve(int alloc)
QString uid() const
ContactCreateJob(const ContactPtr &contact, const AccountPtr &account, QObject *parent=nullptr)
Constructs a job that will create given contact in user&#39;s addressbook.
QString APIVersion()
Supported API version.
~ContactCreateJob() override
Destructor.
void dispatchRequest(QNetworkAccessManager *accessManager, const QNetworkRequest &request, const QByteArray &data, const QString &contentType) override
KGAPI2::Job::dispatchRequest implementation.
QString tr(const char *sourceText, const char *disambiguation, int n)
QByteArray contactToXML(const ContactPtr &contact)
Serializes a Contact object into XML.
A job to create one or more new contacts in Google Contacts addressbook.
ResourceLocatorUrl url() const
QUrl createContactUrl(const QString &user)
Returns URL for creating contacts.
QUrl photoUrl(const QString &user, const QString &contactID)
Returns URL for modifying photo.
QNetworkReply * post(const QNetworkRequest &request, QIODevice *data)
QByteArray & prepend(char ch)
A job to fetch a single map tile described by a StaticMapUrl.
Definition: blog.h:15
QString path(QUrl::ComponentFormattingOptions options) const const
Picture photo() const
ObjectsList handleReplyWithItems(const QNetworkReply *reply, const QByteArray &rawData) override
KGAPI2::Job::handleReply implementation.
QByteArray & append(char ch)
ContactPtr JSONToContact(const QByteArray &jsonData)
Parses JSON data into Contact object.
LibKGAPI error - Google returned invalid response.
Definition: types.h:179
QByteArray rawData() const
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
void setHeader(QNetworkRequest::KnownHeaders header, const QVariant &value)
QVariant header(QNetworkRequest::KnownHeaders header) const const
virtual void emitFinished()
Emits Job::finished() signal.
Definition: job.cpp:479
void setErrorString(const QString &errorString)
Set job error description to errorString.
Definition: job.cpp:390
void setRawData(const QByteArray &rawData, const QString &type)
QUrl url() const const
void setError(KGAPI2::Error error)
Set job error to error.
Definition: job.cpp:375
void start() override
KGAPI2::Job::start implementation.
QObject * parent() const const
QString toString() const const
ContentType
Definition: types.h:206
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Tue May 11 2021 23:10:35 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.