diff --git a/src/google/google-contacts/googlepeoplejson.cpp b/src/google/google-contacts/googlepeoplejson.cpp index f781cab..ca855d1 100644 --- a/src/google/google-contacts/googlepeoplejson.cpp +++ b/src/google/google-contacts/googlepeoplejson.cpp @@ -51,7 +51,7 @@ namespace { static const QString StarredContactGroupName = QStringLiteral("contactGroups/starred"); -QDate jsonObjectToDate(const QJsonObject &object) +QDate jsonObjectToDate(const QJsonObject &object, bool *ok) { const int year = object.value("year").toInt(); const int month = object.value("month").toInt(); @@ -61,6 +61,9 @@ QDate jsonObjectToDate(const QJsonObject &object) if (!date.isValid()) { SOCIALD_LOG_ERROR("Cannot read date from JSON:" << object); } + if (ok) { + *ok = date.isValid(); + } return date; } @@ -80,7 +83,11 @@ QList jsonArrayToList(const QJsonArray &array) { QList values; for (auto it = array.constBegin(); it != array.constEnd(); ++it) { - values.append(T::fromJsonObject(it->toObject())); + bool error = false; + const T &value = T::fromJsonObject(it->toObject(), &error); + if (!error) { + values.append(value); + } } return values; } @@ -169,7 +176,7 @@ bool shouldAddDetailChanges(const QContactDetail &detail, bool *hasChanges) } -GooglePeople::Source GooglePeople::Source::fromJsonObject(const QJsonObject &object) +GooglePeople::Source GooglePeople::Source::fromJsonObject(const QJsonObject &object, bool *) { Source ret; ret.type = object.value("type").toString(); @@ -223,7 +230,7 @@ bool GooglePeople::Address::saveContactDetails(QContact *contact, const QList return saveContactDetail(contact, &detail); } -GooglePeople::Name GooglePeople::Name::fromJsonObject(const QJsonObject &object) +GooglePeople::Name GooglePeople::Name::fromJsonObject(const QJsonObject &object, bool *) { Name ret; ret.metadata = FieldMetadata::fromJsonObject(object.value("metadata").toObject()); @@ -676,7 +701,7 @@ bool GooglePeople::Nickname::saveContactDetails(QContact *contact, const QList(object.value("sources").toArray()); @@ -961,7 +986,7 @@ bool GooglePeople::Photo::saveContactDetails(QContact *contact, const QList & return true; } -GooglePeople::Url GooglePeople::Url::fromJsonObject(const QJsonObject &object) +GooglePeople::Url GooglePeople::Url::fromJsonObject(const QJsonObject &object, bool *) { Url ret; ret.metadata = FieldMetadata::fromJsonObject(object.value("metadata").toObject()); @@ -1091,7 +1116,7 @@ GooglePeople::Person GooglePeople::Person::fromJsonObject(const QJsonObject &obj { Person ret; ret.resourceName = object.value("resourceName").toString(); - ret.metadata = PersonMetadata::fromJsonObject(object.value("metadata").toObject()); + ret.metadata = PersonMetadata::fromJsonObject(object.value("metadata").toObject(), nullptr); ret.addresses = jsonArrayToList
(object.value("addresses").toArray()); ret.biographies = jsonArrayToList(object.value("biographies").toArray()); ret.birthdays = jsonArrayToList(object.value("birthdays").toArray()); diff --git a/src/google/google-contacts/googlepeoplejson.h b/src/google/google-contacts/googlepeoplejson.h index e4c7a37..8dd773e 100644 --- a/src/google/google-contacts/googlepeoplejson.h +++ b/src/google/google-contacts/googlepeoplejson.h @@ -45,7 +45,7 @@ namespace GooglePeople ProfileMetadata profileMetadata; */ - static Source fromJsonObject(const QJsonObject &obj); + static Source fromJsonObject(const QJsonObject &obj, bool *error = nullptr); }; class FieldMetadata @@ -75,7 +75,7 @@ namespace GooglePeople QString countryCode; static bool saveContactDetails(QContact *contact, const QList
&values); - static Address fromJsonObject(const QJsonObject &obj); + static Address fromJsonObject(const QJsonObject &obj, bool *error = nullptr); static QJsonArray jsonValuesForContact(const QContact &contact, bool *hasChanges); }; @@ -90,7 +90,7 @@ namespace GooglePeople */ static bool saveContactDetails(QContact *contact, const QList &values); - static Biography fromJsonObject(const QJsonObject &obj); + static Biography fromJsonObject(const QJsonObject &obj, bool *error = nullptr); static QJsonArray jsonValuesForContact(const QContact &contact, bool *hasChanges); }; @@ -105,7 +105,7 @@ namespace GooglePeople */ static bool saveContactDetails(QContact *contact, const QList &values); - static Birthday fromJsonObject(const QJsonObject &obj); + static Birthday fromJsonObject(const QJsonObject &obj, bool *error = nullptr); static QJsonArray jsonValuesForContact(const QContact &contact, bool *hasChanges); }; @@ -119,7 +119,7 @@ namespace GooglePeople QString displayName; static bool saveContactDetails(QContact *contact, const QList &values); - static EmailAddress fromJsonObject(const QJsonObject &obj); + static EmailAddress fromJsonObject(const QJsonObject &obj, bool *error = nullptr); static QJsonArray jsonValuesForContact(const QContact &contact, bool *hasChanges); }; @@ -135,7 +135,7 @@ namespace GooglePeople */ static bool saveContactDetails(QContact *contact, const QList &values); - static Event fromJsonObject(const QJsonObject &obj); + static Event fromJsonObject(const QJsonObject &obj, bool *error = nullptr); static QJsonArray jsonValuesForContact(const QContact &contact, bool *hasChanges); }; @@ -155,7 +155,7 @@ namespace GooglePeople const QList &values, int accountId, const QList &candidateCollections); - static Membership fromJsonObject(const QJsonObject &obj); + static Membership fromJsonObject(const QJsonObject &obj, bool *error = nullptr); static QJsonArray jsonValuesForContact(const QContact &contact, bool *hasChanges); }; @@ -182,7 +182,7 @@ namespace GooglePeople */ static bool saveContactDetails(QContact *contact, const QList &values); - static Name fromJsonObject(const QJsonObject &obj); + static Name fromJsonObject(const QJsonObject &obj, bool *error = nullptr); static QJsonArray jsonValuesForContact(const QContact &contact, bool *hasChanges); }; @@ -197,7 +197,7 @@ namespace GooglePeople */ static bool saveContactDetails(QContact *contact, const QList &values); - static Nickname fromJsonObject(const QJsonObject &obj); + static Nickname fromJsonObject(const QJsonObject &obj, bool *error = nullptr); static QJsonArray jsonValuesForContact(const QContact &contact, bool *hasChanges); }; @@ -222,7 +222,7 @@ namespace GooglePeople */ static bool saveContactDetails(QContact *contact, const QList &values); - static Organization fromJsonObject(const QJsonObject &obj); + static Organization fromJsonObject(const QJsonObject &obj, bool *error = nullptr); static QJsonArray jsonValuesForContact(const QContact &contact, bool *hasChanges); }; @@ -239,7 +239,7 @@ namespace GooglePeople */ static bool saveContactDetails(QContact *contact, const QList &values); - static PhoneNumber fromJsonObject(const QJsonObject &obj); + static PhoneNumber fromJsonObject(const QJsonObject &obj, bool *error = nullptr); static QJsonArray jsonValuesForContact(const QContact &contact, bool *hasChanges); }; @@ -254,7 +254,7 @@ namespace GooglePeople static QString etag(const QContact &contact); static bool saveContactDetails(QContact *contact, const PersonMetadata &value); - static PersonMetadata fromJsonObject(const QJsonObject &obj); + static PersonMetadata fromJsonObject(const QJsonObject &obj, bool *error = nullptr); static QJsonObject toJsonObject(const QContact &contact); }; @@ -270,7 +270,7 @@ namespace GooglePeople QString *localAvatarFile = nullptr); static bool saveContactDetails(QContact *contact, const QList &values); - static Photo fromJsonObject(const QJsonObject &obj); + static Photo fromJsonObject(const QJsonObject &obj, bool *error = nullptr); static QJsonArray jsonValuesForContact(const QContact &contact, bool *hasChanges); }; @@ -283,7 +283,7 @@ namespace GooglePeople QString formattedType; static bool saveContactDetails(QContact *contact, const QList &values); - static Url fromJsonObject(const QJsonObject &obj); + static Url fromJsonObject(const QJsonObject &obj, bool *error = nullptr); static QJsonArray jsonValuesForContact(const QContact &contact, bool *hasChanges); }; diff --git a/src/google/google-contacts/googletwowaycontactsyncadaptor.cpp b/src/google/google-contacts/googletwowaycontactsyncadaptor.cpp index 25cecf1..15ee31e 100644 --- a/src/google/google-contacts/googletwowaycontactsyncadaptor.cpp +++ b/src/google/google-contacts/googletwowaycontactsyncadaptor.cpp @@ -188,6 +188,33 @@ void GoogleContactSqliteSyncAdaptor::syncFinishedSuccessfully() void GoogleContactSqliteSyncAdaptor::syncFinishedWithError() { SOCIALD_LOG_ERROR("Sync finished with error"); + + if (q->m_collection.id().isNull()) { + return; + } + + // If sync fails, clear the sync token and date for the collection, so that the next sync + // requests a full contact listing, to ensure we are up-to-date with the server. + + q->m_collection.setExtendedMetaData(CollectionKeySyncToken, QString()); + q->m_collection.setExtendedMetaData(CollectionKeySyncTokenDate, QString()); + + QHash* > modifiedCollections; + QList emptyContacts; + modifiedCollections.insert(&q->m_collection, &emptyContacts); + + QtContactsSqliteExtensions::ContactManagerEngine *cme = QtContactsSqliteExtensions::contactManagerEngine(*q->m_contactManager); + QContactManager::Error error = QContactManager::NoError; + + if (!cme->storeChanges(nullptr, + &modifiedCollections, + QList(), + QtContactsSqliteExtensions::ContactManagerEngine::PreserveLocalChanges, + true, + &error)) { + SOCIALD_LOG_ERROR("Failed to clear sync token for account:" << q->m_accountId + << "due to error:" << error); + } } //------------------------------------- @@ -419,7 +446,8 @@ void GoogleTwoWayContactSyncAdaptor::contactsFinishedHandler() if (reply->error() == QNetworkReply::ProtocolInvalidOperationError) { QNetworkReply *reply = qobject_cast(sender()); - if (reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() == 400) { + if (reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() == 400 + && !m_retriedConnectionsList) { SOCIALD_LOG_INFO("Will request new sync token, got error from server:" << reply->readAll()); DataRequestType requestType = static_cast( @@ -428,6 +456,7 @@ void GoogleTwoWayContactSyncAdaptor::contactsFinishedHandler() reply->property("contactChangeNotifier").toInt()); m_connectionsListParams.requestSyncToken = true; m_connectionsListParams.syncToken.clear(); + m_retriedConnectionsList = true; requestData(requestType, contactChangeNotifier); decrementSemaphore(m_accountId); return; @@ -1108,12 +1137,14 @@ void GoogleTwoWayContactSyncAdaptor::purgeAccount(int pid) void GoogleTwoWayContactSyncAdaptor::finalize(int accountId) { + if (syncAborted()|| status() == SocialNetworkSyncAdaptor::Error) { + m_sqliteSync->syncFinishedWithError(); + return; + } + if (accountId != m_accountId - || m_accessToken.isEmpty() - || syncAborted() - || status() == SocialNetworkSyncAdaptor::Error) { + || m_accessToken.isEmpty()) { // account failure occurred before sync process was started, - // or other error occurred during sync. // in this case we have nothing left to do except cleanup. return; } diff --git a/src/google/google-contacts/googletwowaycontactsyncadaptor.h b/src/google/google-contacts/googletwowaycontactsyncadaptor.h index c99ef9e..cd29d3c 100644 --- a/src/google/google-contacts/googletwowaycontactsyncadaptor.h +++ b/src/google/google-contacts/googletwowaycontactsyncadaptor.h @@ -173,6 +173,7 @@ class GoogleTwoWayContactSyncAdaptor : public GoogleDataTypeSyncAdaptor int m_accountId = 0; int m_apiRequestsRemaining = 0; + bool m_retriedConnectionsList = false; bool m_allowFinalCleanup = false; };