cutelyst  5.0.1
A C++ Web Framework built on top of Qt, using the simple approach of Catalyst (Perl) framework.
statusmessage.cpp
1 /*
2  * SPDX-FileCopyrightText: (C) 2016-2022 Daniel Nicoletti <dantti12@gmail.com>
3  * SPDX-License-Identifier: BSD-3-Clause
4  */
5 #include "statusmessage.h"
6 
7 #include <Cutelyst/Application>
8 #include <Cutelyst/Plugins/Session/session.h>
9 
10 #include <QRandomGenerator>
11 #include <QtCore/QDateTime>
12 #include <QtCore/QLoggingCategory>
13 
14 using namespace Cutelyst;
15 using namespace Qt::StringLiterals;
16 
17 Q_LOGGING_CATEGORY(C_STATUSMESSAGE, "cutelyst.plugins.statusmessage", QtWarningMsg)
18 
19 namespace {
20 thread_local StatusMessage *m_instance = nullptr;
21 } // namespace
22 
23 namespace Cutelyst {
24 
26 {
27 public:
28  static void _q_postFork(Application *app);
29 
30  QString sessionPrefix = u"status_msg"_s;
31  QString tokenParam = u"mid"_s;
32  QString statusMsgStashKey = u"status_msg"_s;
33  QString errorMsgStashKey = u"error_msg"_s;
34 };
35 
36 void StatusMessagePrivate::_q_postFork(Application *app)
37 {
38  m_instance = app->plugin<StatusMessage *>();
39 }
40 
41 } // namespace Cutelyst
42 
44  : Plugin(parent)
45  , d_ptr(new StatusMessagePrivate)
46 {
47  m_instance = this;
48 }
49 
51 {
52  delete d_ptr;
53 }
54 
56 {
57  Q_D(const StatusMessage);
58  return d->sessionPrefix;
59 }
60 
61 void StatusMessage::setSessionPrefix(const QString &sessionPrefix)
62 {
63  Q_D(StatusMessage);
64  d->sessionPrefix = sessionPrefix;
65 }
66 
68 {
69  Q_D(const StatusMessage);
70  return d->tokenParam;
71 }
72 
73 void StatusMessage::setTokenParam(const QString &tokenParam)
74 {
75  Q_D(StatusMessage);
76  d->tokenParam = tokenParam;
77 }
78 
80 {
81  Q_D(const StatusMessage);
82  return d->statusMsgStashKey;
83 }
84 
85 void StatusMessage::setStatusMsgStashKey(const QString &statusMsgStashKey)
86 {
87  Q_D(StatusMessage);
88  d->statusMsgStashKey = statusMsgStashKey;
89 }
90 
92 {
93  Q_D(const StatusMessage);
94  return d->errorMsgStashKey;
95 }
96 
97 void StatusMessage::setErrorMgStashKey(const QString &errorMgStashKey)
98 {
99  Q_D(StatusMessage);
100  d->errorMsgStashKey = errorMgStashKey;
101 }
102 
104 {
105  if (Q_UNLIKELY(!m_instance)) {
106  qCCritical(C_STATUSMESSAGE, "StatusMessage plugin not registered");
107  return;
108  }
109  StatusMessagePrivate *priv = m_instance->d_ptr;
110 
111  const QString token = c->request()->queryParam(priv->tokenParam);
112  if (token.isEmpty()) {
113  return;
114  }
115 
116  QStringList deleteKeys;
117  const QString statusKey = priv->sessionPrefix + u"status" + token;
118  const QVariant statusValue = Session::value(c, statusKey);
119  if (!statusValue.isNull()) {
120  deleteKeys.append(statusKey);
121  c->setStash(priv->statusMsgStashKey, statusValue);
122  }
123 
124  const QString errorKey = priv->sessionPrefix + u"error" + token;
125  const QVariant errorValue = Session::value(c, errorKey);
126  if (!errorValue.isNull()) {
127  deleteKeys.append(errorKey);
128  c->setStash(priv->errorMsgStashKey, errorValue);
129  }
130 
131  if (!deleteKeys.isEmpty()) {
132  Session::deleteValues(c, deleteKeys);
133  }
134 }
135 
136 inline QString createToken()
137 {
138  return QString::number(QRandomGenerator::global()->generate() % 99999999)
139  .rightJustified(8, u'0', true);
140 }
141 
143 {
144  QString token;
145  if (Q_UNLIKELY(!m_instance)) {
146  qCCritical(C_STATUSMESSAGE, "StatusMessage plugin not registered");
147  return token;
148  }
149 
150  token = createToken();
151  Session::setValue(c, m_instance->d_ptr->sessionPrefix + u"error" + token, msg);
152  return token;
153 }
154 
156 {
157  ParamsMultiMap map(query);
158  if (Q_UNLIKELY(!m_instance)) {
159  qCCritical(C_STATUSMESSAGE, "StatusMessage plugin not registered");
160  return map;
161  }
162  StatusMessagePrivate *priv = m_instance->d_ptr;
163 
164  const QString token = createToken();
165  Session::setValue(c, priv->sessionPrefix + u"error" + token, msg);
166  map.insert(priv->tokenParam, token);
167  return map;
168 }
169 
171 {
172  QString token;
173  if (Q_UNLIKELY(!m_instance)) {
174  qCCritical(C_STATUSMESSAGE, "StatusMessage plugin not registered");
175  return token;
176  }
177 
178  token = createToken();
179  Session::setValue(c, m_instance->d_ptr->sessionPrefix + u"status" + token, msg);
180  return token;
181 }
182 
184 {
185  ParamsMultiMap map(query);
186  if (Q_UNLIKELY(!m_instance)) {
187  qCCritical(C_STATUSMESSAGE, "StatusMessage plugin not registered");
188  return map;
189  }
190  StatusMessagePrivate *priv = m_instance->d_ptr;
191 
192  const QString token = createToken();
193  Session::setValue(c, priv->sessionPrefix + u"status" + token, msg);
194  map.insert(priv->tokenParam, token);
195  return map;
196 }
197 
199 {
200  connect(app, &Application::postForked, this, &StatusMessagePrivate::_q_postFork);
201  return true;
202 }
203 
204 #include "moc_statusmessage.cpp"
void setTokenParam(const QString &tokenParam)
Request request
Definition: context.h:72
static QString status(Context *c, const QString &msg)
void postForked(Cutelyst::Application *app)
static ParamsMultiMap statusQuery(Context *c, const QString &msg, ParamsMultiMap query={})
static ParamsMultiMap errorQuery(Context *c, const QString &msg, ParamsMultiMap query={})
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
virtual ~StatusMessage() override
Manage status messages over multiple requests stored in the Session.
Definition: statusmessage.h:85
void setStash(const QString &key, const QVariant &value)
Definition: context.cpp:213
QString queryParam(const QString &key, const QString &defaultValue={}) const
Definition: request.h:591
QString tokenParam() const noexcept
QString sessionPrefix() const noexcept
static void load(Context *c)
The Cutelyst Context.
Definition: context.h:42
StatusMessage(Application *parent)
QString number(double n, char format, int precision)
bool isNull() const const
QString rightJustified(qsizetype width, QChar fill, bool truncate) const const
bool isEmpty() const const
bool isEmpty() const const
static void setValue(Context *c, const QString &key, const QVariant &value)
Definition: session.cpp:186
iterator insert(const Key &key, const T &value)
The Cutelyst namespace holds all public Cutelyst API.
void setStatusMsgStashKey(const QString &statusMsgStashKey)
QString statusMsgStashKey() const noexcept
virtual bool setup(Application *app) override
QString errorMgStashKey() const noexcept
void append(QList< T > &&value)
static void deleteValues(Context *c, const QStringList &keys)
Definition: session.cpp:234
static QVariant value(Context *c, const QString &key, const QVariant &defaultValue=QVariant())
Definition: session.cpp:171
Base class for Cutelyst Plugins.
Definition: plugin.h:24
The Cutelyst application.
Definition: application.h:72
static QString error(Context *c, const QString &msg)
void setErrorMgStashKey(const QString &errorMgStashKey)
QRandomGenerator * global()
void setSessionPrefix(const QString &sessionPrefix)