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
public:
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());
QNetworkRequest photoRequest(url);
photoRequest.setHeader(QNetworkRequest::ContentTypeHeader, QLatin1String("image/*"));
pendingPhoto.first = contact->photo().rawData();
pendingPhoto.second = contact->photo().type();
q->enqueueRequest(photoRequest, pendingPhoto.first, QStringLiteral("modifyImage"));
}
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 = 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>();
d->contacts.currentProcessed();
} else if (ct == KGAPI2::XML) {
d->lastContact = ContactsService::XMLToContact(rawData);
items << d->lastContact.dynamicCast<Object>();
d->contacts.currentProcessed();
} else {
setError(KGAPI2::InvalidResponse);
setErrorString(tr("Invalid response content type"));
emitFinished();
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 {
if (d->lastContact) {
KContacts::Picture picture;
......@@ -158,11 +166,9 @@ ObjectsList ContactCreateJob::handleReplyWithItems(const QNetworkReply *reply, c
d->pendingPhoto.first.clear();
d->pendingPhoto.second.clear();
}
// Enqueue next item or finish
d->processNextContact();
}
// Enqueue next item or finish
d->processNextContact();
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