diff options
author | Christian Mollekopf <chrigi_1@fastmail.fm> | 2016-06-17 09:09:33 +0200 |
---|---|---|
committer | Christian Mollekopf <chrigi_1@fastmail.fm> | 2016-06-17 09:09:33 +0200 |
commit | 3f4011bcbf4ccf55edb8ea618fbf9b50f9e7bec9 (patch) | |
tree | 489d4bc4c672d60f35a20556cb16a98d871a9fe9 /examples/mailtransportresource/mailtransportresource.cpp | |
parent | 749c4d7da40bf20d240be5ad7948f4be843865cd (diff) | |
download | sink-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.cpp | 199 |
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 | |||
44 | using namespace Sink; | ||
45 | |||
46 | class MimeMessageMover : public Sink::EntityPreprocessor<ApplicationDomain::Mail> | ||
47 | { | ||
48 | public: | ||
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 | |||
94 | static 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 | ||
114 | class MailtransportWriteback : public Sink::SourceWriteBack | ||
115 | { | ||
116 | public: | ||
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 | |||
133 | public: | ||
134 | MailtransportResource::Settings mSettings; | ||
135 | }; | ||
136 | |||
137 | class MailtransportSynchronizer : public Sink::Synchronizer { | ||
138 | public: | ||
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 | |||
176 | public: | ||
177 | QByteArray mResourceInstanceIdentifier; | ||
178 | MailtransportResource::Settings mSettings; | ||
179 | }; | ||
180 | |||
181 | MailtransportResource::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 | |||
203 | void MailtransportResource::removeFromDisk(const QByteArray &instanceIdentifier) | ||
204 | { | ||
205 | GenericResource::removeFromDisk(instanceIdentifier); | ||
206 | Sink::Storage(Sink::storageLocation(), instanceIdentifier + ".synchronization", Sink::Storage::ReadWrite).removeFromDisk(); | ||
207 | } | ||
208 | |||
209 | KAsync::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 | ||
24 | MailtransportResourceFactory::MailtransportResourceFactory(QObject *parent) | 214 | MailtransportResourceFactory::MailtransportResourceFactory(QObject *parent) |
25 | : Sink::ResourceFactory(parent) | 215 | : Sink::ResourceFactory(parent) |
@@ -29,12 +219,15 @@ MailtransportResourceFactory::MailtransportResourceFactory(QObject *parent) | |||
29 | 219 | ||
30 | Sink::Resource *MailtransportResourceFactory::createResource(const QByteArray &instanceIdentifier) | 220 | Sink::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 | ||
36 | void MailtransportResourceFactory::registerFacades(Sink::FacadeFactory &factory) | 225 | void 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 | ||
230 | void MailtransportResourceFactory::registerAdaptorFactories(Sink::AdaptorFactoryRegistry ®istry) | ||
231 | { | ||
232 | registry.registerFactory<Sink::ApplicationDomain::Mail, DomainTypeAdaptorFactory<ApplicationDomain::Mail>>(PLUGIN_NAME); | ||
233 | } | ||