summaryrefslogtreecommitdiffstats
path: root/examples/mailtransportresource/mailtransportresource.cpp
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2016-06-17 09:09:33 +0200
committerChristian Mollekopf <chrigi_1@fastmail.fm>2016-06-17 09:09:33 +0200
commit3f4011bcbf4ccf55edb8ea618fbf9b50f9e7bec9 (patch)
tree489d4bc4c672d60f35a20556cb16a98d871a9fe9 /examples/mailtransportresource/mailtransportresource.cpp
parent749c4d7da40bf20d240be5ad7948f4be843865cd (diff)
downloadsink-3f4011bcbf4ccf55edb8ea618fbf9b50f9e7bec9.tar.gz
sink-3f4011bcbf4ccf55edb8ea618fbf9b50f9e7bec9.zip
Initial version of the mailtransport resource
Diffstat (limited to 'examples/mailtransportresource/mailtransportresource.cpp')
-rw-r--r--examples/mailtransportresource/mailtransportresource.cpp199
1 files changed, 196 insertions, 3 deletions
diff --git a/examples/mailtransportresource/mailtransportresource.cpp b/examples/mailtransportresource/mailtransportresource.cpp
index 3b8dfd0..e8a15ee 100644
--- a/examples/mailtransportresource/mailtransportresource.cpp
+++ b/examples/mailtransportresource/mailtransportresource.cpp
@@ -20,6 +20,196 @@
20#include "mailtransportresource.h" 20#include "mailtransportresource.h"
21#include "facade.h" 21#include "facade.h"
22#include "facadefactory.h" 22#include "facadefactory.h"
23#include "resourceconfig.h"
24#include "definitions.h"
25#include "domainadaptor.h"
26#include "sourcewriteback.h"
27#include <QDir>
28#include <QFileInfo>
29#include <QSettings>
30#include <QStandardPaths>
31#include <QUuid>
32#include <KMime/Message>
33
34#include "resultprovider.h"
35#include "mailtransport.h"
36#include "mail_generated.h"
37#include <synchronizer.h>
38#include <log.h>
39#include <resourceconfig.h>
40#include <pipeline.h>
41
42#define ENTITY_TYPE_MAIL "mail"
43
44using namespace Sink;
45
46class MimeMessageMover : public Sink::EntityPreprocessor<ApplicationDomain::Mail>
47{
48public:
49 MimeMessageMover(const QByteArray &resourceInstanceIdentifier) : Sink::EntityPreprocessor<ApplicationDomain::Mail>(), mResourceInstanceIdentifier(resourceInstanceIdentifier) {}
50
51 QString moveMessage(const QString &oldPath, const Sink::ApplicationDomain::Mail &mail)
52 {
53 const auto directory = Sink::resourceStorageLocation(mResourceInstanceIdentifier);
54 const auto filePath = directory + "/" + mail.identifier();
55 if (oldPath != filePath) {
56 if (!QDir().mkpath(directory)) {
57 Warning() << "Failed to create the directory: " << directory;
58 }
59 QFile::remove(filePath);
60 QFile origFile(oldPath);
61 if (!origFile.open(QIODevice::ReadWrite)) {
62 Warning() << "Failed to open the original file with write rights: " << origFile.errorString();
63 }
64 if (!origFile.rename(filePath)) {
65 Warning() << "Failed to move the file from: " << oldPath << " to " << filePath << ". " << origFile.errorString();
66 }
67 origFile.close();
68 return filePath;
69 }
70 return oldPath;
71 }
72
73 void newEntity(Sink::ApplicationDomain::Mail &mail, Sink::Storage::Transaction &transaction) Q_DECL_OVERRIDE
74 {
75 if (!mail.getMimeMessagePath().isEmpty()) {
76 mail.setMimeMessagePath(moveMessage(mail.getMimeMessagePath(), mail));
77 }
78 }
79
80 void modifiedEntity(const Sink::ApplicationDomain::Mail &oldMail, Sink::ApplicationDomain::Mail &newMail, Sink::Storage::Transaction &transaction) Q_DECL_OVERRIDE
81 {
82 if (!newMail.getMimeMessagePath().isEmpty()) {
83 newMail.setMimeMessagePath(moveMessage(newMail.getMimeMessagePath(), newMail));
84 }
85 }
86
87 void deletedEntity(const Sink::ApplicationDomain::Mail &mail, Sink::Storage::Transaction &transaction) Q_DECL_OVERRIDE
88 {
89 QFile::remove(mail.getMimeMessagePath());
90 }
91 QByteArray mResourceInstanceIdentifier;
92};
93
94static KAsync::Job<void>send(const ApplicationDomain::Mail &mail, const MailtransportResource::Settings &settings)
95{
96 const auto data = mail.getMimeMessage();
97 auto msg = KMime::Message::Ptr::create();
98 msg->setHead(KMime::CRLFtoLF(data));
99 msg->parse();
100 if (settings.testMode) {
101 Log() << "I would totally send that mail, but I'm in test mode.";
102 } else {
103 if (MailTransport::sendMessage(msg, settings.server.toUtf8(), settings.username.toUtf8(), settings.password.toUtf8(), settings.cacert.toUtf8())) {
104 Log() << "Sent message successfully";
105 } else {
106 Log() << "Failed to send message";
107 return KAsync::error<void>(1, "Failed to send the message.");
108 }
109 }
110 return KAsync::null<void>();
111}
112
113//TODO fold into synchronizer
114class MailtransportWriteback : public Sink::SourceWriteBack
115{
116public:
117 MailtransportWriteback(const QByteArray &resourceType, const QByteArray &resourceInstanceIdentifier) : Sink::SourceWriteBack(resourceType, resourceInstanceIdentifier)
118 {
119
120 }
121
122 KAsync::Job<QByteArray> replay(const ApplicationDomain::Mail &mail, Sink::Operation operation, const QByteArray &oldRemoteId, const QList<QByteArray> &changedProperties) Q_DECL_OVERRIDE
123 {
124 if (operation == Sink::Operation_Creation) {
125 Trace() << "Dispatching message.";
126 // return send(mail, mSettings);
127 } else if (operation == Sink::Operation_Removal) {
128 } else if (operation == Sink::Operation_Modification) {
129 }
130 return KAsync::null<QByteArray>();
131 }
132
133public:
134 MailtransportResource::Settings mSettings;
135};
136
137class MailtransportSynchronizer : public Sink::Synchronizer {
138public:
139 MailtransportSynchronizer(const QByteArray &resourceType, const QByteArray &resourceInstanceIdentifier)
140 : Sink::Synchronizer(resourceType, resourceInstanceIdentifier)
141 {
142
143 }
144
145 KAsync::Job<void> synchronizeWithSource() Q_DECL_OVERRIDE
146 {
147 Log() << " Synchronizing";
148 return KAsync::start<void>([this](KAsync::Future<void> future) {
149 Sink::Query query;
150 QList<ApplicationDomain::Mail> toSend;
151 Log() << " Looking for mail";
152 store().reader<ApplicationDomain::Mail>().query(query, [&](const ApplicationDomain::Mail &mail) -> bool {
153 Trace() << "Found mail: " << mail.identifier();
154 // if (!mail.isSent()) {
155 toSend << mail;
156 // }
157 return true;
158 });
159 auto job = KAsync::null<void>();
160 for (const auto &m : toSend) {
161 job = job.then(send(m, mSettings)).then<void>([]() {
162 //on success, mark the mail as sent and move it to a separate place
163 //TODO
164 });
165 }
166 job = job.then<void>([&future]() {
167 future.setFinished();
168 },
169 [&future](int errorCode, const QString &errorString) {
170 future.setFinished();
171 });
172 job.exec();
173 });
174 }
175
176public:
177 QByteArray mResourceInstanceIdentifier;
178 MailtransportResource::Settings mSettings;
179};
180
181MailtransportResource::MailtransportResource(const QByteArray &instanceIdentifier, const QSharedPointer<Sink::Pipeline> &pipeline)
182 : Sink::GenericResource(PLUGIN_NAME, instanceIdentifier, pipeline)
183{
184 auto config = ResourceConfig::getConfiguration(instanceIdentifier);
185 mSettings = {config.value("server").toString(),
186 config.value("username").toString(),
187 config.value("cacert").toString(),
188 config.value("password").toString(),
189 config.value("testmode").toBool()
190 };
191
192 auto synchronizer = QSharedPointer<MailtransportSynchronizer>::create(PLUGIN_NAME, instanceIdentifier);
193 synchronizer->mSettings = mSettings;
194 setupSynchronizer(synchronizer);
195
196 auto changereplay = QSharedPointer<MailtransportWriteback>::create(PLUGIN_NAME, instanceIdentifier);
197 changereplay->mSettings = mSettings;
198 setupChangereplay(changereplay);
199
200 setupPreprocessors(ENTITY_TYPE_MAIL, QVector<Sink::Preprocessor*>() << new MimeMessageMover(mResourceInstanceIdentifier));
201}
202
203void MailtransportResource::removeFromDisk(const QByteArray &instanceIdentifier)
204{
205 GenericResource::removeFromDisk(instanceIdentifier);
206 Sink::Storage(Sink::storageLocation(), instanceIdentifier + ".synchronization", Sink::Storage::ReadWrite).removeFromDisk();
207}
208
209KAsync::Job<void> MailtransportResource::inspect(int inspectionType, const QByteArray &inspectionId, const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, const QVariant &expectedValue)
210{
211 return KAsync::null<void>();
212}
23 213
24MailtransportResourceFactory::MailtransportResourceFactory(QObject *parent) 214MailtransportResourceFactory::MailtransportResourceFactory(QObject *parent)
25 : Sink::ResourceFactory(parent) 215 : Sink::ResourceFactory(parent)
@@ -29,12 +219,15 @@ MailtransportResourceFactory::MailtransportResourceFactory(QObject *parent)
29 219
30Sink::Resource *MailtransportResourceFactory::createResource(const QByteArray &instanceIdentifier) 220Sink::Resource *MailtransportResourceFactory::createResource(const QByteArray &instanceIdentifier)
31{ 221{
32 ErrorMsg() << "The mailtransport resource has no synchronizer process: " << instanceIdentifier; 222 return new MailtransportResource(instanceIdentifier);
33 return nullptr;
34} 223}
35 224
36void MailtransportResourceFactory::registerFacades(Sink::FacadeFactory &factory) 225void MailtransportResourceFactory::registerFacades(Sink::FacadeFactory &factory)
37{ 226{
38 factory.registerFacade<Sink::ApplicationDomain::Mail, MailtransportFacade>(PLUGIN_NAME); 227 factory.registerFacade<ApplicationDomain::Mail, DefaultFacade<ApplicationDomain::Mail, DomainTypeAdaptorFactory<ApplicationDomain::Mail>>>(PLUGIN_NAME);
39} 228}
40 229
230void MailtransportResourceFactory::registerAdaptorFactories(Sink::AdaptorFactoryRegistry &registry)
231{
232 registry.registerFactory<Sink::ApplicationDomain::Mail, DomainTypeAdaptorFactory<ApplicationDomain::Mail>>(PLUGIN_NAME);
233}