Commit 7de9af3d authored by Igor Poboiko's avatar Igor Poboiko
Browse files

[contacts] Fix ContactCreateJob with a photo

When we run `ContactCreateJob`, the UID of a contact is not yet known.
We can only add a photo only after we receive a reply from main create job.

Also, since we also don't want the following race condition to trigger:
 1) Contact1 create request
 2) Contact1 reply, Photo1 change request, Contact2 create request
 3) Contact2 reply, Photo2 change request
 4) Photo1 reply (here both `currentContact` and `lastContact` is Contact2)
 5) Photo2 reply
we only go for next contact after the previous has been fully procesed:
 1) Contact1 create request
 2) Contact1 reply, Photo1 change request
 3) Photo1 reply, Contact2 create request
 4) Contact2 reply, Photo2 change request
 5) Photo2 reply

Test Plan:
Without patch:
 1) Create a contact with photo inside KAddressBook
 2) Check Web UI: no photo is set, sometimes bunch of contacts get created (?)
With patch:
 2) Observe a single contact with a proper photo being set

Reviewers: dvratil

Reviewed By: dvratil

Subscribers: kde-pim

Tags: #kde_pim

Differential Revision:
parent e999f481
......@@ -40,6 +40,7 @@ class Q_DECL_HIDDEN ContactCreateJob::Private
Private(ContactCreateJob *parent);
void processNextContact();
void setPhoto(const KContacts::Picture &photo, const QString &uid);
QueueHelper<ContactPtr> contacts;
ContactPtr lastContact;
......@@ -83,15 +84,16 @@ void ContactCreateJob::Private::processNextContact()
q->enqueueRequest(request, rawData, QStringLiteral("application/atom+xml"));
if (!contact->photo().isEmpty()) {
const QUrl url = ContactsService::photoUrl(q->account()->accountName(), contact->uid());
void ContactCreateJob::Private::setPhoto(const KContacts::Picture &photo, const QString &uid)
const QUrl url = ContactsService::photoUrl(q->account()->accountName(), uid);
QNetworkRequest photoRequest(url);
photoRequest.setHeader(QNetworkRequest::ContentTypeHeader, QLatin1String("image/*"));
pendingPhoto.first = contact->photo().rawData();
pendingPhoto.second = contact->photo().type();
pendingPhoto.first = photo.rawData();
pendingPhoto.second = photo.type();
q->enqueueRequest(photoRequest, pendingPhoto.first, QStringLiteral("modifyImage"));
ContactCreateJob::ContactCreateJob(const ContactsList& contacts, const AccountPtr& account, QObject* parent):
......@@ -139,17 +141,23 @@ ObjectsList ContactCreateJob::handleReplyWithItems(const QNetworkReply *reply, c
if (ct == KGAPI2::JSON) {
d->lastContact = ContactsService::JSONToContact(rawData);
items << d->lastContact.dynamicCast<Object>();
} else if (ct == KGAPI2::XML) {
d->lastContact = ContactsService::XMLToContact(rawData);
items << d->lastContact.dynamicCast<Object>();
} else {
setErrorString(tr("Invalid response content type"));
return items;
if (!d->contacts.current()->photo().isEmpty()) {
// current contact does not have uid populated
d->setPhoto(d->contacts.current()->photo(), d->lastContact->uid());
} else {
} else {
if (d->lastContact) {
KContacts::Picture picture;
......@@ -158,11 +166,9 @@ ObjectsList ContactCreateJob::handleReplyWithItems(const QNetworkReply *reply, c
// Enqueue next item or finish
return items;
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment