QXmpp  Version: 1.10.4
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 
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  QXmppTask<Result> createNode(const QString &jid, const QString &nodeName);
74  QXmppTask<Result> createNode(const QString &jid, const QString &nodeName, const QXmppPubSubNodeConfig &config);
75  QXmppTask<InstantNodeResult> createInstantNode(const QString &jid);
76  QXmppTask<InstantNodeResult> createInstantNode(const QString &jid, const QXmppPubSubNodeConfig &config);
77  QXmppTask<Result> deleteNode(const QString &jid, const QString &nodeName);
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  QXmppTask<Result> retractItem(const QString &jid, const QString &nodeName, const QString &itemId);
96  QXmppTask<Result> retractItem(const QString &jid, const QString &nodeName, StandardItemId itemId);
97  QXmppTask<Result> purgeItems(const QString &jid, const QString &nodeName);
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) { return retractItem(client()->configuration().jidBare(), nodeName, itemId); }
134  QXmppTask<Result> retractOwnPepItem(const QString &nodeName, StandardItemId itemId) { return retractItem(client()->configuration().jidBare(), nodeName, itemId); }
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  return chainIq(client()->sendIq(requestItemsIq(jid, nodeName, { itemId })), this,
176  [](PubSubIq<T> &&iq) -> ItemResult<T> {
177  if (!iq.items().isEmpty()) {
178  return iq.items().constFirst();
179  }
180  return QXmppError { QStringLiteral("No such item has been found."), {} };
181  });
182 }
183 
193 template<typename T>
195  const QString &nodeName,
196  StandardItemId itemId)
197 {
198  return requestItem<T>(jid, nodeName, standardItemIdToString(itemId));
199 }
200 
209 template<typename T>
211  const QString &nodeName)
212 {
213  return requestItems<T>(jid, nodeName, {});
214 }
215 
226 template<typename T>
228  const QString &nodeName,
229  const QStringList &itemIds)
230 {
231  using namespace QXmpp::Private;
232  return chainIq(client()->sendIq(requestItemsIq(jid, nodeName, itemIds)), this,
233  [](PubSubIq<T> &&iq) -> ItemsResult<T> {
234  return Items<T> {
235  iq.items(),
236  iq.itemsContinuation(),
237  };
238  });
239 }
240 
252 template<typename T>
254  const QString &nodeName,
255  const T &item)
256 {
257  QXmpp::Private::PubSubIq<T> request;
258  request.setTo(jid);
259  request.setItems({ item });
260  request.setQueryNode(nodeName);
261  return publishItem(std::move(request));
262 }
263 
276 template<typename T>
278  const QString &nodeName,
279  const T &item,
280  const QXmppPubSubPublishOptions &publishOptions)
281 {
282  QXmpp::Private::PubSubIq<T> request;
283  request.setTo(jid);
284  request.setItems({ item });
285  request.setQueryNode(nodeName);
286  request.setDataForm(publishOptions.toDataForm());
287  return publishItem(std::move(request));
288 }
289 
298 template<typename T>
300  const QString &nodeName,
301  const QVector<T> &items)
302 {
303  QXmpp::Private::PubSubIq<T> request;
304  request.setTo(jid);
305  request.setItems(items);
306  request.setQueryNode(nodeName);
307  return publishItems(std::move(request));
308 }
309 
319 template<typename T>
321  const QString &nodeName,
322  const QVector<T> &items,
323  const QXmppPubSubPublishOptions &publishOptions)
324 {
325  QXmpp::Private::PubSubIq<T> request;
326  request.setTo(jid);
327  request.setItems(items);
328  request.setQueryNode(nodeName);
329  request.setDataForm(publishOptions.toDataForm());
330  return publishItems(std::move(request));
331 }
332 
341 template<typename T>
342 QXmppTask<QXmppPubSubManager::PublishItemResult> QXmppPubSubManager::publishOwnPepItem(const QString &nodeName, const T &item, const QXmppPubSubPublishOptions &publishOptions)
343 {
344  return publishItem(client()->configuration().jidBare(), nodeName, item, publishOptions);
345 }
346 
354 template<typename T>
356 {
357  return publishItem(client()->configuration().jidBare(), nodeName, item);
358 }
359 
369 template<typename T>
370 QXmppTask<QXmppPubSubManager::PublishItemsResult> QXmppPubSubManager::publishOwnPepItems(const QString &nodeName, const QVector<T> &items, const QXmppPubSubPublishOptions &publishOptions)
371 {
372  return publishItems(client()->configuration().jidBare(), nodeName, items, publishOptions);
373 }
374 
382 template<typename T>
384 {
385  return publishItems(client()->configuration().jidBare(), nodeName, items);
386 }
387 
388 #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
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:26
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:342
std::variant< QString, QXmppError > PublishItemResult
Definition: QXmppPubSubManager.h:61
Definition: QXmppError.h:17
StandardItemId
Definition: QXmppPubSubManager.h:37
QString jidBare() const
Definition: QXmppConfiguration.cpp:318
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
Definition: QXmppTask.h:61
PubSub service or PEP service.
Definition: QXmppPubSubManager.h:29
QXmppTask< PublishItemResult > publishItem(const QString &jid, const QString &nodeName, const T &item)
Definition: QXmppPubSubManager.h:253
PubSub service only.
Definition: QXmppPubSubManager.h:30
std::variant< QVector< QString >, QXmppError > PublishItemsResult
Definition: QXmppPubSubManager.h:62
Definition: QXmppPubSubManager.h:44
QXmppTask< PublishItemsResult > publishOwnPepItems(const QString &nodeName, const QVector< T > &items, const QXmppPubSubPublishOptions &publishOptions)
Definition: QXmppPubSubManager.h:370
std::variant< QVector< QString >, InvalidServiceType, QXmppError > FeaturesResult
Definition: QXmppPubSubManager.h:53
QXmppTask< ItemsResult< T > > requestItems(const QString &jid, const QString &nodeName)
Definition: QXmppPubSubManager.h:210
static QString standardItemIdToString(StandardItemId itemId)
Definition: QXmppPubSubManager.cpp:962
QXmppConfiguration & configuration()
Returns a modifiable reference to the current configuration of QXmppClient.
Definition: QXmppClient.cpp:439
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:299
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:12
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< Result > retractOwnPepItem(const QString &nodeName, StandardItemId itemId)
Definition: QXmppPubSubManager.h:134
QXmppTask< ItemsResult< T > > requestOwnPepItems(const QString &nodeName)
Definition: QXmppPubSubManager.h:123
QXmppTask< Result > retractOwnPepItem(const QString &nodeName, const QString &itemId)
Definition: QXmppPubSubManager.h:133
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