Cutelyst  2.3.0
viewemail.cpp
1 /*
2  * Copyright (C) 2015-2018 Daniel Nicoletti <dantti12@gmail.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library 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 GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 #include "viewemail_p.h"
19 
20 #include <Cutelyst/application.h>
21 #include <Cutelyst/context.h>
22 #include <Cutelyst/response.h>
23 
24 #include <QtCore/QLoggingCategory>
25 
26 #include <SimpleMail/mimemessage.h>
27 #include <SimpleMail/emailaddress.h>
28 #include <SimpleMail/mimetext.h>
29 
30 Q_LOGGING_CATEGORY(CUTELYST_VIEW_EMAIL, "cutelyst.view.email")
31 
32 using namespace Cutelyst;
33 using namespace SimpleMail;
34 
35 ViewEmail::ViewEmail(QObject *parent, const QString &name) : View(parent, name)
36  , d_ptr(new ViewEmailPrivate)
37 {
38  initSender();
39 }
40 
41 ViewEmail::~ViewEmail()
42 {
43  delete d_ptr;
44 }
45 
46 QString ViewEmail::stashKey() const
47 {
48  Q_D(const ViewEmail);
49  return d->stashKey;
50 }
51 
52 void ViewEmail::setStashKey(const QString &stashKey)
53 {
54  Q_D(ViewEmail);
55  d->stashKey = stashKey;
56  Q_EMIT changed();
57 }
58 
59 QByteArray ViewEmail::defaultContentType() const
60 {
61  Q_D(const ViewEmail);
62  return d->defaultContentType;
63 }
64 
65 void ViewEmail::setDefaultContentType(const QByteArray &contentType)
66 {
67  Q_D(ViewEmail);
68  d->defaultContentType = contentType;
69  Q_EMIT changed();
70 }
71 
72 QByteArray ViewEmail::defaultCharset() const
73 {
74  Q_D(const ViewEmail);
75  return d->defaultCharset;
76 }
77 
78 void ViewEmail::setDefaultCharset(const QByteArray &charset)
79 {
80  Q_D(ViewEmail);
81  d->defaultCharset = charset;
82  Q_EMIT changed();
83 }
84 
85 QByteArray ViewEmail::defaultEncoding() const
86 {
87  Q_D(const ViewEmail);
88  return d->defaultEncoding;
89 }
90 
91 void ViewEmail::setDefaultEncoding(const QByteArray &encoding)
92 {
93  Q_D(ViewEmail);
94  d->defaultEncoding = encoding;
95  Q_EMIT changed();
96 }
97 
98 QString ViewEmail::senderHost() const
99 {
100  Q_D(const ViewEmail);
101  return d->sender->host();
102 }
103 
104 void ViewEmail::setSenderHost(const QString &host)
105 {
106  Q_D(ViewEmail);
107  d->sender->setHost(host);
108 }
109 
111 {
112  Q_D(const ViewEmail);
113  return d->sender->port();
114 }
115 
117 {
118  Q_D(ViewEmail);
119  d->sender->setPort(port);
120 }
121 
123 {
124  Q_D(const ViewEmail);
125  return static_cast<ViewEmail::ConnectionType>(d->sender->connectionType());
126 }
127 
129 {
130  Q_D(ViewEmail);
131  d->sender->setConnectionType(static_cast<Sender::ConnectionType>(ct));
132 }
133 
135 {
136  Q_D(const ViewEmail);
137  return static_cast<ViewEmail::AuthMethod>(d->sender->authMethod());
138 }
139 
141 {
142  Q_D(ViewEmail);
143  d->sender->setAuthMethod(static_cast<Sender::AuthMethod>(method));
144 }
145 
146 QString ViewEmail::senderUser() const
147 {
148  Q_D(const ViewEmail);
149  return d->sender->user();
150 }
151 
152 void ViewEmail::setSenderUser(const QString &user)
153 {
154  Q_D(ViewEmail);
155  d->sender->setUser(user);
156 }
157 
159 {
160  Q_D(const ViewEmail);
161  return d->sender->password();
162 }
163 
164 void ViewEmail::setSenderPassword(const QString &password)
165 {
166  Q_D(ViewEmail);
167  d->sender->setPassword(password);
168 }
169 
170 QByteArray ViewEmail::render(Context *c) const
171 {
172  Q_D(const ViewEmail);
173  QByteArray ret;
174  QVariantHash email = c->stash(d->stashKey).toHash();
175  if (email.isEmpty()) {
176  c->error(QStringLiteral("Cannot render template, template name or template stash key not defined"));
177  return ret;
178  }
179 
180  MimeMessage message;
181 
182  QVariant value;
183  value = email.value(QStringLiteral("to"));
184  if (value.type() == QVariant::String && !value.toString().isEmpty()) {
185  message.addTo(value.toString());
186  }
187 
188  value = email.value(QStringLiteral("cc"));
189  if (value.type() == QVariant::String && !value.toString().isEmpty()) {
190  message.addCc(value.toString());
191  }
192 
193  value = email.value(QStringLiteral("from"));
194  if (value.type() == QVariant::String && !value.toString().isEmpty()) {
195  message.setSender(value.toString());
196  }
197 
198  value = email.value(QStringLiteral("subject"));
199  if (value.type() == QVariant::String && !value.toString().isEmpty()) {
200  message.setSubject(value.toString());
201  }
202 
203  QVariant body = email.value(QStringLiteral("body"));
204  QVariant parts = email.value(QStringLiteral("parts"));
205  if (body.isNull() && parts.isNull()) {
206  c->error(QStringLiteral("Can't send email without parts or body, check stash"));
207  return ret;
208  }
209 
210  if (!parts.isNull()) {
211  const QVariantList partsVariant = parts.toList();
212  for (const QVariant &part : partsVariant) {
213  MimePart *mime = part.value<MimePart*>();
214  if (mime) {
215  message.addPart(mime);
216  } else {
217  qCCritical(CUTELYST_VIEW_EMAIL) << "Failed to cast MimePart";
218  }
219  }
220 
221  auto contentTypeIt = email.constFind(QStringLiteral("content_type"));
222  if (contentTypeIt != email.constEnd()
223  && !contentTypeIt.value().isNull()
224  && !contentTypeIt.value().toString().isEmpty()) {
225  const QByteArray contentType = contentTypeIt.value().toString().toLatin1();
226  qCDebug(CUTELYST_VIEW_EMAIL) << "Using specified content_type" << contentType;
227  message.getContent().setContentType(contentType);
228  } else if (!d->defaultContentType.isEmpty()) {
229  qCDebug(CUTELYST_VIEW_EMAIL) << "Using default content_type" << d->defaultContentType;
230  message.getContent().setContentType(d->defaultContentType);
231  }
232  } else {
233  MimeText *part = new MimeText(body.toString());
234  d->setupAttributes(part, email);
235  message.setContent(part);
236  }
237 
238  if (!d->sender->sendMail(message)) {
239  c->error(QString::fromLatin1(d->sender->responseText()));
240  return ret;
241  }
242 
243  return ret;
244 }
245 
246 ViewEmail::ViewEmail(ViewEmailPrivate *d, QObject *parent, const QString &name) : View(parent, name)
247 {
248  d_ptr = d;
249 
250  initSender();
251 }
252 
253 void ViewEmail::initSender()
254 {
255  Q_D(ViewEmail);
256  d->sender = new Sender(this);
257 
258  QVariantHash config;
259  const auto app = qobject_cast<Application *>(parent());
260  if (app) {
261  config = app->config(QStringLiteral("VIEW_EMAIL")).toHash();
262  }
263 
264  d->stashKey = config.value(QStringLiteral("stash_key"), QStringLiteral("email")).toString();
265 
266  if (!config.value(QStringLiteral("sender_host")).isNull()) {
267  d->sender->setHost(config.value(QStringLiteral("sender_host")).toString());
268  }
269  if (!config.value(QStringLiteral("sender_port")).isNull()) {
270  d->sender->setPort(config.value(QStringLiteral("sender_port")).toInt());
271  }
272  if (!config.value(QStringLiteral("sender_username")).isNull()) {
273  d->sender->setUser(config.value(QStringLiteral("sender_username")).toString());
274  }
275  if (!config.value(QStringLiteral("sender_password")).isNull()) {
276  d->sender->setPassword(config.value(QStringLiteral("sender_password")).toString());
277  }
278 }
279 
280 
281 void ViewEmailPrivate::setupAttributes(MimePart *part, const QVariantHash &attrs) const
282 {
283  auto contentTypeIt = attrs.constFind(QStringLiteral("content_type"));
284  if (contentTypeIt != attrs.constEnd()
285  && !contentTypeIt.value().isNull()
286  && !contentTypeIt.value().toString().isEmpty()) {
287  const QByteArray contentType = contentTypeIt.value().toString().toLatin1();
288  qCDebug(CUTELYST_VIEW_EMAIL) << "Using specified content_type" << contentType;
289  part->setContentType(contentType);
290  } else if (!defaultContentType.isEmpty()) {
291  qCDebug(CUTELYST_VIEW_EMAIL) << "Using default content_type" << defaultContentType;
292  part->setContentType(defaultContentType);
293  }
294 
295  auto charsetIt = attrs.constFind(QStringLiteral("charset"));
296  if (charsetIt != attrs.constEnd()
297  && !charsetIt.value().isNull()
298  && !charsetIt.value().toString().isEmpty()) {
299  const QByteArray charset = charsetIt.value().toString().toLatin1();
300  qCDebug(CUTELYST_VIEW_EMAIL) << "Using specified charset" << charset;
301  part->setCharset(charset);
302  } else if (!defaultCharset.isEmpty()) {
303  qCDebug(CUTELYST_VIEW_EMAIL) << "Using default charset" << defaultCharset;
304  part->setCharset(defaultCharset);
305  }
306 
307  auto encodingIt = attrs.constFind(QStringLiteral("encoding"));
308  if (encodingIt != attrs.constEnd()
309  && !encodingIt.value().isNull()
310  && !encodingIt.value().toString().isEmpty()) {
311  const QByteArray encoding = encodingIt.value().toString().toLatin1();
312  qCDebug(CUTELYST_VIEW_EMAIL) << "Using specified encoding" << encoding;
313  setupEncoding(part, encoding);
314  } else if (!defaultEncoding.isEmpty()) {
315  qCDebug(CUTELYST_VIEW_EMAIL) << "Using default charset" << defaultEncoding;
316  setupEncoding(part, defaultEncoding);
317  }
318 }
319 
320 void ViewEmailPrivate::setupEncoding(MimePart *part, const QByteArray &encoding) const
321 {
322  if (encoding == "7bit") {
323  part->setEncoding(MimePart::_7Bit);
324  } else if (encoding == "8bit") {
325  part->setEncoding(MimePart::_8Bit);
326  } else if (encoding == "base64") {
327  part->setEncoding(MimePart::Base64);
328  } else if (encoding == "quoted-printable") {
329  part->setEncoding(MimePart::QuotedPrintable);
330  } else {
331  qCCritical(CUTELYST_VIEW_EMAIL) << "Unknown encoding" << encoding;
332  }
333 }
334 
335 #include "moc_viewemail.cpp"
void setDefaultEncoding(const QByteArray &encoding)
Definition: viewemail.cpp:91
void setSenderUser(const QString &user)
Definition: viewemail.cpp:152
ViewEmail(QObject *parent, const QString &name=QString())
Constructs a new ViewEmail object with the given parent and name.
Definition: viewemail.cpp:35
void setSenderPassword(const QString &password)
Definition: viewemail.cpp:164
int senderPort() const
Definition: viewemail.cpp:110
void setSenderHost(const QString &host)
Definition: viewemail.cpp:104
The Cutelyst Context.
Definition: context.h:50
QByteArray render(Context *c) const override
Definition: viewemail.cpp:170
QByteArray defaultCharset() const
QByteArray defaultContentType() const
QString name() const
Definition: component.cpp:39
AuthMethod senderAuthMethod() const
Definition: viewemail.cpp:134
ConnectionType senderConnectionType() const
Definition: viewemail.cpp:122
QVariant config(const QString &key, const QVariant &defaultValue=QVariant()) const
The Cutelyst namespace holds all public Cutelyst API.
Definition: Mainpage.dox:7
void setSenderPort(int port)
Definition: viewemail.cpp:116
QByteArray defaultEncoding() const
QString senderPassword() const
Definition: viewemail.cpp:158
void setDefaultCharset(const QByteArray &charset)
Definition: viewemail.cpp:78
void setSenderAuthMethod(AuthMethod method)
Definition: viewemail.cpp:140
Cutelyst View abstract view component
Definition: view.h:33
QString stashKey() const
The Cutelyst Application.
Definition: application.h:55
void setStashKey(const QString &stashKey)
Definition: viewemail.cpp:52
QString senderHost() const
Definition: viewemail.cpp:98
void setDefaultContentType(const QByteArray &contentType)
Definition: viewemail.cpp:65
bool error() const
Returns true if an error was set.
Definition: context.cpp:63
void setSenderConnectionType(ConnectionType ct)
Definition: viewemail.cpp:128
void stash(const QVariantHash &unite)
Definition: context.h:515
QString senderUser() const
Definition: viewemail.cpp:146