QXmpp  Version: 1.5.5
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 "QXmppClient.h"
10 #include "QXmppClientExtension.h"
11 #include "QXmppFutureUtils_p.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 
45  {
46  };
47 
48  template<typename T>
49  struct Items
50  {
51  QVector<T> items;
52  std::optional<QXmppResultSetReply> continuation;
53  };
54 
55  using Result = std::variant<QXmpp::Success, QXmppError>;
56  using FeaturesResult = std::variant<QVector<QString>, InvalidServiceType, QXmppError>;
57  using NodesResult = std::variant<QVector<QString>, QXmppError>;
58  using InstantNodeResult = std::variant<QString, QXmppError>;
59  template<typename T>
60  using ItemResult = std::variant<T, QXmppError>;
61  template<typename T>
62  using ItemsResult = std::variant<Items<T>, QXmppError>;
63  using ItemIdsResult = std::variant<QVector<QString>, QXmppError>;
64  using PublishItemResult = std::variant<QString, QXmppError>;
65  using PublishItemsResult = std::variant<QVector<QString>, QXmppError>;
66  using SubscriptionsResult = std::variant<QVector<QXmppPubSubSubscription>, QXmppError>;
67  using AffiliationsResult = std::variant<QVector<QXmppPubSubAffiliation>, QXmppError>;
68  using OptionsResult = std::variant<QXmppPubSubSubscribeOptions, QXmppError>;
69  using NodeConfigResult = std::variant<QXmppPubSubNodeConfig, QXmppError>;
70 
73 
74  // Generic PubSub (the PubSub service is the given entity)
75  QXmppTask<NodesResult> requestNodes(const QString &jid);
76  QXmppTask<Result> createNode(const QString &jid, const QString &nodeName);
77  QXmppTask<Result> createNode(const QString &jid, const QString &nodeName, const QXmppPubSubNodeConfig &config);
78  QXmppTask<InstantNodeResult> createInstantNode(const QString &jid);
79  QXmppTask<InstantNodeResult> createInstantNode(const QString &jid, const QXmppPubSubNodeConfig &config);
80  QXmppTask<Result> deleteNode(const QString &jid, const QString &nodeName);
81  QXmppTask<ItemIdsResult> requestItemIds(const QString &serviceJid, const QString &nodeName);
82  template<typename T = QXmppPubSubBaseItem>
83  QXmppTask<ItemResult<T>> requestItem(const QString &jid, const QString &nodeName, const QString &itemId);
84  template<typename T = QXmppPubSubBaseItem>
85  QXmppTask<ItemResult<T>> requestItem(const QString &jid, const QString &nodeName, StandardItemId itemId);
86  template<typename T = QXmppPubSubBaseItem>
87  QXmppTask<ItemsResult<T>> requestItems(const QString &jid, const QString &nodeName);
88  template<typename T = QXmppPubSubBaseItem>
89  QXmppTask<ItemsResult<T>> requestItems(const QString &jid, const QString &nodeName, const QStringList &itemIds);
90  template<typename T>
91  QXmppTask<PublishItemResult> publishItem(const QString &jid, const QString &nodeName, const T &item);
92  template<typename T>
93  QXmppTask<PublishItemResult> publishItem(const QString &jid, const QString &nodeName, const T &item, const QXmppPubSubPublishOptions &publishOptions);
94  template<typename T>
95  QXmppTask<PublishItemsResult> publishItems(const QString &jid, const QString &nodeName, const QVector<T> &items);
96  template<typename T>
97  QXmppTask<PublishItemsResult> publishItems(const QString &jid, const QString &nodeName, const QVector<T> &items, const QXmppPubSubPublishOptions &publishOptions);
98  QXmppTask<Result> retractItem(const QString &jid, const QString &nodeName, const QString &itemId);
99  QXmppTask<Result> retractItem(const QString &jid, const QString &nodeName, StandardItemId itemId);
100  QXmppTask<Result> purgeItems(const QString &jid, const QString &nodeName);
101  QXmppTask<SubscriptionsResult> requestSubscriptions(const QString &jid);
102  QXmppTask<SubscriptionsResult> requestSubscriptions(const QString &jid, const QString &nodeName);
103  QXmppTask<AffiliationsResult> requestNodeAffiliations(const QString &jid, const QString &nodeName);
104  QXmppTask<AffiliationsResult> requestAffiliations(const QString &jid);
105  QXmppTask<AffiliationsResult> requestAffiliations(const QString &jid, const QString &nodeName);
106  QXmppTask<OptionsResult> requestSubscribeOptions(const QString &service, const QString &nodeName);
107  QXmppTask<OptionsResult> requestSubscribeOptions(const QString &service, const QString &nodeName, const QString &subscriberJid);
108  QXmppTask<Result> setSubscribeOptions(const QString &service, const QString &nodeName, const QXmppPubSubSubscribeOptions &options);
109  QXmppTask<Result> setSubscribeOptions(const QString &service, const QString &nodeName, const QXmppPubSubSubscribeOptions &options, const QString &subscriberJid);
110  QXmppTask<NodeConfigResult> requestNodeConfiguration(const QString &service, const QString &nodeName);
111  QXmppTask<Result> configureNode(const QString &service, const QString &nodeName, const QXmppPubSubNodeConfig &config);
112  QXmppTask<Result> cancelNodeConfiguration(const QString &service, const QString &nodeName);
113  QXmppTask<Result> subscribeToNode(const QString &serviceJid, const QString &nodeName, const QString &subscriberJid);
114  QXmppTask<Result> unsubscribeFromNode(const QString &serviceJid, const QString &nodeName, const QString &subscriberJid);
115 
116  // PEP-specific (the PubSub service is the current account)
117  QXmppTask<NodesResult> requestOwnPepNodes() { return requestNodes(client()->configuration().jidBare()); };
118  QXmppTask<Result> createOwnPepNode(const QString &nodeName) { return createNode(client()->configuration().jidBare(), nodeName); }
119  QXmppTask<Result> createOwnPepNode(const QString &nodeName, const QXmppPubSubNodeConfig &config) { return createNode(client()->configuration().jidBare(), nodeName, config); }
120  QXmppTask<Result> deleteOwnPepNode(const QString &nodeName) { return deleteNode(client()->configuration().jidBare(), nodeName); }
121  template<typename T = QXmppPubSubBaseItem>
122  QXmppTask<ItemResult<T>> requestOwnPepItem(const QString &nodeName, const QString &itemId) { return requestItem<T>(client()->configuration().jidBare(), nodeName, itemId); }
123  template<typename T = QXmppPubSubBaseItem>
124  QXmppTask<ItemResult<T>> requestOwnPepItem(const QString &nodeName, StandardItemId itemId) { return requestItem<T>(client()->configuration().jidBare(), nodeName, itemId); }
125  template<typename T = QXmppPubSubBaseItem>
126  QXmppTask<ItemsResult<T>> requestOwnPepItems(const QString &nodeName) { return requestItems(client()->configuration().jidBare(), nodeName); }
127  QXmppTask<ItemIdsResult> requestOwnPepItemIds(const QString &nodeName) { return requestItemIds(client()->configuration().jidBare(), nodeName); }
128  template<typename T>
129  QXmppTask<PublishItemResult> publishOwnPepItem(const QString &nodeName, const T &item, const QXmppPubSubPublishOptions &publishOptions);
130  template<typename T>
131  QXmppTask<PublishItemResult> publishOwnPepItem(const QString &nodeName, const T &item);
132  template<typename T>
133  QXmppTask<PublishItemsResult> publishOwnPepItems(const QString &nodeName, const QVector<T> &items, const QXmppPubSubPublishOptions &publishOptions);
134  template<typename T>
135  QXmppTask<PublishItemsResult> publishOwnPepItems(const QString &nodeName, const QVector<T> &items);
136  QXmppTask<Result> retractOwnPepItem(const QString &nodeName, const QString &itemId) { return retractItem(client()->configuration().jidBare(), nodeName, itemId); }
137  QXmppTask<Result> retractOwnPepItem(const QString &nodeName, StandardItemId itemId) { return retractItem(client()->configuration().jidBare(), nodeName, itemId); }
138  QXmppTask<Result> purgeOwnPepItems(const QString &nodeName) { return purgeItems(client()->configuration().jidBare(), nodeName); }
139  QXmppTask<NodeConfigResult> requestOwnPepNodeConfiguration(const QString &nodeName) { return requestNodeConfiguration(client()->configuration().jidBare(), nodeName); }
140  QXmppTask<Result> configureOwnPepNode(const QString &nodeName, const QXmppPubSubNodeConfig &config) { return configureNode(client()->configuration().jidBare(), nodeName, config); }
141  QXmppTask<Result> cancelOwnPepNodeConfiguration(const QString &nodeName) { return cancelNodeConfiguration(client()->configuration().jidBare(), nodeName); }
142 
143  static QString standardItemIdToString(StandardItemId itemId);
144 
146  QStringList discoveryFeatures() const override;
147  bool handleStanza(const QDomElement &element) override;
149 
150 private:
151  // for private requestFeatures() API
152  friend class tst_QXmppPubSubManager;
153  friend class QXmppOmemoManagerPrivate;
154 
155  QXmppTask<FeaturesResult> requestFeatures(const QString &serviceJid, ServiceType serviceType = PubSubOrPep);
156  QXmppTask<FeaturesResult> requestOwnPepFeatures() { return requestFeatures(client()->configuration().jidBare(), Pep); };
157 
158  QXmppTask<PublishItemResult> publishItem(QXmpp::Private::PubSubIqBase &&iq);
159  QXmppTask<PublishItemsResult> publishItems(QXmpp::Private::PubSubIqBase &&iq);
160  static QXmpp::Private::PubSubIq<> requestItemsIq(const QString &jid, const QString &nodeName, const QStringList &itemIds);
161 };
162 
172 template<typename T>
174  const QString &nodeName,
175  const QString &itemId)
176 {
177  using namespace QXmpp::Private;
178  return chainIq(client()->sendIq(requestItemsIq(jid, nodeName, { itemId })), this,
179  [](PubSubIq<T> &&iq) -> ItemResult<T> {
180  if (!iq.items().isEmpty()) {
181  return iq.items().constFirst();
182  }
183  return QXmppError { QStringLiteral("No such item has been found."), {} };
184  });
185 }
186 
196 template<typename T>
198  const QString &nodeName,
199  StandardItemId itemId)
200 {
201  return requestItem<T>(jid, nodeName, standardItemIdToString(itemId));
202 }
203 
212 template<typename T>
214  const QString &nodeName)
215 {
216  return requestItems<T>(jid, nodeName, {});
217 }
218 
229 template<typename T>
231  const QString &nodeName,
232  const QStringList &itemIds)
233 {
234  using namespace QXmpp::Private;
235  return chainIq(client()->sendIq(requestItemsIq(jid, nodeName, itemIds)), this,
236  [](PubSubIq<T> &&iq) -> ItemsResult<T> {
237  return Items<T> {
238  iq.items(),
239  iq.itemsContinuation(),
240  };
241  });
242 }
243 
255 template<typename T>
257  const QString &nodeName,
258  const T &item)
259 {
260  QXmpp::Private::PubSubIq<T> request;
261  request.setTo(jid);
262  request.setItems({ item });
263  request.setQueryNode(nodeName);
264  return publishItem(std::move(request));
265 }
266 
279 template<typename T>
281  const QString &nodeName,
282  const T &item,
283  const QXmppPubSubPublishOptions &publishOptions)
284 {
285  QXmpp::Private::PubSubIq<T> request;
286  request.setTo(jid);
287  request.setItems({ item });
288  request.setQueryNode(nodeName);
289  request.setDataForm(publishOptions.toDataForm());
290  return publishItem(std::move(request));
291 }
292 
301 template<typename T>
303  const QString &nodeName,
304  const QVector<T> &items)
305 {
306  QXmpp::Private::PubSubIq<T> request;
307  request.setTo(jid);
308  request.setItems(items);
309  request.setQueryNode(nodeName);
310  return publishItems(std::move(request));
311 }
312 
322 template<typename T>
324  const QString &nodeName,
325  const QVector<T> &items,
326  const QXmppPubSubPublishOptions &publishOptions)
327 {
328  QXmpp::Private::PubSubIq<T> request;
329  request.setTo(jid);
330  request.setItems(items);
331  request.setQueryNode(nodeName);
332  request.setDataForm(publishOptions.toDataForm());
333  return publishItems(std::move(request));
334 }
335 
344 template<typename T>
345 QXmppTask<QXmppPubSubManager::PublishItemResult> QXmppPubSubManager::publishOwnPepItem(const QString &nodeName, const T &item, const QXmppPubSubPublishOptions &publishOptions)
346 {
347  return publishItem(client()->configuration().jidBare(), nodeName, item, publishOptions);
348 }
349 
357 template<typename T>
359 {
360  return publishItem(client()->configuration().jidBare(), nodeName, item);
361 }
362 
372 template<typename T>
373 QXmppTask<QXmppPubSubManager::PublishItemsResult> QXmppPubSubManager::publishOwnPepItems(const QString &nodeName, const QVector<T> &items, const QXmppPubSubPublishOptions &publishOptions)
374 {
375  return publishItems(client()->configuration().jidBare(), nodeName, items, publishOptions);
376 }
377 
385 template<typename T>
387 {
388  return publishItems(client()->configuration().jidBare(), nodeName, items);
389 }
390 
391 #endif // QXMPPPUBSUBMANAGER_H
The QXmppClientExtension class is the base class for QXmppClient extensions.
Definition: QXmppClientExtension.h:33
QXmppClient * client()
Definition: QXmppClientExtension.cpp:78
virtual QStringList discoveryFeatures() const
Definition: QXmppClientExtension.cpp:22
virtual bool handleStanza(const QDomElement &stanza)
You need to implement this method to process incoming XMPP stanzas.
Definition: QXmppClientExtension.cpp:51
The QXmppPubSubManager aims to provide publish-subscribe functionality as specified in XEP-0060: Publ...
Definition: QXmppPubSubManager.h:21
QXmppTask< ItemIdsResult > requestOwnPepItemIds(const QString &nodeName)
Definition: QXmppPubSubManager.h:127
std::variant< QVector< QString >, InvalidServiceType, QXmppError > FeaturesResult
Definition: QXmppPubSubManager.h:56
std::variant< QVector< QXmppPubSubAffiliation >, QXmppError > AffiliationsResult
Definition: QXmppPubSubManager.h:67
ServiceType
Definition: QXmppPubSubManager.h:28
@ PubSubOrPep
PubSub service or PEP service.
Definition: QXmppPubSubManager.h:29
@ PubSub
PubSub service only.
Definition: QXmppPubSubManager.h:30
std::variant< QXmppPubSubSubscribeOptions, QXmppError > OptionsResult
Definition: QXmppPubSubManager.h:68
QXmppTask< ItemResult< T > > requestOwnPepItem(const QString &nodeName, StandardItemId itemId)
Definition: QXmppPubSubManager.h:124
QXmppTask< PublishItemResult > publishItem(const QString &jid, const QString &nodeName, const T &item)
Definition: QXmppPubSubManager.h:256
QXmppTask< ItemResult< T > > requestOwnPepItem(const QString &nodeName, const QString &itemId)
Definition: QXmppPubSubManager.h:122
std::variant< QVector< QString >, QXmppError > ItemIdsResult
Definition: QXmppPubSubManager.h:63
QXmppTask< PublishItemResult > publishOwnPepItem(const QString &nodeName, const T &item, const QXmppPubSubPublishOptions &publishOptions)
Definition: QXmppPubSubManager.h:345
QXmppTask< Result > configureOwnPepNode(const QString &nodeName, const QXmppPubSubNodeConfig &config)
Definition: QXmppPubSubManager.h:140
QXmppTask< Result > retractOwnPepItem(const QString &nodeName, const QString &itemId)
Definition: QXmppPubSubManager.h:136
std::variant< QXmppPubSubNodeConfig, QXmppError > NodeConfigResult
Definition: QXmppPubSubManager.h:69
QXmppTask< Result > cancelOwnPepNodeConfiguration(const QString &nodeName)
Definition: QXmppPubSubManager.h:141
std::variant< T, QXmppError > ItemResult
Definition: QXmppPubSubManager.h:60
QXmppTask< NodesResult > requestOwnPepNodes()
Definition: QXmppPubSubManager.h:117
std::variant< QString, QXmppError > PublishItemResult
Definition: QXmppPubSubManager.h:64
std::variant< QString, QXmppError > InstantNodeResult
Definition: QXmppPubSubManager.h:58
std::variant< QVector< QString >, QXmppError > PublishItemsResult
Definition: QXmppPubSubManager.h:65
QXmppTask< Result > purgeOwnPepItems(const QString &nodeName)
Definition: QXmppPubSubManager.h:138
std::variant< QXmpp::Success, QXmppError > Result
Definition: QXmppPubSubManager.h:55
static QString standardItemIdToString(StandardItemId itemId)
Definition: QXmppPubSubManager.cpp:958
std::variant< QVector< QXmppPubSubSubscription >, QXmppError > SubscriptionsResult
Definition: QXmppPubSubManager.h:66
QXmppTask< NodeConfigResult > requestOwnPepNodeConfiguration(const QString &nodeName)
Definition: QXmppPubSubManager.h:139
QXmppTask< Result > createOwnPepNode(const QString &nodeName, const QXmppPubSubNodeConfig &config)
Definition: QXmppPubSubManager.h:119
std::variant< Items< T >, QXmppError > ItemsResult
Definition: QXmppPubSubManager.h:62
QXmppTask< ItemsResult< T > > requestItems(const QString &jid, const QString &nodeName)
Definition: QXmppPubSubManager.h:213
QXmppTask< PublishItemsResult > publishItems(const QString &jid, const QString &nodeName, const QVector< T > &items)
Definition: QXmppPubSubManager.h:302
QXmppTask< ItemResult< T > > requestItem(const QString &jid, const QString &nodeName, const QString &itemId)
Definition: QXmppPubSubManager.h:173
QXmppTask< ItemsResult< T > > requestOwnPepItems(const QString &nodeName)
Definition: QXmppPubSubManager.h:126
QXmppTask< Result > deleteOwnPepNode(const QString &nodeName)
Definition: QXmppPubSubManager.h:120
std::variant< QVector< QString >, QXmppError > NodesResult
Definition: QXmppPubSubManager.h:57
QXmppTask< PublishItemsResult > publishOwnPepItems(const QString &nodeName, const QVector< T > &items, const QXmppPubSubPublishOptions &publishOptions)
Definition: QXmppPubSubManager.h:373
StandardItemId
Definition: QXmppPubSubManager.h:37
QXmppTask< Result > createOwnPepNode(const QString &nodeName)
Definition: QXmppPubSubManager.h:118
QXmppTask< Result > retractOwnPepItem(const QString &nodeName, StandardItemId itemId)
Definition: QXmppPubSubManager.h:137
Definition: QXmppTask.h:62
Definition: QXmppError.h:18
Definition: QXmppPubSubManager.h:45