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

[contacts] Fix ContactCreateJob with a photo

Summary:
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: https://phabricator.kde.org/D28178
parent e999f481
...@@ -40,6 +40,7 @@ class Q_DECL_HIDDEN ContactCreateJob::Private ...@@ -40,6 +40,7 @@ class Q_DECL_HIDDEN ContactCreateJob::Private
public: public:
Private(ContactCreateJob *parent); Private(ContactCreateJob *parent);
void processNextContact(); void processNextContact();
void setPhoto(const KContacts::Picture &photo, const QString &uid);
QueueHelper<ContactPtr> contacts; QueueHelper<ContactPtr> contacts;
ContactPtr lastContact; ContactPtr lastContact;
...@@ -83,15 +84,16 @@ void ContactCreateJob::Private::processNextContact() ...@@ -83,15 +84,16 @@ void ContactCreateJob::Private::processNextContact()
} }
q->enqueueRequest(request, rawData, QStringLiteral("application/atom+xml")); q->enqueueRequest(request, rawData, QStringLiteral("application/atom+xml"));
}
if (!contact->photo().isEmpty()) { void ContactCreateJob::Private::setPhoto(const KContacts::Picture &photo, const QString &uid)
const QUrl url = ContactsService::photoUrl(q->account()->accountName(), contact->uid()); {
const QUrl url = ContactsService::photoUrl(q->account()->accountName(), uid);
QNetworkRequest photoRequest(url); QNetworkRequest photoRequest(url);
photoRequest.setHeader(QNetworkRequest::ContentTypeHeader, QLatin1String("image/*")); photoRequest.setHeader(QNetworkRequest::ContentTypeHeader, QLatin1String("image/*"));
pendingPhoto.first = contact->photo().rawData(); pendingPhoto.first = photo.rawData();
pendingPhoto.second = contact->photo().type(); pendingPhoto.second = photo.type();
q->enqueueRequest(photoRequest, pendingPhoto.first, QStringLiteral("modifyImage")); q->enqueueRequest(photoRequest, pendingPhoto.first, QStringLiteral("modifyImage"));
}
} }
ContactCreateJob::ContactCreateJob(const ContactsList& contacts, const AccountPtr& account, QObject* parent): ContactCreateJob::ContactCreateJob(const ContactsList& contacts, const AccountPtr& account, QObject* parent):
...@@ -139,17 +141,23 @@ ObjectsList ContactCreateJob::handleReplyWithItems(const QNetworkReply *reply, c ...@@ -139,17 +141,23 @@ ObjectsList ContactCreateJob::handleReplyWithItems(const QNetworkReply *reply, c
if (ct == KGAPI2::JSON) { if (ct == KGAPI2::JSON) {
d->lastContact = ContactsService::JSONToContact(rawData); d->lastContact = ContactsService::JSONToContact(rawData);
items << d->lastContact.dynamicCast<Object>(); items << d->lastContact.dynamicCast<Object>();
d->contacts.currentProcessed();
} else if (ct == KGAPI2::XML) { } else if (ct == KGAPI2::XML) {
d->lastContact = ContactsService::XMLToContact(rawData); d->lastContact = ContactsService::XMLToContact(rawData);
items << d->lastContact.dynamicCast<Object>(); items << d->lastContact.dynamicCast<Object>();
d->contacts.currentProcessed();
} else { } else {
setError(KGAPI2::InvalidResponse); setError(KGAPI2::InvalidResponse);
setErrorString(tr("Invalid response content type")); setErrorString(tr("Invalid response content type"));
emitFinished(); emitFinished();
return items; return items;
} }
if (!d->contacts.current()->photo().isEmpty()) {
// current contact does not have uid populated
d->setPhoto(d->contacts.current()->photo(), d->lastContact->uid());
d->contacts.currentProcessed();
} else {
d->contacts.currentProcessed();
d->processNextContact();
}
} else { } else {
if (d->lastContact) { if (d->lastContact) {
KContacts::Picture picture; KContacts::Picture picture;
...@@ -158,11 +166,9 @@ ObjectsList ContactCreateJob::handleReplyWithItems(const QNetworkReply *reply, c ...@@ -158,11 +166,9 @@ ObjectsList ContactCreateJob::handleReplyWithItems(const QNetworkReply *reply, c
d->pendingPhoto.first.clear(); d->pendingPhoto.first.clear();
d->pendingPhoto.second.clear(); d->pendingPhoto.second.clear();
} }
}
// Enqueue next item or finish // Enqueue next item or finish
d->processNextContact(); d->processNextContact();
}
return items; 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