/* Copyright (c) 2016 Christian Mollekopf This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "sinkfabric.h" #include #include #include #include #include #include "fabric.h" using namespace Kube; using namespace Sink; using namespace Sink::ApplicationDomain; class SinkListener : public Kube::Fabric::Listener { public: SinkListener() = default; void notify(const QString &id, const QVariantMap &message) { SinkLog() << "Received message: " << id << message; if (id == "synchronize"/*Kube::Messages::synchronize*/) { if (auto folder = message["folder"].value()) { SinkLog() << "Synchronizing folder " << folder->resourceInstanceIdentifier() << folder->identifier(); auto scope = SyncScope().resourceFilter(folder->resourceInstanceIdentifier()).filter(QVariant::fromValue(folder->identifier())); scope.setType(); Store::synchronize(scope).exec(); } else { auto accountId = message["accountId"].value(); auto type = message["type"].value(); SyncScope scope; if (!accountId.isEmpty()) { //FIXME this should work with either string or bytearray, but is apparently very picky scope.resourceFilter(accountId.toLatin1()); } if (type == "contacts") { scope.setType(); } else if (type == "mail") { scope.setType(); } else if (type == "folder") { scope.setType(); } else { //Only synchronize folders by default for now scope.setType(); } SinkLog() << "Synchronizing all. AccountId: " << accountId << " Type: " << scope.type(); Store::synchronize(scope).exec(); } } if (id == "sendOutbox"/*Kube::Messages::synchronize*/) { Query query; query.containsFilter(ResourceCapabilities::Mail::transport); auto job = Store::fetchAll(query) .each([=](const SinkResource::Ptr &resource) -> KAsync::Job { return Store::synchronize(SyncScope{}.resourceFilter(resource->identifier())); }); job.exec(); } if (id == "markAsRead"/*Kube::Messages::synchronize*/) { if (auto mail = message["mail"].value()) { mail->setUnread(false); Store::modify(*mail).exec(); } } if (id == "markAsUnread"/*Kube::Messages::synchronize*/) { if (auto mail = message["mail"].value()) { mail->setUnread(true); Store::modify(*mail).exec(); } } if (id == "toggleImportant"/*Kube::Messages::synchronize*/) { if (auto mail = message["mail"].value()) { mail->setImportant(message["important"].toBool()); Store::modify(*mail).exec(); } } if (id == "moveToTrash"/*Kube::Messages::synchronize*/) { if (auto mail = message["mail"].value()) { mail->setTrash(true); Store::modify(*mail).exec(); } } if (id == "moveToDrafts"/*Kube::Messages::synchronize*/) { if (auto mail = message["mail"].value()) { mail->setDraft(true); Store::modify(*mail).exec(); } } if (id == "moveToFolder"/*Kube::Messages::synchronize*/) { if (auto mail = message["mail"].value()) { auto folder = message["folder"].value(); mail->setFolder(*folder); Store::modify(*mail).exec(); } } } }; class SinkNotifier { public: SinkNotifier() : mNotifier{Sink::Query{Sink::Query::LiveQuery}} { mNotifier.registerHandler([this] (const Sink::Notification ¬ification) { Notification n; SinkLog() << "Received notification: " << notification; QVariantMap message; if (notification.type == Sink::Notification::Warning) { message["type"] = Notification::Warning; if (notification.code == Sink::ApplicationDomain::TransmissionError) { message["message"] = QObject::tr("Failed to send message."); } else { return; } } else if (notification.type == Sink::Notification::Status) { if (notification.code == Sink::ApplicationDomain::ErrorStatus) { //A resource entered error status message["type"] = Notification::Warning; message["message"] = QObject::tr("A resource experienced an error."); } else { return; } } else if (notification.type == Sink::Notification::Error) { message["type"] = Notification::Warning; message["resource"] = QString{notification.resource}; switch(notification.code) { case Sink::ApplicationDomain::ConnectionError: message["message"] = QObject::tr("Failed to connect to server."); break; case Sink::ApplicationDomain::NoServerError: message["message"] = QObject::tr("Host not found."); break; case Sink::ApplicationDomain::LoginError: message["message"] = QObject::tr("Failed to login."); break; case Sink::ApplicationDomain::ConfigurationError: message["message"] = QObject::tr("Configuration error."); break; case Sink::ApplicationDomain::ConnectionLostError: message["message"] = QObject::tr("Connection lost."); break; default: message["message"] = "An unknown error occurred: " + notification.message; } Fabric::Fabric{}.postMessage("errorNotification", message); } else if (notification.type == Sink::Notification::Info) { if (notification.code == Sink::ApplicationDomain::TransmissionSuccess) { message["type"] = Notification::Info; message["message"] = QObject::tr("A message has been sent."); } else { return; } } else if (notification.type == Sink::Notification::Progress) { message["progress"] = notification.progress; message["total"] = notification.total; if (!notification.entities.isEmpty()) { message["folderId"] = notification.entities.first(); } message["resourceId"] = notification.resource; Fabric::Fabric{}.postMessage("progressNotification", message); return; } else { return; } Fabric::Fabric{}.postMessage("notification", message); }); } Sink::Notifier mNotifier; }; class SinkFabric::Private { SinkNotifier notifier; SinkListener listener; }; SinkFabric::SinkFabric() : QObject(), d(new SinkFabric::Private) { } SinkFabric::~SinkFabric() { delete d; } SinkFabric &SinkFabric::instance() { static SinkFabric instance; return instance; }