Cutelyst  1.11.0
viewemail.cpp
1 /*
2  * Copyright (C) 2015-2017 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 }
57 
58 QByteArray ViewEmail::defaultContentType() const
59 {
60  Q_D(const ViewEmail);
61  return d->defaultContentType;
62 }
63 
64 void ViewEmail::setDefaultContentType(const QByteArray &contentType)
65 {
66  Q_D(ViewEmail);
67  d->defaultContentType = contentType;
68 }
69 
70 QByteArray ViewEmail::defaultCharset() const
71 {
72  Q_D(const ViewEmail);
73  return d->defaultCharset;
74 }
75 
76 void ViewEmail::setDefaultCharset(const QByteArray &charset)
77 {
78  Q_D(ViewEmail);
79  d->defaultCharset = charset;
80 }
81 
82 QByteArray ViewEmail::defaultEncoding() const
83 {
84  Q_D(const ViewEmail);
85  return d->defaultEncoding;
86 }
87 
88 void ViewEmail::setDefaultEncoding(const QByteArray &encoding)
89 {
90  Q_D(ViewEmail);
91  d->defaultEncoding = encoding;
92 }
93 
94 QString ViewEmail::senderHost() const
95 {
96  Q_D(const ViewEmail);
97  return d->sender->host();
98 }
99 
100 void ViewEmail::setSenderHost(const QString &host)
101 {
102  Q_D(ViewEmail);
103  d->sender->setHost(host);
104 }
105 
107 {
108  Q_D(const ViewEmail);
109  return d->sender->port();
110 }
111 
113 {
114  Q_D(ViewEmail);
115  d->sender->setPort(port);
116 }
117 
119 {
120  Q_D(const ViewEmail);
121  return static_cast<ViewEmail::ConnectionType>(d->sender->connectionType());
122 }
123 
125 {
126  Q_D(ViewEmail);
127  d->sender->setConnectionType(static_cast<Sender::ConnectionType>(ct));
128 }
129 
131 {
132  Q_D(const ViewEmail);
133  return static_cast<ViewEmail::AuthMethod>(d->sender->authMethod());
134 }
135 
137 {
138  Q_D(ViewEmail);
139  d->sender->setAuthMethod(static_cast<Sender::AuthMethod>(method));
140 }
141 
142 QString ViewEmail::senderUser() const
143 {
144  Q_D(const ViewEmail);
145  return d->sender->user();
146 }
147 
148 void ViewEmail::setSenderUser(const QString &user)
149 {
150  Q_D(ViewEmail);
151  d->sender->setUser(user);
152 }
153 
155 {
156  Q_D(const ViewEmail);
157  return d->sender->password();
158 }
159 
160 void ViewEmail::setSenderPassword(const QString &password)
161 {
162  Q_D(ViewEmail);
163  d->sender->setPassword(password);
164 }
165 
166 QByteArray ViewEmail::render(Context *c) const
167 {
168  Q_D(const ViewEmail);
169  QByteArray ret;
170  QVariantHash email = c->stash(d->stashKey).toHash();
171  if (email.isEmpty()) {
172  c->error(QStringLiteral("Cannot render template, template name or template stash key not defined"));
173  return ret;
174  }
175 
176  MimeMessage message;
177 
178  QVariant value;
179  value = email.value(QStringLiteral("to"));
180  if (value.type() == QVariant::String && !value.toString().isEmpty()) {
181  message.addTo(value.toString());
182  }
183 
184  value = email.value(QStringLiteral("cc"));
185  if (value.type() == QVariant::String && !value.toString().isEmpty()) {
186  message.addCc(value.toString());
187  }
188 
189  value = email.value(QStringLiteral("from"));
190  if (value.type() == QVariant::String && !value.toString().isEmpty()) {
191  message.setSender(value.toString());
192  }
193 
194  value = email.value(QStringLiteral("subject"));
195  if (value.type() == QVariant::String && !value.toString().isEmpty()) {
196  message.setSubject(value.toString());
197  }
198 
199  QVariant body = email.value(QStringLiteral("body"));
200  QVariant parts = email.value(QStringLiteral("parts"));
201  if (body.isNull() && parts.isNull()) {
202  c->error(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  MimePart *mime = part.value<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()
219  && !contentTypeIt.value().isNull()
220  && !contentTypeIt.value().toString().isEmpty()) {
221  const QByteArray contentType = contentTypeIt.value().toString().toLatin1();
222  qCDebug(CUTELYST_VIEW_EMAIL) << "Using specified content_type" << contentType;
223  message.getContent().setContentType(contentType);
224  } else if (!d->defaultContentType.isEmpty()) {
225  qCDebug(CUTELYST_VIEW_EMAIL) << "Using default content_type" << d->defaultContentType;
226  message.getContent().setContentType(d->defaultContentType);
227  }
228  } else {
229  MimeText *part = new MimeText(body.toString());
230  d->setupAttributes(part, email);
231  message.setContent(part);
232  }
233 
234  if (!d->sender->sendMail(message)) {
235  c->error(QString::fromLatin1(d->sender->responseText()));
236  return ret;
237  }
238 
239  return ret;
240 }
241 
242 ViewEmail::ViewEmail(ViewEmailPrivate *d, QObject *parent, const QString &name) : View(parent, name)
243 {
244  d_ptr = d;
245 
246  initSender();
247 }
248 
249 void ViewEmail::initSender()
250 {
251  Q_D(ViewEmail);
252  d->sender = new Sender(this);
253 
254  QVariantHash config;
255  const auto app = qobject_cast<Application *>(parent());
256  if (app) {
257  config = app->config(QStringLiteral("VIEW_EMAIL")).toHash();
258  }
259 
260  d->stashKey = config.value(QStringLiteral("stash_key"), QStringLiteral("email")).toString();
261 
262  if (!config.value(QStringLiteral("sender_host")).isNull()) {
263  d->sender->setHost(config.value(QStringLiteral("sender_host")).toString());
264  }
265  if (!config.value(QStringLiteral("sender_port")).isNull()) {
266  d->sender->setPort(config.value(QStringLiteral("sender_port")).toInt());
267  }
268  if (!config.value(QStringLiteral("sender_username")).isNull()) {
269  d->sender->setUser(config.value(QStringLiteral("sender_username")).toString());
270  }
271  if (!config.value(QStringLiteral("sender_password")).isNull()) {
272  d->sender->setPassword(config.value(QStringLiteral("sender_password")).toString());
273  }
274 }
275 
276 
277 void ViewEmailPrivate::setupAttributes(MimePart *part, const QVariantHash &attrs) const
278 {
279  auto contentTypeIt = attrs.constFind(QStringLiteral("content_type"));
280  if (contentTypeIt != attrs.constEnd()
281  && !contentTypeIt.value().isNull()
282  && !contentTypeIt.value().toString().isEmpty()) {
283  const QByteArray contentType = contentTypeIt.value().toString().toLatin1();
284  qCDebug(CUTELYST_VIEW_EMAIL) << "Using specified content_type" << contentType;
285  part->setContentType(contentType);
286  } else if (!defaultContentType.isEmpty()) {
287  qCDebug(CUTELYST_VIEW_EMAIL) << "Using default content_type" << defaultContentType;
288  part->setContentType(defaultContentType);
289  }
290 
291  auto charsetIt = attrs.constFind(QStringLiteral("charset"));
292  if (charsetIt != attrs.constEnd()
293  && !charsetIt.value().isNull()
294  && !charsetIt.value().toString().isEmpty()) {
295  const QByteArray charset = charsetIt.value().toString().toLatin1();
296  qCDebug(CUTELYST_VIEW_EMAIL) << "Using specified charset" << charset;
297  part->setCharset(charset);
298  } else if (!defaultCharset.isEmpty()) {
299  qCDebug(CUTELYST_VIEW_EMAIL) << "Using default charset" << defaultCharset;
300  part->setCharset(defaultCharset);
301  }
302 
303  auto encodingIt = attrs.constFind(QStringLiteral("encoding"));
304  if (encodingIt != attrs.constEnd()
305  && !encodingIt.value().isNull()
306  && !encodingIt.value().toString().isEmpty()) {
307  const QByteArray encoding = encodingIt.value().toString().toLatin1();
308  qCDebug(CUTELYST_VIEW_EMAIL) << "Using specified encoding" << encoding;
309  setupEncoding(part, encoding);
310  } else if (!defaultEncoding.isEmpty()) {
311  qCDebug(CUTELYST_VIEW_EMAIL) << "Using default charset" << defaultEncoding;
312  setupEncoding(part, defaultEncoding);
313  }
314 }
315 
316 void ViewEmailPrivate::setupEncoding(MimePart *part, const QByteArray &encoding) const
317 {
318  if (encoding == "7bit") {
319  part->setEncoding(MimePart::_7Bit);
320  } else if (encoding == "8bit") {
321  part->setEncoding(MimePart::_8Bit);
322  } else if (encoding == "base64") {
323  part->setEncoding(MimePart::Base64);
324  } else if (encoding == "quoted-printable") {
325  part->setEncoding(MimePart::QuotedPrintable);
326  } else {
327  qCCritical(CUTELYST_VIEW_EMAIL) << "Unknown encoding" << encoding;
328  }
329 }
330 
331 #include "moc_viewemail.cpp"
void setDefaultEncoding(const QByteArray &encoding)
Definition: viewemail.cpp:88
void setSenderUser(const QString &user)
Definition: viewemail.cpp:148
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:160
void setSenderHost(const QString &host)
Definition: viewemail.cpp:100
bool error() const
Returns true if an error was set.
Definition: context.cpp:64
AuthMethod senderAuthMethod() const
Definition: viewemail.cpp:130
QString senderHost() const
Definition: viewemail.cpp:94
The Cutelyst Context.
Definition: context.h:50
QByteArray render(Context *c) const override
Definition: viewemail.cpp:166
The Cutelyst namespace holds all public Cutelyst API.
Definition: Mainpage.dox:7
QVariant config(const QString &key, const QVariant &defaultValue=QVariant()) const
QByteArray defaultCharset() const
QByteArray defaultContentType() const
void setSenderPort(int port)
Definition: viewemail.cpp:112
ConnectionType senderConnectionType() const
Definition: viewemail.cpp:118
QByteArray defaultEncoding() const
void setDefaultCharset(const QByteArray &charset)
Definition: viewemail.cpp:76
int senderPort() const
Definition: viewemail.cpp:106
void setSenderAuthMethod(AuthMethod method)
Definition: viewemail.cpp:136
Cutelyst View abstract view component
Definition: view.h:33
QString senderUser() const
Definition: viewemail.cpp:142
The Cutelyst Application.
Definition: application.h:54
QString stashKey() const
QString senderPassword() const
Definition: viewemail.cpp:154
void setStashKey(const QString &stashKey)
Definition: viewemail.cpp:52
QString name() const
Definition: view.cpp:40
void setDefaultContentType(const QByteArray &contentType)
Definition: viewemail.cpp:64
void setSenderConnectionType(ConnectionType ct)
Definition: viewemail.cpp:124
void stash(const QVariantHash &unite)
Definition: context.h:499