QXmpp  Version: 1.15.1
QXmppPubSubManager.h
1 // SPDX-FileCopyrightText: 2020 Linus Jahn <lnj@kaidan.im>
2 // SPDX-FileCopyrightText: 2022 Melvin Keskin <melvo@olomono.de>
3 //
4 // SPDX-License-Identifier: LGPL-2.1-or-later
5 
6 #ifndef QXMPPPUBSUBMANAGER_H
7 #define QXMPPPUBSUBMANAGER_H
8 
9 #include "QXmppAsync_p.h"
10 #include "QXmppClient.h"
11 #include "QXmppClientExtension.h"
12 #include "QXmppMessage.h"
13 #include "QXmppPubSubIq_p.h"
14 #include "QXmppPubSubPublishOptions.h"
15 #include "QXmppResultSet.h"
16 
17 class QXmppPubSubPublishOptions;
18 class QXmppPubSubSubscribeOptions;
19 
20 class QXMPP_EXPORT QXmppPubSubManager : public QXmppClientExtension
21 {
22  Q_OBJECT
23 
24 public:
28  enum ServiceType {
31  Pep
32  };
33 
38  Current
39  };
40 
44  struct InvalidServiceType { };
45 
46  template<typename T>
47  struct Items {
48  QVector<T> items;
49  std::optional<QXmppResultSetReply> continuation;
50  };
51 
52  using Result = std::variant<QXmpp::Success, QXmppError>;
53  using FeaturesResult = std::variant<QVector<QString>, InvalidServiceType, QXmppError>;
54  using NodesResult = std::variant<QVector<QString>, QXmppError>;
55  using InstantNodeResult = std::variant<QString, QXmppError>;
56  template<typename T>
57  using ItemResult = std::variant<T, QXmppError>;
58  template<typename T>
59  using ItemsResult = std::variant<Items<T>, QXmppError>;
60  using ItemIdsResult = std::variant<QVector<QString>, QXmppError>;
61  using PublishItemResult = std::variant<QString, QXmppError>;
62  using PublishItemsResult = std::variant<QVector<QString>, QXmppError>;
63  using SubscriptionsResult = std::variant<QVector<QXmppPubSubSubscription>, QXmppError>;
64  using AffiliationsResult = std::variant<QVector<QXmppPubSubAffiliation>, QXmppError>;
65  using OptionsResult = std::variant<QXmppPubSubSubscribeOptions, QXmppError>;
66  using NodeConfigResult = std::variant<QXmppPubSubNodeConfig, QXmppError>;
67 
70 
71  // Generic PubSub (the PubSub service is the given entity)
72  QXmppTask<NodesResult> requestNodes(const QString &jid);
73  auto createNode(const QString &jid, const QString &nodeName) -> QXmppTask<Result>;
74  auto createNode(const QString &jid, const QString &nodeName, const QXmppPubSubNodeConfig &config) -> QXmppTask<Result>;
75  auto createInstantNode(const QString &jid) -> QXmppTask<InstantNodeResult>;
76  auto createInstantNode(const QString &jid, const QXmppPubSubNodeConfig &config) -> QXmppTask<InstantNodeResult>;
77  auto deleteNode(const QString &jid, const QString &nodeName) -> QXmppTask<Result>;
78  QXmppTask<ItemIdsResult> requestItemIds(const QString &serviceJid, const QString &nodeName);
79  template<typename T = QXmppPubSubBaseItem>
80  QXmppTask<ItemResult<T>> requestItem(const QString &jid, const QString &nodeName, const QString &itemId);
81  template<typename T = QXmppPubSubBaseItem>
82  QXmppTask<ItemResult<T>> requestItem(const QString &jid, const QString &nodeName, StandardItemId itemId);
83  template<typename T = QXmppPubSubBaseItem>
84  QXmppTask<ItemsResult<T>> requestItems(const QString &jid, const QString &nodeName);
85  template<typename T = QXmppPubSubBaseItem>
86  QXmppTask<ItemsResult<T>> requestItems(const QString &jid, const QString &nodeName, const QStringList &itemIds);
87  template<typename T>
88  QXmppTask<PublishItemResult> publishItem(const QString &jid, const QString &nodeName, const T &item);
89  template<typename T>
90  QXmppTask<PublishItemResult> publishItem(const QString &jid, const QString &nodeName, const T &item, const QXmppPubSubPublishOptions &publishOptions);
91  template<typename T>
92  QXmppTask<PublishItemsResult> publishItems(const QString &jid, const QString &nodeName, const QVector<T> &items);
93  template<typename T>
94  QXmppTask<PublishItemsResult> publishItems(const QString &jid, const QString &nodeName, const QVector<T> &items, const QXmppPubSubPublishOptions &publishOptions);
95  auto retractItem(const QString &jid, const QString &nodeName, const QString &itemId, bool notify = false) -> QXmppTask<Result>;
96  auto retractItem(const QString &jid, const QString &nodeName, StandardItemId itemId, bool notify = false) -> QXmppTask<Result>;
97  auto purgeItems(const QString &jid, const QString &nodeName) -> QXmppTask<Result>;
98  QXmppTask<SubscriptionsResult> requestSubscriptions(const QString &jid);
99  QXmppTask<SubscriptionsResult> requestSubscriptions(const QString &jid, const QString &nodeName);
100  QXmppTask<AffiliationsResult> requestNodeAffiliations(const QString &jid, const QString &nodeName);
101  QXmppTask<AffiliationsResult> requestAffiliations(const QString &jid);
102  QXmppTask<AffiliationsResult> requestAffiliations(const QString &jid, const QString &nodeName);
103  QXmppTask<OptionsResult> requestSubscribeOptions(const QString &service, const QString &nodeName);
104  QXmppTask<OptionsResult> requestSubscribeOptions(const QString &service, const QString &nodeName, const QString &subscriberJid);
105  QXmppTask<Result> setSubscribeOptions(const QString &service, const QString &nodeName, const QXmppPubSubSubscribeOptions &options);
106  QXmppTask<Result> setSubscribeOptions(const QString &service, const QString &nodeName, const QXmppPubSubSubscribeOptions &options, const QString &subscriberJid);
107  QXmppTask<NodeConfigResult> requestNodeConfiguration(const QString &service, const QString &nodeName);
108  QXmppTask<Result> configureNode(const QString &service, const QString &nodeName, const QXmppPubSubNodeConfig &config);
109  QXmppTask<Result> cancelNodeConfiguration(const QString &service, const QString &nodeName);
110  QXmppTask<Result> subscribeToNode(const QString &serviceJid, const QString &nodeName, const QString &subscriberJid);
111  QXmppTask<Result> unsubscribeFromNode(const QString &serviceJid, const QString &nodeName, const QString &subscriberJid);
112 
113  // PEP-specific (the PubSub service is the current account)
114  QXmppTask<NodesResult> requestOwnPepNodes() { return requestNodes(client()->configuration().jidBare()); };
115  QXmppTask<Result> createOwnPepNode(const QString &nodeName) { return createNode(client()->configuration().jidBare(), nodeName); }
116  QXmppTask<Result> createOwnPepNode(const QString &nodeName, const QXmppPubSubNodeConfig &config) { return createNode(client()->configuration().jidBare(), nodeName, config); }
117  QXmppTask<Result> deleteOwnPepNode(const QString &nodeName) { return deleteNode(client()->configuration().jidBare(), nodeName); }
118  template<typename T = QXmppPubSubBaseItem>
119  QXmppTask<ItemResult<T>> requestOwnPepItem(const QString &nodeName, const QString &itemId) { return requestItem<T>(client()->configuration().jidBare(), nodeName, itemId); }
120  template<typename T = QXmppPubSubBaseItem>
121  QXmppTask<ItemResult<T>> requestOwnPepItem(const QString &nodeName, StandardItemId itemId) { return requestItem<T>(client()->configuration().jidBare(), nodeName, itemId); }
122  template<typename T = QXmppPubSubBaseItem>
123  QXmppTask<ItemsResult<T>> requestOwnPepItems(const QString &nodeName) { return requestItems(client()->configuration().jidBare(), nodeName); }
124  QXmppTask<ItemIdsResult> requestOwnPepItemIds(const QString &nodeName) { return requestItemIds(client()->configuration().jidBare(), nodeName); }
125  template<typename T>
126  QXmppTask<PublishItemResult> publishOwnPepItem(const QString &nodeName, const T &item, const QXmppPubSubPublishOptions &publishOptions);
127  template<typename T>
128  QXmppTask<PublishItemResult> publishOwnPepItem(const QString &nodeName, const T &item);
129  template<typename T>
130  QXmppTask<PublishItemsResult> publishOwnPepItems(const QString &nodeName, const QVector<T> &items, const QXmppPubSubPublishOptions &publishOptions);
131  template<typename T>
132  QXmppTask<PublishItemsResult> publishOwnPepItems(const QString &nodeName, const QVector<T> &items);
133  QXmppTask<Result> retractOwnPepItem(const QString &nodeName, const QString &itemId, bool notify = false) { return retractItem(client()->configuration().jidBare(), nodeName, itemId, notify); }
134  QXmppTask<Result> retractOwnPepItem(const QString &nodeName, StandardItemId itemId, bool notify = false) { return retractItem(client()->configuration().jidBare(), nodeName, itemId, notify); }
135  QXmppTask<Result> purgeOwnPepItems(const QString &nodeName) { return purgeItems(client()->configuration().jidBare(), nodeName); }
136  QXmppTask<NodeConfigResult> requestOwnPepNodeConfiguration(const QString &nodeName) { return requestNodeConfiguration(client()->configuration().jidBare(), nodeName); }
137  QXmppTask<Result> configureOwnPepNode(const QString &nodeName, const QXmppPubSubNodeConfig &config) { return configureNode(client()->configuration().jidBare(), nodeName, config); }
138  QXmppTask<Result> cancelOwnPepNodeConfiguration(const QString &nodeName) { return cancelNodeConfiguration(client()->configuration().jidBare(), nodeName); }
139 
140  static QString standardItemIdToString(StandardItemId itemId);
141 
143  QStringList discoveryFeatures() const override;
144  bool handleStanza(const QDomElement &element) override;
146 
147 private:
148  // for private requestFeatures() API
149  friend class tst_QXmppPubSubManager;
150  friend class QXmppOmemoManagerPrivate;
151 
152  QXmppTask<FeaturesResult> requestFeatures(const QString &serviceJid, ServiceType serviceType = PubSubOrPep);
153  QXmppTask<FeaturesResult> requestOwnPepFeatures() { return requestFeatures(client()->configuration().jidBare(), Pep); };
154 
155  QXmppTask<PublishItemResult> publishItem(QXmpp::Private::PubSubIqBase &&iq);
156  QXmppTask<PublishItemsResult> publishItems(QXmpp::Private::PubSubIqBase &&iq);
157  static QXmpp::Private::PubSubIq<> requestItemsIq(const QString &jid, const QString &nodeName, const QStringList &itemIds);
158 };
159 
169 template<typename T>
171  const QString &nodeName,
172  const QString &itemId)
173 {
174  using namespace QXmpp::Private;
175  co_return parseIq<PubSubIq<T>>(co_await client()->sendIq(requestItemsIq(jid, nodeName, { itemId })), [](PubSubIq<T> &&iq) -> ItemResult<T> {
176  if (!iq.items().isEmpty()) {
177  return iq.items().constFirst();
178  }
179  return QXmppError { QStringLiteral("No such item has been found."), {} };
180  });
181 }
182 
192 template<typename T>
194  const QString &nodeName,
195  StandardItemId itemId)
196 {
197  return requestItem<T>(jid, nodeName, standardItemIdToString(itemId));
198 }
199 
208 template<typename T>
210  const QString &nodeName)
211 {
212  return requestItems<T>(jid, nodeName, {});
213 }
214 
225 template<typename T>
227  const QString &nodeName,
228  const QStringList &itemIds)
229 {
230  using namespace QXmpp::Private;
231  co_return parseIq<PubSubIq<T>>(
232  co_await client()->sendIq(requestItemsIq(jid, nodeName, itemIds)),
233  [](PubSubIq<T> &&iq) -> ItemsResult<T> {
234  return Items<T> { iq.items(), iq.itemsContinuation() };
235  });
236 }
237 
249 template<typename T>
251  const QString &nodeName,
252  const T &item)
253 {
254  QXmpp::Private::PubSubIq<T> request;
255  request.setTo(jid);
256  request.setItems({ item });
257  request.setQueryNode(nodeName);
258  return publishItem(std::move(request));
259 }
260 
273 template<typename T>
275  const QString &nodeName,
276  const T &item,
277  const QXmppPubSubPublishOptions &publishOptions)
278 {
279  QXmpp::Private::PubSubIq<T> request;
280  request.setTo(jid);
281  request.setItems({ item });
282  request.setQueryNode(nodeName);
283  request.setDataForm(publishOptions.toDataForm());
284  return publishItem(std::move(request));
285 }
286 
295 template<typename T>
297  const QString &nodeName,
298  const QVector<T> &items)
299 {
300  QXmpp::Private::PubSubIq<T> request;
301  request.setTo(jid);
302  request.setItems(items);
303  request.setQueryNode(nodeName);
304  return publishItems(std::move(request));
305 }
306 
316 template<typename T>
318  const QString &nodeName,
319  const QVector<T> &items,
320  const QXmppPubSubPublishOptions &publishOptions)
321 {
322  QXmpp::Private::PubSubIq<T> request;
323  request.setTo(jid);
324  request.setItems(items);
325  request.setQueryNode(nodeName);
326  request.setDataForm(publishOptions.toDataForm());
327  return publishItems(std::move(request));
328 }
329 
338 template<typename T>
339 QXmppTask<QXmppPubSubManager::PublishItemResult> QXmppPubSubManager::publishOwnPepItem(const QString &nodeName, const T &item, const QXmppPubSubPublishOptions &publishOptions)
340 {
341  return publishItem(client()->configuration().jidBare(), nodeName, item, publishOptions);
342 }
343 
351 template<typename T>
353 {
354  return publishItem(client()->configuration().jidBare(), nodeName, item);
355 }
356 
366 template<typename T>
367 QXmppTask<QXmppPubSubManager::PublishItemsResult> QXmppPubSubManager::publishOwnPepItems(const QString &nodeName, const QVector<T> &items, const QXmppPubSubPublishOptions &publishOptions)
368 {
369  return publishItems(client()->configuration().jidBare(), nodeName, items, publishOptions);
370 }
371 
379 template<typename T>
381 {
382  return publishItems(client()->configuration().jidBare(), nodeName, items);
383 }
384 
385 #endif // QXMPPPUBSUBMANAGER_H
QXmppTask< ItemResult< T > > requestOwnPepItem(const QString &nodeName, const QString &itemId)
Definition: QXmppPubSubManager.h:119
QXmppTask< Result > cancelOwnPepNodeConfiguration(const QString &nodeName)
Definition: QXmppPubSubManager.h:138
QXmppTask< IqResult > sendIq(QXmppIq &&, const std::optional< QXmppSendStanzaParams > &={})
Definition: QXmppClient.cpp:584
std::variant< QVector< QXmppPubSubSubscription >, QXmppError > SubscriptionsResult
Definition: QXmppPubSubManager.h:63
virtual bool handleStanza(const QDomElement &stanza)
You need to implement this method to process incoming XMPP stanzas.
Definition: client/compat/removed_api.cpp:45
QXmppTask< NodesResult > requestOwnPepNodes()
Definition: QXmppPubSubManager.h:114
QXmppTask< Result > createOwnPepNode(const QString &nodeName, const QXmppPubSubNodeConfig &config)
Definition: QXmppPubSubManager.h:116
QXmppTask< PublishItemResult > publishOwnPepItem(const QString &nodeName, const T &item, const QXmppPubSubPublishOptions &publishOptions)
Definition: QXmppPubSubManager.h:339
std::variant< QString, QXmppError > PublishItemResult
Definition: QXmppPubSubManager.h:61
Definition: QXmppError.h:17
StandardItemId
Definition: QXmppPubSubManager.h:37
QString jidBare() const
Definition: QXmppConfiguration.cpp:319
std::variant< QVector< QString >, QXmppError > ItemIdsResult
Definition: QXmppPubSubManager.h:60
ServiceType
Definition: QXmppPubSubManager.h:28
QXmppTask< ItemIdsResult > requestOwnPepItemIds(const QString &nodeName)
Definition: QXmppPubSubManager.h:124
QXmppTask< Result > retractOwnPepItem(const QString &nodeName, StandardItemId itemId, bool notify=false)
Definition: QXmppPubSubManager.h:134
Definition: QXmppTask.h:67
PubSub service or PEP service.
Definition: QXmppPubSubManager.h:29
QXmppTask< PublishItemResult > publishItem(const QString &jid, const QString &nodeName, const T &item)
Definition: QXmppPubSubManager.h:250
PubSub service only.
Definition: QXmppPubSubManager.h:30
std::variant< QVector< QString >, QXmppError > PublishItemsResult
Definition: QXmppPubSubManager.h:62
Definition: QXmppPubSubManager.h:44
QXmppTask< Result > retractOwnPepItem(const QString &nodeName, const QString &itemId, bool notify=false)
Definition: QXmppPubSubManager.h:133
QXmppTask< PublishItemsResult > publishOwnPepItems(const QString &nodeName, const QVector< T > &items, const QXmppPubSubPublishOptions &publishOptions)
Definition: QXmppPubSubManager.h:367
std::variant< QVector< QString >, InvalidServiceType, QXmppError > FeaturesResult
Definition: QXmppPubSubManager.h:53
QXmppTask< ItemsResult< T > > requestItems(const QString &jid, const QString &nodeName)
Definition: QXmppPubSubManager.h:209
static QString standardItemIdToString(StandardItemId itemId)
Definition: QXmppPubSubManager.cpp:957
QXmppConfiguration & configuration()
Returns a modifiable reference to the current configuration of QXmppClient.
Definition: QXmppClient.cpp:442
QXmppTask< Result > createOwnPepNode(const QString &nodeName)
Definition: QXmppPubSubManager.h:115
QXmppTask< PublishItemsResult > publishItems(const QString &jid, const QString &nodeName, const QVector< T > &items)
Definition: QXmppPubSubManager.h:296
std::variant< Items< T >, QXmppError > ItemsResult
Definition: QXmppPubSubManager.h:59
std::variant< QXmpp::Success, QXmppError > Result
Definition: QXmppPubSubManager.h:52
std::variant< QVector< QXmppPubSubAffiliation >, QXmppError > AffiliationsResult
Definition: QXmppPubSubManager.h:64
std::variant< QString, QXmppError > InstantNodeResult
Definition: QXmppPubSubManager.h:55
QXmppTask< Result > configureOwnPepNode(const QString &nodeName, const QXmppPubSubNodeConfig &config)
Definition: QXmppPubSubManager.h:137
virtual QStringList discoveryFeatures() const
Definition: QXmppClientExtension.cpp:22
std::variant< QVector< QString >, QXmppError > NodesResult
Definition: QXmppPubSubManager.h:54
std::variant< QXmppPubSubSubscribeOptions, QXmppError > OptionsResult
Definition: QXmppPubSubManager.h:65
Definition: Algorithms.h:14
QXmppClient * client() const
Definition: QXmppClientExtension.cpp:57
QXmppTask< ItemResult< T > > requestOwnPepItem(const QString &nodeName, StandardItemId itemId)
Definition: QXmppPubSubManager.h:121
QXmppTask< Result > deleteOwnPepNode(const QString &nodeName)
Definition: QXmppPubSubManager.h:117
The QXmppPubSubManager aims to provide publish-subscribe functionality as specified in XEP-0060: Publ...
Definition: QXmppPubSubManager.h:20
QXmppTask< Result > purgeOwnPepItems(const QString &nodeName)
Definition: QXmppPubSubManager.h:135
The QXmppClientExtension class is the base class for QXmppClient extensions.
Definition: QXmppClientExtension.h:31
QXmppTask< ItemsResult< T > > requestOwnPepItems(const QString &nodeName)
Definition: QXmppPubSubManager.h:123
QXmppTask< ItemResult< T > > requestItem(const QString &jid, const QString &nodeName, const QString &itemId)
Definition: QXmppPubSubManager.h:170
std::variant< T, QXmppError > ItemResult
Definition: QXmppPubSubManager.h:57
QXmppTask< NodeConfigResult > requestOwnPepNodeConfiguration(const QString &nodeName)
Definition: QXmppPubSubManager.h:136
std::variant< QXmppPubSubNodeConfig, QXmppError > NodeConfigResult
Definition: QXmppPubSubManager.h:66