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 | |
parent | 749c4d7da40bf20d240be5ad7948f4be843865cd (diff) | |
download | sink-3f4011bcbf4ccf55edb8ea618fbf9b50f9e7bec9.tar.gz sink-3f4011bcbf4ccf55edb8ea618fbf9b50f9e7bec9.zip |
Initial version of the mailtransport resource
-rw-r--r-- | common/entitystore.h | 6 | ||||
-rw-r--r-- | examples/mailtransportresource/CMakeLists.txt | 4 | ||||
-rw-r--r-- | examples/mailtransportresource/facade.cpp | 142 | ||||
-rw-r--r-- | examples/mailtransportresource/facade.h | 36 | ||||
-rw-r--r-- | examples/mailtransportresource/mailtransport.cpp | 11 | ||||
-rw-r--r-- | examples/mailtransportresource/mailtransport.h | 2 | ||||
-rw-r--r-- | examples/mailtransportresource/mailtransportresource.cpp | 199 | ||||
-rw-r--r-- | examples/mailtransportresource/mailtransportresource.h | 20 | ||||
-rw-r--r-- | examples/mailtransportresource/tests/CMakeLists.txt | 11 | ||||
-rw-r--r-- | examples/mailtransportresource/tests/mailtransporttest.cpp | 94 |
10 files changed, 337 insertions, 188 deletions
diff --git a/common/entitystore.h b/common/entitystore.h index b795b26..6bfe414 100644 --- a/common/entitystore.h +++ b/common/entitystore.h | |||
@@ -54,6 +54,12 @@ public: | |||
54 | return reader.readPrevious(uid, revision); | 54 | return reader.readPrevious(uid, revision); |
55 | } | 55 | } |
56 | 56 | ||
57 | template<typename T> | ||
58 | EntityReader<T> reader() | ||
59 | { | ||
60 | return EntityReader<T>(mResourceType, mResourceInstanceIdentifier, mTransaction); | ||
61 | } | ||
62 | |||
57 | private: | 63 | private: |
58 | QByteArray mResourceType; | 64 | QByteArray mResourceType; |
59 | QByteArray mResourceInstanceIdentifier; | 65 | QByteArray mResourceInstanceIdentifier; |
diff --git a/examples/mailtransportresource/CMakeLists.txt b/examples/mailtransportresource/CMakeLists.txt index c9b0401..d16e779 100644 --- a/examples/mailtransportresource/CMakeLists.txt +++ b/examples/mailtransportresource/CMakeLists.txt | |||
@@ -9,8 +9,10 @@ find_package(CURL 7.20.0 REQUIRED) | |||
9 | include_directories(${CURL_INCLUDE_DIRS}) | 9 | include_directories(${CURL_INCLUDE_DIRS}) |
10 | 10 | ||
11 | 11 | ||
12 | add_library(${PROJECT_NAME} SHARED facade.cpp mailtransportresource.cpp mailtransport.cpp) | 12 | add_library(${PROJECT_NAME} SHARED mailtransportresource.cpp mailtransport.cpp) |
13 | qt5_use_modules(${PROJECT_NAME} Core Network) | 13 | qt5_use_modules(${PROJECT_NAME} Core Network) |
14 | target_link_libraries(${PROJECT_NAME} sink KF5::Mime ${CURL_LIBRARIES}) | 14 | target_link_libraries(${PROJECT_NAME} sink KF5::Mime ${CURL_LIBRARIES}) |
15 | 15 | ||
16 | add_subdirectory(tests) | ||
17 | |||
16 | install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION ${SINK_RESOURCE_PLUGINS_PATH}) | 18 | install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION ${SINK_RESOURCE_PLUGINS_PATH}) |
diff --git a/examples/mailtransportresource/facade.cpp b/examples/mailtransportresource/facade.cpp deleted file mode 100644 index cd0dd62..0000000 --- a/examples/mailtransportresource/facade.cpp +++ /dev/null | |||
@@ -1,142 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014 Christian Mollekopf <chrigi_1@fastmail.fm> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the | ||
16 | * Free Software Foundation, Inc., | ||
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
18 | */ | ||
19 | |||
20 | #include "facade.h" | ||
21 | |||
22 | #include <QDir> | ||
23 | #include <QFileInfo> | ||
24 | #include <QSettings> | ||
25 | #include <QStandardPaths> | ||
26 | #include <QUuid> | ||
27 | #include <KMime/Message> | ||
28 | |||
29 | #include "resultprovider.h" | ||
30 | #include "mailtransport.h" | ||
31 | #include <log.h> | ||
32 | #include <resourceconfig.h> | ||
33 | |||
34 | static QString dataDirectory(const QByteArray &identifier) | ||
35 | { | ||
36 | return QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/sink/mailtransport/" + identifier; | ||
37 | } | ||
38 | |||
39 | class Outbox { | ||
40 | public: | ||
41 | Outbox(const QByteArray &identifier) : mIdentifier(identifier) | ||
42 | { | ||
43 | |||
44 | } | ||
45 | |||
46 | static QString fileName(const QByteArray &resourceId, const QByteArray &messageId) | ||
47 | { | ||
48 | return dataDirectory(resourceId)+"/" + messageId; | ||
49 | } | ||
50 | |||
51 | void add(const QByteArray &messageId, const QString &messagePath, QMap<QByteArray, QString> config) | ||
52 | { | ||
53 | QDir dir; | ||
54 | dir.mkpath(dataDirectory(mIdentifier)); | ||
55 | if (!QFile(messagePath).rename(fileName(mIdentifier, messageId))) { | ||
56 | ErrorMsg() << "Failed to move the file:"; | ||
57 | ErrorMsg() << messagePath << " to " << fileName(mIdentifier, messageId); | ||
58 | } | ||
59 | //TODO store settings | ||
60 | // QSettings settings(dataDirectory(mIdentifier) + "/messageId.ini", QSettings::IniFormat); | ||
61 | } | ||
62 | |||
63 | void dispatch(const QByteArray &messageId) | ||
64 | { | ||
65 | QFile mimeMessage(fileName(mIdentifier, messageId)); | ||
66 | if (!mimeMessage.open(QIODevice::ReadOnly)) { | ||
67 | ErrorMsg() << "Failed to open mime message: " << mimeMessage.errorString(); | ||
68 | ErrorMsg() << fileName(mIdentifier, messageId); | ||
69 | return; | ||
70 | } | ||
71 | |||
72 | auto msg = KMime::Message::Ptr::create(); | ||
73 | msg->setHead(KMime::CRLFtoLF(mimeMessage.readAll())); | ||
74 | msg->parse(); | ||
75 | MailTransport::sendMessage(msg, mServer, mUsername, mPassword, mCaCert); | ||
76 | Trace() << "Sent message: " << msg->subject(); | ||
77 | } | ||
78 | |||
79 | void setServer(const QByteArray &server, const QByteArray &username, const QByteArray &caCert) | ||
80 | { | ||
81 | mServer = server; | ||
82 | mUsername = username; | ||
83 | mCaCert = caCert; | ||
84 | } | ||
85 | |||
86 | void setPassword(const QByteArray &password) | ||
87 | { | ||
88 | mPassword = password; | ||
89 | } | ||
90 | |||
91 | private: | ||
92 | QByteArray mServer; | ||
93 | QByteArray mUsername; | ||
94 | QByteArray mPassword; | ||
95 | QByteArray mCaCert; | ||
96 | QByteArray mIdentifier; | ||
97 | }; | ||
98 | |||
99 | MailtransportFacade::MailtransportFacade(const QByteArray &identifier) : Sink::StoreFacade<Sink::ApplicationDomain::Mail>(), mIdentifier(identifier) | ||
100 | { | ||
101 | } | ||
102 | |||
103 | MailtransportFacade::~MailtransportFacade() | ||
104 | { | ||
105 | } | ||
106 | |||
107 | KAsync::Job<void> MailtransportFacade::create(const Sink::ApplicationDomain::Mail &mail) | ||
108 | { | ||
109 | Trace() << "Called create: "; | ||
110 | return KAsync::start<void>([mail, this]() { | ||
111 | auto config = ResourceConfig::getConfiguration(mIdentifier); | ||
112 | |||
113 | auto identifier = Sink::Storage::generateUid(); | ||
114 | Trace() << "Sending new message: " << identifier; | ||
115 | Trace() << config.value("server").toByteArray() << config.value("username").toByteArray() << config.value("cacert").toByteArray(); | ||
116 | |||
117 | Outbox outbox(mIdentifier); | ||
118 | outbox.setServer(config.value("server").toByteArray(), config.value("username").toByteArray(), config.value("cacert").toByteArray()); | ||
119 | //FIXME remove and somehow retrieve the password on demand | ||
120 | outbox.setPassword(config.value("password").toByteArray()); | ||
121 | |||
122 | const QByteArray mimeMessage = mail.getProperty("mimeMessage").toByteArray(); | ||
123 | QMap<QByteArray, QString> configurationValues; | ||
124 | outbox.add(identifier, mimeMessage, configurationValues); | ||
125 | outbox.dispatch(identifier); | ||
126 | }); | ||
127 | } | ||
128 | |||
129 | KAsync::Job<void> MailtransportFacade::modify(const Sink::ApplicationDomain::Mail &mail) | ||
130 | { | ||
131 | return KAsync::error<void>(0, "Not implemented."); | ||
132 | } | ||
133 | |||
134 | KAsync::Job<void> MailtransportFacade::remove(const Sink::ApplicationDomain::Mail &mail) | ||
135 | { | ||
136 | return KAsync::error<void>(0, "Not implemented."); | ||
137 | } | ||
138 | |||
139 | QPair<KAsync::Job<void>, typename Sink::ResultEmitter<Sink::ApplicationDomain::Mail::Ptr>::Ptr> MailtransportFacade::load(const Sink::Query &query) | ||
140 | { | ||
141 | return qMakePair(KAsync::error<void>(0, "Not implemented."), Sink::ResultEmitter<Sink::ApplicationDomain::Mail::Ptr>::Ptr()); | ||
142 | } | ||
diff --git a/examples/mailtransportresource/facade.h b/examples/mailtransportresource/facade.h deleted file mode 100644 index 858f73a..0000000 --- a/examples/mailtransportresource/facade.h +++ /dev/null | |||
@@ -1,36 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014 Christian Mollekopf <chrigi_1@fastmail.fm> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the | ||
16 | * Free Software Foundation, Inc., | ||
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
18 | */ | ||
19 | |||
20 | #pragma once | ||
21 | |||
22 | #include "common/facade.h" | ||
23 | |||
24 | class MailtransportFacade : public Sink::StoreFacade<Sink::ApplicationDomain::Mail> | ||
25 | { | ||
26 | public: | ||
27 | MailtransportFacade(const QByteArray &instanceIdentifier); | ||
28 | virtual ~MailtransportFacade(); | ||
29 | KAsync::Job<void> create(const Sink::ApplicationDomain::Mail &resource) Q_DECL_OVERRIDE; | ||
30 | KAsync::Job<void> modify(const Sink::ApplicationDomain::Mail &resource) Q_DECL_OVERRIDE; | ||
31 | KAsync::Job<void> remove(const Sink::ApplicationDomain::Mail &resource) Q_DECL_OVERRIDE; | ||
32 | QPair<KAsync::Job<void>, typename Sink::ResultEmitter<Sink::ApplicationDomain::Mail::Ptr>::Ptr> load(const Sink::Query &query) Q_DECL_OVERRIDE; | ||
33 | private: | ||
34 | QByteArray mIdentifier; | ||
35 | }; | ||
36 | |||
diff --git a/examples/mailtransportresource/mailtransport.cpp b/examples/mailtransportresource/mailtransport.cpp index 49d858e..5985562 100644 --- a/examples/mailtransportresource/mailtransport.cpp +++ b/examples/mailtransportresource/mailtransport.cpp | |||
@@ -58,7 +58,7 @@ static size_t payload_source(void *ptr, size_t size, size_t nmemb, void *userp) | |||
58 | } | 58 | } |
59 | 59 | ||
60 | 60 | ||
61 | void sendMessageCurl(const char *to[], int numTos, const char *cc[], int numCcs, const char *msg, bool useTls, const char* from, const char *username, const char *password, const char *server, bool verifyPeer) | 61 | bool sendMessageCurl(const char *to[], int numTos, const char *cc[], int numCcs, const char *msg, bool useTls, const char* from, const char *username, const char *password, const char *server, bool verifyPeer) |
62 | { | 62 | { |
63 | //For ssl use "smtps://mainserver.example.net | 63 | //For ssl use "smtps://mainserver.example.net |
64 | const char* cacert = 0; // = "/path/to/certificate.pem"; | 64 | const char* cacert = 0; // = "/path/to/certificate.pem"; |
@@ -121,15 +121,17 @@ void sendMessageCurl(const char *to[], int numTos, const char *cc[], int numCcs, | |||
121 | } | 121 | } |
122 | curl_slist_free_all(recipients); | 122 | curl_slist_free_all(recipients); |
123 | curl_easy_cleanup(curl); | 123 | curl_easy_cleanup(curl); |
124 | return res == CURLE_OK; | ||
124 | } | 125 | } |
126 | return false; | ||
125 | } | 127 | } |
126 | 128 | ||
127 | }; | 129 | }; |
128 | 130 | ||
129 | void MailTransport::sendMessage(const KMime::Message::Ptr &message, const QByteArray &server, const QByteArray &username, const QByteArray &password, const QByteArray &cacert) | 131 | bool MailTransport::sendMessage(const KMime::Message::Ptr &message, const QByteArray &server, const QByteArray &username, const QByteArray &password, const QByteArray &cacert) |
130 | { | 132 | { |
131 | QByteArray msg = message->encodedContent(); | 133 | QByteArray msg = message->encodedContent(); |
132 | qWarning() << "Sending message " << msg; | 134 | qDebug() << "Sending message " << msg; |
133 | 135 | ||
134 | QByteArray from(message->from(true)->mailboxes().isEmpty() ? QByteArray() : message->from(true)->mailboxes().first().address()); | 136 | QByteArray from(message->from(true)->mailboxes().isEmpty() ? QByteArray() : message->from(true)->mailboxes().first().address()); |
135 | QList<QByteArray> toList; | 137 | QList<QByteArray> toList; |
@@ -155,6 +157,5 @@ void MailTransport::sendMessage(const KMime::Message::Ptr &message, const QByteA | |||
155 | cc[i] = ccList.at(i); | 157 | cc[i] = ccList.at(i); |
156 | } | 158 | } |
157 | 159 | ||
158 | sendMessageCurl(to, numTos, cc, numCcs, msg, useTls, from.isEmpty() ? nullptr : from, username, password, server, verifyPeer); | 160 | return sendMessageCurl(to, numTos, cc, numCcs, msg, useTls, from.isEmpty() ? nullptr : from, username, password, server, verifyPeer); |
159 | qWarning() << "Message sent"; | ||
160 | } | 161 | } |
diff --git a/examples/mailtransportresource/mailtransport.h b/examples/mailtransportresource/mailtransport.h index 2eb30a0..6cd3452 100644 --- a/examples/mailtransportresource/mailtransport.h +++ b/examples/mailtransportresource/mailtransport.h | |||
@@ -24,5 +24,5 @@ | |||
24 | 24 | ||
25 | namespace MailTransport | 25 | namespace MailTransport |
26 | { | 26 | { |
27 | void sendMessage(const KMime::Message::Ptr &message, const QByteArray &server, const QByteArray &username, const QByteArray &password, const QByteArray &cacert); | 27 | bool sendMessage(const KMime::Message::Ptr &message, const QByteArray &server, const QByteArray &username, const QByteArray &password, const QByteArray &cacert); |
28 | }; | 28 | }; |
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 | } | ||
diff --git a/examples/mailtransportresource/mailtransportresource.h b/examples/mailtransportresource/mailtransportresource.h index 2ccca0a..6622ea6 100644 --- a/examples/mailtransportresource/mailtransportresource.h +++ b/examples/mailtransportresource/mailtransportresource.h | |||
@@ -20,10 +20,29 @@ | |||
20 | #pragma once | 20 | #pragma once |
21 | 21 | ||
22 | #include "common/resource.h" | 22 | #include "common/resource.h" |
23 | #include "common/genericresource.h" | ||
23 | 24 | ||
24 | //TODO: a little ugly to have this in two places, once here and once in Q_PLUGIN_METADATA | 25 | //TODO: a little ugly to have this in two places, once here and once in Q_PLUGIN_METADATA |
25 | #define PLUGIN_NAME "org.kde.mailtransport" | 26 | #define PLUGIN_NAME "org.kde.mailtransport" |
26 | 27 | ||
28 | class MailtransportResource : public Sink::GenericResource | ||
29 | { | ||
30 | public: | ||
31 | MailtransportResource(const QByteArray &instanceIdentifier, const QSharedPointer<Sink::Pipeline> &pipeline = QSharedPointer<Sink::Pipeline>()); | ||
32 | KAsync::Job<void> inspect(int inspectionType, const QByteArray &inspectionId, const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, const QVariant &expectedValue) Q_DECL_OVERRIDE; | ||
33 | static void removeFromDisk(const QByteArray &instanceIdentifier); | ||
34 | |||
35 | struct Settings { | ||
36 | QString server; | ||
37 | QString username; | ||
38 | QString cacert; | ||
39 | QString password; | ||
40 | bool testMode; | ||
41 | }; | ||
42 | private: | ||
43 | Settings mSettings; | ||
44 | }; | ||
45 | |||
27 | class MailtransportResourceFactory : public Sink::ResourceFactory | 46 | class MailtransportResourceFactory : public Sink::ResourceFactory |
28 | { | 47 | { |
29 | Q_OBJECT | 48 | Q_OBJECT |
@@ -35,5 +54,6 @@ public: | |||
35 | 54 | ||
36 | Sink::Resource *createResource(const QByteArray &instanceIdentifier) Q_DECL_OVERRIDE; | 55 | Sink::Resource *createResource(const QByteArray &instanceIdentifier) Q_DECL_OVERRIDE; |
37 | void registerFacades(Sink::FacadeFactory &factory) Q_DECL_OVERRIDE; | 56 | void registerFacades(Sink::FacadeFactory &factory) Q_DECL_OVERRIDE; |
57 | void registerAdaptorFactories(Sink::AdaptorFactoryRegistry ®istry) Q_DECL_OVERRIDE; | ||
38 | }; | 58 | }; |
39 | 59 | ||
diff --git a/examples/mailtransportresource/tests/CMakeLists.txt b/examples/mailtransportresource/tests/CMakeLists.txt new file mode 100644 index 0000000..458b462 --- /dev/null +++ b/examples/mailtransportresource/tests/CMakeLists.txt | |||
@@ -0,0 +1,11 @@ | |||
1 | set(CMAKE_AUTOMOC ON) | ||
2 | include_directories( | ||
3 | ${CMAKE_CURRENT_BINARY_DIR} | ||
4 | ) | ||
5 | |||
6 | include(SinkTest) | ||
7 | |||
8 | auto_tests ( | ||
9 | mailtransporttest | ||
10 | ) | ||
11 | target_link_libraries(mailtransporttest sink_resource_mailtransport) | ||
diff --git a/examples/mailtransportresource/tests/mailtransporttest.cpp b/examples/mailtransportresource/tests/mailtransporttest.cpp new file mode 100644 index 0000000..564b4cb --- /dev/null +++ b/examples/mailtransportresource/tests/mailtransporttest.cpp | |||
@@ -0,0 +1,94 @@ | |||
1 | #include <QtTest> | ||
2 | |||
3 | #include "tests/testutils.h" | ||
4 | #include "../mailtransport.h" | ||
5 | |||
6 | #include "common/test.h" | ||
7 | #include "common/store.h" | ||
8 | #include "common/resourcecontrol.h" | ||
9 | #include "common/domain/applicationdomaintype.h" | ||
10 | #include "common/log.h" | ||
11 | |||
12 | using namespace Sink; | ||
13 | using namespace Sink::ApplicationDomain; | ||
14 | |||
15 | class MailtransportTest : public QObject | ||
16 | { | ||
17 | Q_OBJECT | ||
18 | |||
19 | Sink::ApplicationDomain::SinkResource createResource() | ||
20 | { | ||
21 | auto resource = ApplicationDomain::MailtransportResource::create("account1"); | ||
22 | resource.setProperty("server", "localhost"); | ||
23 | // resource.setProperty("port", 993); | ||
24 | resource.setProperty("user", "doe"); | ||
25 | resource.setProperty("password", "doe"); | ||
26 | resource.setProperty("testmode", true); | ||
27 | return resource; | ||
28 | } | ||
29 | |||
30 | void removeResourceFromDisk(const QByteArray &identifier) | ||
31 | { | ||
32 | // ::MailtransportResource::removeFromDisk(identifier); | ||
33 | } | ||
34 | QByteArray mResourceInstanceIdentifier; | ||
35 | |||
36 | private slots: | ||
37 | |||
38 | void initTestCase() | ||
39 | { | ||
40 | Test::initTest(); | ||
41 | Log::setDebugOutputLevel(Sink::Log::Trace); | ||
42 | // resetTestEnvironment(); | ||
43 | auto resource = createResource(); | ||
44 | QVERIFY(!resource.identifier().isEmpty()); | ||
45 | VERIFYEXEC(Store::create(resource)); | ||
46 | mResourceInstanceIdentifier = resource.identifier(); | ||
47 | // mCapabilities = resource.getProperty("capabilities").value<QByteArrayList>(); | ||
48 | qWarning() << "FOooooooooooooooooooo"; | ||
49 | } | ||
50 | |||
51 | void cleanup() | ||
52 | { | ||
53 | // VERIFYEXEC(ResourceControl::shutdown(mResourceInstanceIdentifier)); | ||
54 | // removeResourceFromDisk(mResourceInstanceIdentifier); | ||
55 | } | ||
56 | |||
57 | void init() | ||
58 | { | ||
59 | // qDebug(); | ||
60 | // qDebug() << "-----------------------------------------"; | ||
61 | // qDebug(); | ||
62 | // VERIFYEXEC(ResourceControl::start(mResourceInstanceIdentifier)); | ||
63 | } | ||
64 | |||
65 | void testSendMail() | ||
66 | { | ||
67 | auto message = KMime::Message::Ptr::create(); | ||
68 | message->subject(true)->fromUnicodeString(QString::fromLatin1("Foobar"), "utf8"); | ||
69 | message->assemble(); | ||
70 | |||
71 | auto mail = ApplicationDomain::Mail::create(mResourceInstanceIdentifier); | ||
72 | mail.setMimeMessage(message->encodedContent()); | ||
73 | |||
74 | VERIFYEXEC(Store::create(mail)); | ||
75 | VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier)); | ||
76 | VERIFYEXEC(Store::synchronize(Query::ResourceFilter(mResourceInstanceIdentifier))); | ||
77 | |||
78 | //TODO verify the mail has been sent | ||
79 | |||
80 | // auto modifiedMail = Store::readOne<ApplicationDomain::Mail>(Query::IdentityFilter(mail)); | ||
81 | // VERIFYEXEC(Store::modify(modifiedMail)); | ||
82 | // VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier)); | ||
83 | // VERIFYEXEC(ResourceControl::flushReplayQueue(QByteArrayList() << mResourceInstanceIdentifier)); | ||
84 | |||
85 | } | ||
86 | |||
87 | //TODO test mail that fails to be sent. add a special header to the mail and have the resource fail sending. Ensure we can modify the mail to fix sending of the message. | ||
88 | |||
89 | }; | ||
90 | |||
91 | |||
92 | QTEST_MAIN(MailtransportTest) | ||
93 | |||
94 | #include "mailtransporttest.moc" | ||