diff --git a/examples/carddavresource/carddavresource.cpp b/examples/carddavresource/carddavresource.cpp index a6a7393f..5a935a10 100644 --- a/examples/carddavresource/carddavresource.cpp +++ b/examples/carddavresource/carddavresource.cpp @@ -1,191 +1,192 @@ /* * Copyright (C) 2015 Christian Mollekopf * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "carddavresource.h" #include "../webdavcommon/webdav.h" #include "facade.h" #include "resourceconfig.h" #include "log.h" #include "definitions.h" #include "synchronizer.h" #include "inspector.h" #include "facadefactory.h" #include "adaptorfactoryregistry.h" #include "contactpreprocessor.h" //This is the resources entity type, and not the domain type #define ENTITY_TYPE_CONTACT "contact" #define ENTITY_TYPE_ADDRESSBOOK "addressbook" using namespace Sink; class ContactSynchronizer : public WebDavSynchronizer { public: ContactSynchronizer(const Sink::ResourceContext &resourceContext) : WebDavSynchronizer(resourceContext, KDAV2::CardDav, ApplicationDomain::getTypeName(), ApplicationDomain::getTypeName()) {} QByteArray createAddressbook(const QString &addressbookName, const QString &addressbookPath, const QString &parentAddressbookRid) { SinkTrace() << "Creating addressbook: " << addressbookName << parentAddressbookRid; const auto remoteId = addressbookPath.toUtf8(); const auto bufferType = ENTITY_TYPE_ADDRESSBOOK; Sink::ApplicationDomain::Addressbook addressbook; addressbook.setName(addressbookName); + addressbook.setEnabled(true); if (!parentAddressbookRid.isEmpty()) { addressbook.setParent(syncStore().resolveRemoteId(ENTITY_TYPE_ADDRESSBOOK, parentAddressbookRid.toUtf8())); } createOrModify(bufferType, remoteId, addressbook, {}); return remoteId; } protected: void updateLocalCollections(KDAV2::DavCollection::List addressbookList) Q_DECL_OVERRIDE { const QByteArray bufferType = ENTITY_TYPE_ADDRESSBOOK; SinkTrace() << "Found" << addressbookList.size() << "addressbooks"; for (const auto &f : addressbookList) { const auto &rid = resourceID(f); SinkLog() << "Found addressbook:" << rid << f.displayName(); createAddressbook(f.displayName(), rid, ""); } } void updateLocalItem(KDAV2::DavItem remoteContact, const QByteArray &addressbookLocalId) Q_DECL_OVERRIDE { Sink::ApplicationDomain::Contact localContact; localContact.setVcard(remoteContact.data()); localContact.setAddressbook(addressbookLocalId); createOrModify(ENTITY_TYPE_CONTACT, resourceID(remoteContact), localContact, {}); } KAsync::Job replay(const ApplicationDomain::Contact &contact, Sink::Operation operation, const QByteArray &oldRemoteId, const QList &changedProperties) Q_DECL_OVERRIDE { SinkLog() << "Replaying to:" << serverUrl().url(); switch (operation) { case Sink::Operation_Creation: { const auto vcard = contact.getVcard(); if (vcard.isEmpty()) { return KAsync::error("No vcard in item for creation replay."); } auto collectionId = syncStore().resolveLocalId(ENTITY_TYPE_ADDRESSBOOK, contact.getAddressbook()); KDAV2::DavItem remoteItem; remoteItem.setData(vcard); remoteItem.setContentType("text/vcard"); remoteItem.setUrl(urlOf(collectionId, contact.getUid())); SinkLog() << "Creating:" << contact.getUid() << remoteItem.url().url() << vcard; return createItem(remoteItem).then([=] { return resourceID(remoteItem); }); } case Sink::Operation_Removal: { // We only need the URL in the DAV item for removal KDAV2::DavItem remoteItem; remoteItem.setUrl(urlOf(oldRemoteId)); SinkLog() << "Removing:" << oldRemoteId; return removeItem(remoteItem).then([] { return QByteArray{}; }); } case Sink::Operation_Modification: const auto vcard = contact.getVcard(); if (vcard.isEmpty()) { return KAsync::error("No ICal in item for modification replay"); } KDAV2::DavItem remoteItem; remoteItem.setData(vcard); remoteItem.setContentType("text/vcard"); remoteItem.setUrl(urlOf(oldRemoteId)); return modifyItem(remoteItem).then([=] { return oldRemoteId; }); } return KAsync::null(); } KAsync::Job replay(const ApplicationDomain::Addressbook &addressbook, Sink::Operation operation, const QByteArray &oldRemoteId, const QList &changedProperties) Q_DECL_OVERRIDE { return KAsync::null(); } }; class CollectionCleanupPreprocessor : public Sink::Preprocessor { public: virtual void deletedEntity(const ApplicationDomain::ApplicationDomainType &oldEntity) Q_DECL_OVERRIDE { //Remove all events of a collection when removing the collection. const auto revision = entityStore().maxRevision(); entityStore().indexLookup(oldEntity.identifier(), [&] (const QByteArray &identifier) { deleteEntity(ApplicationDomain::ApplicationDomainType{{}, identifier, revision, {}}, ApplicationDomain::getTypeName(), false); }); } }; CardDavResource::CardDavResource(const Sink::ResourceContext &resourceContext) : Sink::GenericResource(resourceContext) { auto synchronizer = QSharedPointer::create(resourceContext); setupSynchronizer(synchronizer); setupPreprocessors(ENTITY_TYPE_CONTACT, {new ContactPropertyExtractor}); setupPreprocessors(ENTITY_TYPE_ADDRESSBOOK, {new CollectionCleanupPreprocessor}); } CardDavResourceFactory::CardDavResourceFactory(QObject *parent) : Sink::ResourceFactory(parent, {Sink::ApplicationDomain::ResourceCapabilities::Contact::contact, Sink::ApplicationDomain::ResourceCapabilities::Contact::addressbook, Sink::ApplicationDomain::ResourceCapabilities::Contact::storage } ) { } Sink::Resource *CardDavResourceFactory::createResource(const ResourceContext &context) { return new CardDavResource(context); } void CardDavResourceFactory::registerFacades(const QByteArray &name, Sink::FacadeFactory &factory) { factory.registerFacade>(name); factory.registerFacade>(name); } void CardDavResourceFactory::registerAdaptorFactories(const QByteArray &name, Sink::AdaptorFactoryRegistry ®istry) { registry.registerFactory>(name); registry.registerFactory>(name); } void CardDavResourceFactory::removeDataFromDisk(const QByteArray &instanceIdentifier) { CardDavResource::removeFromDisk(instanceIdentifier); }