cutelyst 4.3.0
A C++ Web Framework built on top of Qt, using the simple approach of Catalyst (Perl) framework.
viewemail.cpp
1/*
2 * SPDX-FileCopyrightText: (C) 2015-2022 Daniel Nicoletti <dantti12@gmail.com>
3 * SPDX-License-Identifier: BSD-3-Clause
4 */
5#include "viewemail_p.h"
6
7#include <Cutelyst/application.h>
8#include <Cutelyst/context.h>
9#include <Cutelyst/response.h>
10#include <SimpleMail/emailaddress.h>
11#include <SimpleMail/mimemessage.h>
12#include <SimpleMail/mimetext.h>
13#include <SimpleMail/serverreply.h>
14
15#include <QtCore/QLoggingCategory>
16
17Q_LOGGING_CATEGORY(CUTELYST_VIEW_EMAIL, "cutelyst.view.email", QtWarningMsg)
18
19using namespace Cutelyst;
20using namespace SimpleMail;
21
23 : View(new ViewEmailPrivate, parent, name)
24{
25 initSender();
26}
27
29{
30 Q_D(const ViewEmail);
31 return d->stashKey;
32}
33
34void ViewEmail::setStashKey(const QString &stashKey)
35{
36 Q_D(ViewEmail);
37 d->stashKey = stashKey;
38 Q_EMIT changed();
39}
40
42{
43 Q_D(const ViewEmail);
44 return d->defaultContentType;
45}
46
48{
49 Q_D(ViewEmail);
50 d->defaultContentType = contentType;
51 Q_EMIT changed();
52}
53
55{
56 Q_D(const ViewEmail);
57 return d->defaultCharset;
58}
59
61{
62 Q_D(ViewEmail);
63 d->defaultCharset = charset;
64 Q_EMIT changed();
65}
66
68{
69 Q_D(const ViewEmail);
70 return d->defaultEncoding;
71}
72
74{
75 Q_D(ViewEmail);
76 d->defaultEncoding = encoding;
77 Q_EMIT changed();
78}
79
81{
82 Q_D(const ViewEmail);
83 return d->server->host();
84}
85
87{
88 Q_D(ViewEmail);
89 d->server->setHost(host);
90}
91
93{
94 Q_D(const ViewEmail);
95 return d->server->port();
96}
97
99{
100 Q_D(ViewEmail);
101 d->server->setPort(quint16(port));
102}
103
105{
106 Q_D(const ViewEmail);
107 return static_cast<ViewEmail::ConnectionType>(d->server->connectionType());
108}
109
111{
112 Q_D(ViewEmail);
113 d->server->setConnectionType(static_cast<Server::ConnectionType>(ct));
114}
115
117{
118 Q_D(const ViewEmail);
119 return static_cast<ViewEmail::AuthMethod>(d->server->authMethod());
120}
121
123{
124 Q_D(ViewEmail);
125 d->server->setAuthMethod(static_cast<Server::AuthMethod>(method));
126}
127
129{
130 Q_D(const ViewEmail);
131 return d->server->username();
132}
133
135{
136 Q_D(ViewEmail);
137 d->server->setUsername(user);
138}
139
141{
142 Q_D(const ViewEmail);
143 return d->server->password();
144}
145
147{
148 Q_D(ViewEmail);
149 d->server->setPassword(password);
150}
151
153{
154 Q_D(const ViewEmail);
155 QByteArray ret;
156 QVariantHash email = c->stash(d->stashKey).toHash();
157 if (email.isEmpty()) {
158 c->appendError(QStringLiteral(
159 "Cannot render template, template name or template stash key not defined"));
160 return ret;
161 }
162
163 MimeMessage message;
164
165 QVariant value;
166 value = email.value(QStringLiteral("to"));
167 if (value.typeId() == QMetaType::QString && !value.toString().isEmpty()) {
168 message.addTo(SimpleMail::EmailAddress{value.toString()});
169 } else if (value.typeId() == QMetaType::QStringList) {
170 const auto rcpts = value.toStringList();
171 for (const QString &rcpt : rcpts) {
172 message.addTo(SimpleMail::EmailAddress{rcpt});
173 }
174 }
175
176 value = email.value(QStringLiteral("cc"));
177 if (value.typeId() == QMetaType::QString && !value.toString().isEmpty()) {
178 message.addCc(SimpleMail::EmailAddress{value.toString()});
179 } else if (value.typeId() == QMetaType::QStringList) {
180 const auto rcpts = value.toStringList();
181 for (const QString &rcpt : rcpts) {
182 message.addCc(SimpleMail::EmailAddress{rcpt});
183 }
184 }
185
186 value = email.value(QStringLiteral("bcc"));
187 if (value.typeId() == QMetaType::QString && !value.toString().isEmpty()) {
188 message.addBcc(SimpleMail::EmailAddress{value.toString()});
189 } else if (value.typeId() == QMetaType::QStringList) {
190 const auto rcpts = value.toStringList();
191 for (const QString &rcpt : rcpts) {
192 message.addBcc(SimpleMail::EmailAddress{rcpt});
193 }
194 }
195
196 message.setSender(SimpleMail::EmailAddress{email.value(QStringLiteral("from")).toString()});
197 message.setSubject(email.value(QStringLiteral("subject")).toString());
198
199 QVariant body = email.value(QStringLiteral("body"));
200 QVariant parts = email.value(QStringLiteral("parts"));
201 if (body.isNull() && parts.isNull()) {
202 c->appendError(QStringLiteral("Can't send email without parts or body, check stash"));
203 return ret;
204 }
205
206 if (!parts.isNull()) {
207 const QVariantList partsVariant = parts.toList();
208 for (const QVariant &part : partsVariant) {
209 auto mime = part.value<std::shared_ptr<MimePart>>();
210 if (mime) {
211 message.addPart(mime);
212 } else {
213 qCCritical(CUTELYST_VIEW_EMAIL) << "Failed to cast MimePart";
214 }
215 }
216
217 auto contentTypeIt = email.constFind(QStringLiteral("content_type"));
218 if (contentTypeIt != email.constEnd() && !contentTypeIt.value().isNull() &&
219 !contentTypeIt.value().toString().isEmpty()) {
220 const QByteArray contentType = contentTypeIt.value().toString().toLatin1();
221 qCDebug(CUTELYST_VIEW_EMAIL) << "Using specified content_type" << contentType;
222 message.getContent().setContentType(contentType);
223 } else if (!d->defaultContentType.isEmpty()) {
224 qCDebug(CUTELYST_VIEW_EMAIL) << "Using default content_type" << d->defaultContentType;
225 message.getContent().setContentType(d->defaultContentType);
226 }
227 } else {
228 auto part = std::make_shared<MimeText>(body.toString());
229 d->setupAttributes(part, email);
230 message.setContent(part);
231 }
232
233 ServerReply *reply = d->server->sendMail(message);
234 connect(reply, &ServerReply::finished, reply, &ServerReply::deleteLater);
235
236 return ret;
237}
238
239ViewEmail::ViewEmail(ViewEmailPrivate *d, QObject *parent, const QString &name)
240 : View(d, parent, name)
241{
242 initSender();
243}
244
245void ViewEmail::initSender()
246{
247 Q_D(ViewEmail);
248 d->server = new Server(this);
249
250 QVariantHash config;
251 const auto app = qobject_cast<Application *>(parent());
252 if (app) {
253 config = app->config(QStringLiteral("VIEW_EMAIL")).toHash();
254 }
255
256 d->stashKey = config.value(QStringLiteral("stash_key"), QStringLiteral("email")).toString();
257
258 if (!config.value(QStringLiteral("sender_host")).isNull()) {
259 d->server->setHost(config.value(QStringLiteral("sender_host")).toString());
260 }
261 if (!config.value(QStringLiteral("sender_port")).isNull()) {
262 d->server->setPort(quint16(config.value(QStringLiteral("sender_port")).toInt()));
263 }
264 if (!config.value(QStringLiteral("sender_username")).isNull()) {
265 d->server->setUsername(config.value(QStringLiteral("sender_username")).toString());
266 }
267 if (!config.value(QStringLiteral("sender_password")).isNull()) {
268 d->server->setPassword(config.value(QStringLiteral("sender_password")).toString());
269 }
270}
271
272void ViewEmailPrivate::setupAttributes(std::shared_ptr<MimePart> part,
273 const QVariantHash &attrs) const
274{
275 auto contentTypeIt = attrs.constFind(QStringLiteral("content_type"));
276 if (contentTypeIt != attrs.constEnd() && !contentTypeIt.value().isNull() &&
277 !contentTypeIt.value().toString().isEmpty()) {
278 const QByteArray contentType = contentTypeIt.value().toString().toLatin1();
279 qCDebug(CUTELYST_VIEW_EMAIL) << "Using specified content_type" << contentType;
280 part->setContentType(contentType);
281 } else if (!defaultContentType.isEmpty()) {
282 qCDebug(CUTELYST_VIEW_EMAIL) << "Using default content_type" << defaultContentType;
283 part->setContentType(defaultContentType);
284 }
285
286 auto charsetIt = attrs.constFind(QStringLiteral("charset"));
287 if (charsetIt != attrs.constEnd() && !charsetIt.value().isNull() &&
288 !charsetIt.value().toString().isEmpty()) {
289 const QByteArray charset = charsetIt.value().toString().toLatin1();
290 qCDebug(CUTELYST_VIEW_EMAIL) << "Using specified charset" << charset;
291 part->setCharset(charset);
292 } else if (!defaultCharset.isEmpty()) {
293 qCDebug(CUTELYST_VIEW_EMAIL) << "Using default charset" << defaultCharset;
294 part->setCharset(defaultCharset);
295 }
296
297 auto encodingIt = attrs.constFind(QStringLiteral("encoding"));
298 if (encodingIt != attrs.constEnd() && !encodingIt.value().isNull() &&
299 !encodingIt.value().toString().isEmpty()) {
300 const QByteArray encoding = encodingIt.value().toString().toLatin1();
301 qCDebug(CUTELYST_VIEW_EMAIL) << "Using specified encoding" << encoding;
302 setupEncoding(part, encoding);
303 } else if (!defaultEncoding.isEmpty()) {
304 qCDebug(CUTELYST_VIEW_EMAIL) << "Using default charset" << defaultEncoding;
305 setupEncoding(part, defaultEncoding);
306 }
307}
308
309void ViewEmailPrivate::setupEncoding(std::shared_ptr<MimePart> part,
310 const QByteArray &encoding) const
311{
312 if (encoding == "7bit") {
313 part->setEncoding(MimePart::_7Bit);
314 } else if (encoding == "8bit") {
315 part->setEncoding(MimePart::_8Bit);
316 } else if (encoding == "base64") {
317 part->setEncoding(MimePart::Base64);
318 } else if (encoding == "quoted-printable") {
319 part->setEncoding(MimePart::QuotedPrintable);
320 } else {
321 qCCritical(CUTELYST_VIEW_EMAIL) << "Unknown encoding" << encoding;
322 }
323}
324
325#include "moc_viewemail.cpp"
The Cutelyst Context.
Definition context.h:42
void stash(const QVariantHash &unite)
Definition context.cpp:562
void appendError(const QString &error)
Definition context.cpp:56
Implements a web server.
Definition server.h:60
A view that sends stash data via e-mail.
Definition viewemail.h:24
QString senderUser() const
void setSenderConnectionType(ConnectionType ct)
QByteArray defaultEncoding
Definition viewemail.h:46
int senderPort() const
Definition viewemail.cpp:92
QString senderPassword() const
void setSenderUser(const QString &user)
QByteArray defaultContentType
Definition viewemail.h:36
QByteArray defaultCharset
Definition viewemail.h:41
void setSenderHost(const QString &host)
Definition viewemail.cpp:86
ConnectionType senderConnectionType() const
QString senderHost() const
Definition viewemail.cpp:80
void setStashKey(const QString &stashKey)
Definition viewemail.cpp:34
void setDefaultContentType(const QByteArray &contentType)
Definition viewemail.cpp:47
void setSenderPort(int port)
Definition viewemail.cpp:98
void setSenderAuthMethod(AuthMethod method)
void setDefaultCharset(const QByteArray &charset)
Definition viewemail.cpp:60
void setDefaultEncoding(const QByteArray &encoding)
Definition viewemail.cpp:73
AuthMethod senderAuthMethod() const
ViewEmail(QObject *parent, const QString &name=QString())
Definition viewemail.cpp:22
void setSenderPassword(const QString &password)
QByteArray render(Context *c) const override
Abstract View component for Cutelyst.
Definition view.h:25
The Cutelyst namespace holds all public Cutelyst API.
Q_EMITQ_EMIT
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QObject * parent() const const
bool isNull() const const
QList< QVariant > toList() const const
QString toString() const const
T value() const const