QXmpp Version: 1.7.0
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
17class QXmppPubSubPublishOptions;
18class QXmppPubSubSubscribeOptions;
19
20class QXMPP_EXPORT QXmppPubSubManager : public QXmppClientExtension
21{
22 Q_OBJECT
23
24public:
31 Pep
32 };
33
38 Current
39 };
40
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
147private:
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
169template<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
193template<typename T>
195 const QString &nodeName,
196 StandardItemId itemId)
197{
198 return requestItem<T>(jid, nodeName, standardItemIdToString(itemId));
199}
200
209template<typename T>
211 const QString &nodeName)
212{
213 return requestItems<T>(jid, nodeName, {});
214}
215
226template<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
252template<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
276template<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
298template<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
319template<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
341template<typename T>
342QXmppTask<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
354template<typename T>
356{
357 return publishItem(client()->configuration().jidBare(), nodeName, item);
358}
359
369template<typename T>
370QXmppTask<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
382template<typename T>
384{
385 return publishItems(client()->configuration().jidBare(), nodeName, items);
386}
387
388#endif // QXMPPPUBSUBMANAGER_H
The QXmppClientExtension class is the base class for QXmppClient extensions.
Definition: QXmppClientExtension.h:33
QXmppClient * client()
Definition: QXmppClientExtension.cpp:57
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: client/compat/removed_api.cpp:26
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:124
std::variant< QVector< QString >, InvalidServiceType, QXmppError > FeaturesResult
Definition: QXmppPubSubManager.h:53
std::variant< QVector< QXmppPubSubAffiliation >, QXmppError > AffiliationsResult
Definition: QXmppPubSubManager.h:64
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:65
QXmppTask< ItemResult< T > > requestOwnPepItem(const QString &nodeName, StandardItemId itemId)
Definition: QXmppPubSubManager.h:121
QXmppTask< PublishItemResult > publishItem(const QString &jid, const QString &nodeName, const T &item)
Definition: QXmppPubSubManager.h:253
QXmppTask< ItemResult< T > > requestOwnPepItem(const QString &nodeName, const QString &itemId)
Definition: QXmppPubSubManager.h:119
std::variant< QVector< QString >, QXmppError > ItemIdsResult
Definition: QXmppPubSubManager.h:60
QXmppTask< PublishItemResult > publishOwnPepItem(const QString &nodeName, const T &item, const QXmppPubSubPublishOptions &publishOptions)
Definition: QXmppPubSubManager.h:342
QXmppTask< Result > configureOwnPepNode(const QString &nodeName, const QXmppPubSubNodeConfig &config)
Definition: QXmppPubSubManager.h:137
QXmppTask< Result > retractOwnPepItem(const QString &nodeName, const QString &itemId)
Definition: QXmppPubSubManager.h:133
std::variant< QXmppPubSubNodeConfig, QXmppError > NodeConfigResult
Definition: QXmppPubSubManager.h:66
QXmppTask< Result > cancelOwnPepNodeConfiguration(const QString &nodeName)
Definition: QXmppPubSubManager.h:138
std::variant< T, QXmppError > ItemResult
Definition: QXmppPubSubManager.h:57
QXmppTask< NodesResult > requestOwnPepNodes()
Definition: QXmppPubSubManager.h:114
std::variant< QString, QXmppError > PublishItemResult
Definition: QXmppPubSubManager.h:61
std::variant< QString, QXmppError > InstantNodeResult
Definition: QXmppPubSubManager.h:55
std::variant< QVector< QString >, QXmppError > PublishItemsResult
Definition: QXmppPubSubManager.h:62
QXmppTask< Result > purgeOwnPepItems(const QString &nodeName)
Definition: QXmppPubSubManager.h:135
std::variant< QXmpp::Success, QXmppError > Result
Definition: QXmppPubSubManager.h:52
static QString standardItemIdToString(StandardItemId itemId)
Definition: QXmppPubSubManager.cpp:961
std::variant< QVector< QXmppPubSubSubscription >, QXmppError > SubscriptionsResult
Definition: QXmppPubSubManager.h:63
QXmppTask< NodeConfigResult > requestOwnPepNodeConfiguration(const QString &nodeName)
Definition: QXmppPubSubManager.h:136
QXmppTask< Result > createOwnPepNode(const QString &nodeName, const QXmppPubSubNodeConfig &config)
Definition: QXmppPubSubManager.h:116
std::variant< Items< T >, QXmppError > ItemsResult
Definition: QXmppPubSubManager.h:59
QXmppTask< ItemsResult< T > > requestItems(const QString &jid, const QString &nodeName)
Definition: QXmppPubSubManager.h:210
QXmppTask< PublishItemsResult > publishItems(const QString &jid, const QString &nodeName, const QVector< T > &items)
Definition: QXmppPubSubManager.h:299
QXmppTask< ItemResult< T > > requestItem(const QString &jid, const QString &nodeName, const QString &itemId)
Definition: QXmppPubSubManager.h:170
QXmppTask< ItemsResult< T > > requestOwnPepItems(const QString &nodeName)
Definition: QXmppPubSubManager.h:123
QXmppTask< Result > deleteOwnPepNode(const QString &nodeName)
Definition: QXmppPubSubManager.h:117
std::variant< QVector< QString >, QXmppError > NodesResult
Definition: QXmppPubSubManager.h:54
QXmppTask< PublishItemsResult > publishOwnPepItems(const QString &nodeName, const QVector< T > &items, const QXmppPubSubPublishOptions &publishOptions)
Definition: QXmppPubSubManager.h:370
StandardItemId
Definition: QXmppPubSubManager.h:37
QXmppTask< Result > createOwnPepNode(const QString &nodeName)
Definition: QXmppPubSubManager.h:115
QXmppTask< Result > retractOwnPepItem(const QString &nodeName, StandardItemId itemId)
Definition: QXmppPubSubManager.h:134
Definition: QXmppTask.h:62
Definition: QXmppError.h:17
Definition: QXmppPubSubManager.h:44