diff --git a/framework/src/sinkfabric.cpp b/framework/src/sinkfabric.cpp index 61cba598..1ea5b555 100644 --- a/framework/src/sinkfabric.cpp +++ b/framework/src/sinkfabric.cpp @@ -1,247 +1,247 @@ /* 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 #include "fabric.h" #include "keyring.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 if (message.contains("specialPurpose")) { auto specialPurpose = message["specialPurpose"].value(); //Synchronize all drafts folders if (specialPurpose == "drafts") { //TODO or rather just synchronize draft mails and have resource figure out what that means? Sink::Query folderQuery{}; folderQuery.containsFilter(Sink::ApplicationDomain::SpecialPurpose::Mail::drafts); folderQuery.request(); folderQuery.request(); Store::fetch(folderQuery) .then([] (const QList &folders) { for (const auto f : folders) { auto scope = SyncScope().resourceFilter(f->resourceInstanceIdentifier()).filter(QVariant::fromValue(f->identifier())); scope.setType(); Store::synchronize(scope).exec(); } }).exec(); } } else { const auto accountId = message["accountId"].value(); const 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()); } - scope.setType(type); + scope.setType(type.toUtf8()); SinkLog() << "Synchronizing... 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 == "setImportant"/*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(); } } if (id == "unlockKeyring") { auto accountId = message["accountId"].value(); Kube::AccountKeyring{accountId}.unlock(); } } }; class SinkNotifier { public: SinkNotifier() : mNotifier{Sink::Query{Sink::Query::LiveQuery}} { mNotifier.registerHandler([] (const Sink::Notification ¬ification) { Notification n; SinkLog() << "Received notification: " << notification; QVariantMap message; if (notification.type == Sink::Notification::Warning) { message["type"] = "warning"; QVariantList entities; for(const auto &entity : notification.entities) { entities << entity; } message["entities"] = entities; message["resource"] = QString{notification.resource}; if (notification.code == Sink::ApplicationDomain::TransmissionError) { message["message"] = QObject::tr("Failed to send message."); message["subtype"] = "transmissionError"; } else { return; } } else if (notification.type == Sink::Notification::Status) { return; } else if (notification.type == Sink::Notification::Error) { message["type"] = "error"; message["resource"] = QString{notification.resource}; message["details"] = notification.message; switch(notification.code) { case Sink::ApplicationDomain::ConnectionError: message["message"] = QObject::tr("Failed to connect to server."); message["subtype"] = "connectionError"; break; case Sink::ApplicationDomain::NoServerError: message["message"] = QObject::tr("Host not found."); message["subtype"] = "hostNotFoundError"; break; case Sink::ApplicationDomain::LoginError: message["message"] = QObject::tr("Failed to login."); message["subtype"] = "loginError"; break; case Sink::ApplicationDomain::ConfigurationError: message["message"] = QObject::tr("Configuration error."); break; case Sink::ApplicationDomain::ConnectionLostError: message["message"] = QObject::tr("Connection lost."); break; case Sink::ApplicationDomain::MissingCredentialsError: message["message"] = QObject::tr("No credentials available."); break; default: //Ignore unknown errors, they are not going to help. return; } Fabric::Fabric{}.postMessage("errorNotification", message); } else if (notification.type == Sink::Notification::Info) { if (notification.code == Sink::ApplicationDomain::TransmissionSuccess) { message["type"] = "info"; message["message"] = QObject::tr("A message has been sent."); } else if (notification.code == Sink::ApplicationDomain::NewContentAvailable) { message["type"] = "info"; if (!notification.entities.isEmpty()) { message["folderId"] = notification.entities.first(); } } else { return; } } else if (notification.type == Sink::Notification::Progress) { message["type"] = "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; }