Cutelyst  3.1.0
statusmessage.cpp
1 /*
2  * Copyright (C) 2016-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 "statusmessage.h"
19 
20 #include <Cutelyst/Application>
21 #include <Cutelyst/Plugins/Session/session.h>
22 
23 #include <QtCore/QDateTime>
24 #include <QtCore/QLoggingCategory>
25 
26 #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
27 #include <QRandomGenerator>
28 #endif
29 
30 using namespace Cutelyst;
31 
32 Q_LOGGING_CATEGORY(C_STATUSMESSAGE, "cutelyst.plugins.statusmessage", QtWarningMsg)
33 
34 static thread_local StatusMessage *m_instance = nullptr;
35 
36 namespace Cutelyst {
37 
39 {
40 public:
41  static void _q_postFork(Application *app);
42 
43  QString sessionPrefix = QStringLiteral("status_msg");
44  QString tokenParam = QStringLiteral("mid");
45  QString statusMsgStashKey = QStringLiteral("status_msg");
46  QString errorMsgStashKey = QStringLiteral("error_msg");
47 };
48 
49 void StatusMessagePrivate::_q_postFork(Application *app)
50 {
51  m_instance = app->plugin<StatusMessage *>();
52 }
53 
54 }
55 
56 StatusMessage::StatusMessage(Application *parent) : Plugin(parent), d_ptr(new StatusMessagePrivate)
57 {
58 #if (QT_VERSION < QT_VERSION_CHECK(5, 10, 0))
60 #endif
61  m_instance = this;
62 }
63 
64 StatusMessage::~StatusMessage()
65 {
66  delete d_ptr;
67 }
68 
70 {
71  Q_D(const StatusMessage);
72  return d->sessionPrefix;
73 }
74 
75 void StatusMessage::setSessionPrefix(const QString &sessionPrefix)
76 {
77  Q_D(StatusMessage);
78  d->sessionPrefix = sessionPrefix;
79 }
80 
82 {
83  Q_D(const StatusMessage);
84  return d->tokenParam;
85 }
86 
87 void StatusMessage::setTokenParam(const QString &tokenParam)
88 {
89  Q_D(StatusMessage);
90  d->tokenParam = tokenParam;
91 }
92 
94 {
95  Q_D(const StatusMessage);
96  return d->statusMsgStashKey;
97 }
98 
99 void StatusMessage::setStatusMsgStashKey(const QString &statusMsgStashKey)
100 {
101  Q_D(StatusMessage);
102  d->statusMsgStashKey = statusMsgStashKey;
103 }
104 
106 {
107  Q_D(const StatusMessage);
108  return d->errorMsgStashKey;
109 }
110 
111 void StatusMessage::setErrorMgStashKey(const QString &errorMgStashKey)
112 {
113  Q_D(StatusMessage);
114  d->errorMsgStashKey = errorMgStashKey;
115 }
116 
118 {
119  if (Q_UNLIKELY(!m_instance)) {
120  qCCritical(C_STATUSMESSAGE, "StatusMessage plugin not registered");
121  return;
122  }
123  StatusMessagePrivate *priv = m_instance->d_ptr;
124 
125  const QString token = c->request()->queryParam(priv->tokenParam);
126  if (token.isEmpty()) {
127  return;
128  }
129 
130  QStringList deleteKeys;
131  const QString statusKey = priv->sessionPrefix + QLatin1String("status") + token;
132  const QVariant statusValue = Session::value(c, statusKey);
133  if (!statusValue.isNull()) {
134  deleteKeys.append(statusKey);
135  c->setStash(priv->statusMsgStashKey, statusValue);
136  }
137 
138  const QString errorKey = priv->sessionPrefix + QLatin1String("error") + token;
139  const QVariant errorValue = Session::value(c, errorKey);
140  if (!errorValue.isNull()) {
141  deleteKeys.append(errorKey);
142  c->setStash(priv->errorMsgStashKey, errorValue);
143  }
144 
145  if (!deleteKeys.isEmpty()) {
146  Session::deleteValues(c, deleteKeys);
147  }
148 }
149 
150 inline QString createToken()
151 {
152 #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
153  return QString::number(QRandomGenerator::global()->generate() % 99999999).rightJustified(8, QLatin1Char('0'), true);
154 #else
155  return QString::number(qrand() % 99999999).rightJustified(8, QLatin1Char('0'), true);
156 #endif
157 }
158 
160 {
161  QString token;
162  if (Q_UNLIKELY(!m_instance)) {
163  qCCritical(C_STATUSMESSAGE, "StatusMessage plugin not registered");
164  return token;
165  }
166 
167  token = createToken();
168  Session::setValue(c, m_instance->d_ptr->sessionPrefix + QLatin1String("error") + token, msg);
169  return token;
170 }
171 
173 {
174  ParamsMultiMap map(query);
175  if (Q_UNLIKELY(!m_instance)) {
176  qCCritical(C_STATUSMESSAGE, "StatusMessage plugin not registered");
177  return map;
178  }
179  StatusMessagePrivate *priv = m_instance->d_ptr;
180 
181  const QString token = createToken();
182  Session::setValue(c, priv->sessionPrefix + QLatin1String("error") + token, msg);
183  map.insert(priv->tokenParam, token);
184  return map;
185 }
186 
188 {
189  QString token;
190  if (Q_UNLIKELY(!m_instance)) {
191  qCCritical(C_STATUSMESSAGE, "StatusMessage plugin not registered");
192  return token;
193  }
194 
195  token = createToken();
196  Session::setValue(c, m_instance->d_ptr->sessionPrefix + QLatin1String("status") + token, msg);
197  return token;
198 }
199 
201 {
202  ParamsMultiMap map(query);
203  if (Q_UNLIKELY(!m_instance)) {
204  qCCritical(C_STATUSMESSAGE, "StatusMessage plugin not registered");
205  return map;
206  }
207  StatusMessagePrivate *priv = m_instance->d_ptr;
208 
209  const QString token = createToken();
210  Session::setValue(c, priv->sessionPrefix + QLatin1String("status") + token, msg);
211  map.insert(priv->tokenParam, token);
212  return map;
213 }
214 
216 {
217  connect(app, &Application::postForked, this, &StatusMessagePrivate::_q_postFork);
218  return true;
219 }
220 
221 #include "moc_statusmessage.cpp"
The Cutelyst Application.
Definition: application.h:56
T plugin()
Returns the registered plugin that casts to the template type T.
Definition: application.h:115
void postForked(Cutelyst::Application *app)
The Cutelyst Context.
Definition: context.h:52
void setStash(const QString &key, const QVariant &value)
Definition: context.cpp:225
QString queryParam(const QString &key, const QString &defaultValue={}) const
Definition: request.h:555
static QVariant value(Context *c, const QString &key, const QVariant &defaultValue=QVariant())
Definition: session.cpp:165
static void setValue(Context *c, const QString &key, const QVariant &value)
Definition: session.cpp:180
static void deleteValues(Context *c, const QStringList &keys)
Definition: session.cpp:226
static ParamsMultiMap errorQuery(Context *c, const QString &msg, ParamsMultiMap query=ParamsMultiMap())
static QString error(Context *c, const QString &msg)
QString tokenParam() const
static void load(Context *c)
QString sessionPrefix() const
QString errorMgStashKey() const
void setTokenParam(const QString &tokenParam)
virtual bool setup(Application *app) override
static QString status(Context *c, const QString &msg)
void setErrorMgStashKey(const QString &errorMgStashKey)
QString statusMsgStashKey() const
void setStatusMsgStashKey(const QString &statusMsgStashKey)
void setSessionPrefix(const QString &sessionPrefix)
static ParamsMultiMap statusQuery(Context *c, const QString &msg, ParamsMultiMap query=ParamsMultiMap())
The Cutelyst namespace holds all public Cutelyst API.
Definition: Mainpage.dox:8
qint64 currentMSecsSinceEpoch()
void append(const T &value)
bool isEmpty() const const
typename QMap< Key, T >::iterator insert(const Key &key, const T &value)
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QRandomGenerator * global()
bool isEmpty() const const
QString number(int n, int base)
QString rightJustified(int width, QChar fill, bool truncate) const const
bool isNull() const const