Skip to content
This repository has been archived by the owner on Sep 4, 2021. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
[libcontacts] Preserve some syncTarget values in backup/restore
Contacts with 'bluetooth' or 'was_local' sync target values should
preserve these properties during export/import.
  • Loading branch information
matthewvogt committed Jun 30, 2014
1 parent 4eaf712 commit 2e5769e
Show file tree
Hide file tree
Showing 6 changed files with 213 additions and 22 deletions.
49 changes: 49 additions & 0 deletions src/seasideexport.cpp
@@ -0,0 +1,49 @@
/*
* Copyright (C) 2014 Jolla Ltd.
* Contact: Matt Vogt <matthew.vogt@jollamobile.com>
*
* You may use this file under the terms of the BSD license as follows:
*
* "Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Nemo Mobile nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
*/

#include "seasideexport.h"

#include "seasidepropertyhandler.h"

#include <QVersitContactExporter>

QList<QVersitDocument> SeasideExport::buildExportContacts(const QList<QContact> &contacts)
{
SeasidePropertyHandler propertyHandler;

QVersitContactExporter exporter;
exporter.setDetailHandler(&propertyHandler);
exporter.exportContacts(contacts);

return exporter.documents();
}

53 changes: 53 additions & 0 deletions src/seasideexport.h
@@ -0,0 +1,53 @@
/*
* Copyright (C) 2014 Jolla Ltd.
* Contact: Matt Vogt <matthew.vogt@jollamobile.com>
*
* You may use this file under the terms of the BSD license as follows:
*
* "Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Nemo Mobile nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
*/

#ifndef SEASIDEEXPORT_H
#define SEASIDEEXPORT_H

#include "contactcacheexport.h"

#include <QContact>
#include <QVersitDocument>

QTCONTACTS_USE_NAMESPACE
QTVERSIT_USE_NAMESPACE

class CONTACTCACHE_EXPORT SeasideExport
{
SeasideExport();
~SeasideExport();

public:
static QList<QVersitDocument> buildExportContacts(const QList<QContact> &contacts);
};

#endif
19 changes: 15 additions & 4 deletions src/seasideimport.cpp
Expand Up @@ -83,12 +83,14 @@ QContactFetchHint basicFetchHint()

QContactFilter localContactFilter()
{
// Contacts that are local to the device have sync target 'local' or 'was_local'
QContactDetailFilter filterLocal, filterWasLocal;
// Contacts that are local to the device have sync target 'local' or 'was_local' or 'bluetooth'
QContactDetailFilter filterLocal, filterWasLocal, filterBluetooth;
filterLocal.setDetailType(QContactSyncTarget::Type, QContactSyncTarget::FieldSyncTarget);
filterWasLocal.setDetailType(QContactSyncTarget::Type, QContactSyncTarget::FieldSyncTarget);
filterBluetooth.setDetailType(QContactSyncTarget::Type, QContactSyncTarget::FieldSyncTarget);
filterLocal.setValue(QString::fromLatin1("local"));
filterWasLocal.setValue(QString::fromLatin1("was_local"));
filterBluetooth.setValue(QString::fromLatin1("bluetooth"));

return filterLocal | filterWasLocal;
}
Expand Down Expand Up @@ -315,7 +317,6 @@ QList<QContact> SeasideImport::buildImportContacts(const QList<QVersitDocument>
unimportableDetailTypes.insert(QContactDetail::TypeFamily);
unimportableDetailTypes.insert(QContactDetail::TypeGeoLocation);
unimportableDetailTypes.insert(QContactDetail::TypeGlobalPresence);
unimportableDetailTypes.insert(QContactDetail::TypeSyncTarget);
unimportableDetailTypes.insert(QContactDetail::TypeVersion);

// Merge any duplicates in the import list
Expand All @@ -325,7 +326,17 @@ QList<QContact> SeasideImport::buildImportContacts(const QList<QVersitDocument>

// Remove any details that our backend can't store
foreach (QContactDetail detail, contact.details()) {
if (unimportableDetailTypes.contains(detail.type())) {
if (detail.type() == QContactSyncTarget::Type) {
// We allow some syncTarget values
const QString syncTarget(detail.value<QString>(QContactSyncTarget::FieldSyncTarget));
if (syncTarget == QStringLiteral("was_local") ||
syncTarget == QStringLiteral("bluetooth")) {
// These values are permissible
} else {
qDebug() << " Removing unimportable syncTarget:" << syncTarget;
contact.removeDetail(&detail);
}
} else if (unimportableDetailTypes.contains(detail.type())) {
qDebug() << " Removing unimportable detail:" << detail;
contact.removeDetail(&detail);
}
Expand Down
99 changes: 83 additions & 16 deletions src/seasidepropertyhandler.cpp
Expand Up @@ -35,25 +35,13 @@
#include <QContactAvatar>
#include <QContactOnlineAccount>
#include <QContactPresence>
#include <QContactSyncTarget>
#include <QCryptographicHash>
#include <QDir>
#include <QImage>

#include <qtcontacts-extensions.h>

SeasidePropertyHandler::SeasidePropertyHandler()
{
}

SeasidePropertyHandler::~SeasidePropertyHandler()
{
}

void SeasidePropertyHandler::documentProcessed(const QVersitDocument &, QContact *)
{
// do nothing, have no state to clean.
}

namespace {

void processPhoto(const QVersitProperty &property, bool *alreadyProcessed, QList<QContactDetail> * updatedDetails)
Expand Down Expand Up @@ -188,14 +176,93 @@ void processOnlineAccount(const QVersitProperty &property, bool *alreadyProcesse
}
}

void processSyncTarget(const QVersitProperty &property, bool *alreadyProcessed, QList<QContactDetail> * updatedDetails)
{
// Set the sync target for this contact, if appropriate

// Try to interpret the data as a string
const QString data(property.variantValue().toString().toLower());

if (data == QString::fromLatin1("bluetooth") || data == QString::fromLatin1("was_local")) {
QList<QContactDetail>::iterator it = updatedDetails->begin(), end = updatedDetails->end();
for ( ; it != end; ++it) {
if ((*it).type() == QContactSyncTarget::Type)
break;
}
if (it != end) {
QContactSyncTarget &syncTarget(static_cast<QContactSyncTarget &>(*it));
syncTarget.setSyncTarget(data);
} else {
QContactSyncTarget syncTarget;
syncTarget.setSyncTarget(data);
updatedDetails->append(syncTarget);
}

*alreadyProcessed = true;
} else {
qWarning() << "Invalid syncTarget data:" << data;
}
}

void SeasidePropertyHandler::propertyProcessed(const QVersitDocument &, const QVersitProperty &property, const QContact &, bool *alreadyProcessed, QList<QContactDetail> * updatedDetails)
void processSyncTarget(const QContactSyncTarget &detail, QSet<int> * processedFields, QList<QVersitProperty> * toBeRemoved, QList<QVersitProperty> * toBeAdded)
{
if (property.name().toLower() == QLatin1String("photo")) {
Q_UNUSED(processedFields)
Q_UNUSED(toBeRemoved)

// Include the sync target in the export if it is not 'local' but is exportable
const QString syncTarget(detail.syncTarget());

if (syncTarget == QString::fromLatin1("bluetooth") || syncTarget == QString::fromLatin1("was_local")) {
QVersitProperty stProperty;
stProperty.setName(QString::fromLatin1("X-NEMOMOBILE-SYNCTARGET"));
stProperty.setValue(syncTarget);

toBeAdded->append(stProperty);
} else if (!syncTarget.isEmpty() && syncTarget != QString::fromLatin1("local")) {
qWarning() << "Invalid syncTarget for export:" << syncTarget;
}
}

}

SeasidePropertyHandler::SeasidePropertyHandler()
{
}

SeasidePropertyHandler::~SeasidePropertyHandler()
{
}

void SeasidePropertyHandler::documentProcessed(const QVersitDocument &, QContact *)
{
// do nothing, have no state to clean.
}

void SeasidePropertyHandler::propertyProcessed(const QVersitDocument &, const QVersitProperty &property,
const QContact &, bool *alreadyProcessed, QList<QContactDetail> * updatedDetails)
{
const QString propertyName(property.name().toLower());

if (propertyName == QLatin1String("photo")) {
processPhoto(property, alreadyProcessed, updatedDetails);
} else if (property.name().toLower() == QLatin1String("x-nemomobile-onlineaccount-demo")) {
} else if (propertyName == QLatin1String("x-nemomobile-onlineaccount-demo")) {
processOnlineAccount(property, alreadyProcessed, updatedDetails);
} else if (propertyName == QLatin1String("x-nemomobile-synctarget")) {
processSyncTarget(property, alreadyProcessed, updatedDetails);
}
}

void SeasidePropertyHandler::contactProcessed(const QContact &c, QVersitDocument *)
{
}

void SeasidePropertyHandler::detailProcessed(const QContact &, const QContactDetail &detail,
const QVersitDocument &, QSet<int> * processedFields, QList<QVersitProperty> * toBeRemoved, QList<QVersitProperty> * toBeAdded)
{
const QContactDetail::DetailType detailType(detail.type());

if (detailType == QContactSyncTarget::Type) {
processSyncTarget(static_cast<const QContactSyncTarget &>(detail), processedFields, toBeRemoved, toBeAdded);
}
}

12 changes: 10 additions & 2 deletions src/seasidepropertyhandler.h
Expand Up @@ -40,7 +40,7 @@

#include <QContact>

#include <QVersitContactImporterPropertyHandler>
#include <QVersitContactHandler>
#include <QVersitResourceHandler>
#include <QVersitDocument>
#include <QVersitProperty>
Expand All @@ -56,10 +56,13 @@ QTVERSIT_USE_NAMESPACE
a file, and then the path to the file needs to be saved
to the backend as a contact avatar url detail.
The X-NEMOMOBILE-SYNCTARGET property is supported for specifying
the sync target of a contact.
Also support the X-NEMOMOBILE-ONLINEACCOUNT-DEMO property
for loading demo online account data.
*/
class CONTACTCACHE_EXPORT SeasidePropertyHandler : public QVersitContactImporterPropertyHandlerV2
class CONTACTCACHE_EXPORT SeasidePropertyHandler : public QVersitContactHandler
{
public:
SeasidePropertyHandler();
Expand All @@ -69,6 +72,11 @@ class CONTACTCACHE_EXPORT SeasidePropertyHandler : public QVersitContactImporter
void documentProcessed(const QVersitDocument &, QContact *);
void propertyProcessed(const QVersitDocument &, const QVersitProperty &property,
const QContact &, bool *alreadyProcessed, QList<QContactDetail> * updatedDetails);

// QVersitContactExporterDetailHandlerV2
void contactProcessed(const QContact &, QVersitDocument *);
void detailProcessed(const QContact &, const QContactDetail &detail,
const QVersitDocument &, QSet<int> * processedFields, QList<QVersitProperty> * toBeRemoved, QList<QVersitProperty> * toBeAdded);
};

#endif // PROPERTYHANDLER_H
3 changes: 3 additions & 0 deletions src/src.pro
Expand Up @@ -37,13 +37,15 @@ HEADERS += contactmanagerengine.h
SOURCES += \
$$PWD/cacheconfiguration.cpp \
$$PWD/seasidecache.cpp \
$$PWD/seasideexport.cpp \
$$PWD/seasideimport.cpp \
$$PWD/seasidepropertyhandler.cpp

HEADERS += \
$$PWD/cacheconfiguration.h \
$$PWD/contactcacheexport.h \
$$PWD/seasidecache.h \
$$PWD/seasideexport.h \
$$PWD/seasideimport.h \
$$PWD/synchronizelists.h \
$$PWD/seasidenamegrouper.h \
Expand All @@ -53,6 +55,7 @@ headers.files = \
$$PWD/cacheconfiguration.h \
$$PWD/contactcacheexport.h \
$$PWD/seasidecache.h \
$$PWD/seasideexport.h \
$$PWD/seasideimport.h \
$$PWD/synchronizelists.h \
$$PWD/seasidenamegrouper.h \
Expand Down

0 comments on commit 2e5769e

Please sign in to comment.