aboutsummaryrefslogtreecommitdiff
path: root/src/client/QXmppPubSubManager.h
diff options
context:
space:
mode:
authorLinus Jahn <lnj@kaidan.im>2020-07-05 01:32:09 +0200
committerLinus Jahn <lnj@kaidan.im>2021-08-22 16:09:02 +0200
commit6172dad1d7cc2b5816540503644da7704188f92a (patch)
tree8512a79c6a373ee228483111f02f22dc2a3fcaa7 /src/client/QXmppPubSubManager.h
parentbcc19801f86a155177791d36cce20d9227d17dd4 (diff)
downloadqxmpp-6172dad1d7cc2b5816540503644da7704188f92a.tar.gz
Add QXmppPubSubManager
Supports the most common pubsub requests. Co-authored-by: Germán Márquez Mejía <mancho@olomono.de>
Diffstat (limited to 'src/client/QXmppPubSubManager.h')
-rw-r--r--src/client/QXmppPubSubManager.h342
1 files changed, 342 insertions, 0 deletions
diff --git a/src/client/QXmppPubSubManager.h b/src/client/QXmppPubSubManager.h
new file mode 100644
index 00000000..81112353
--- /dev/null
+++ b/src/client/QXmppPubSubManager.h
@@ -0,0 +1,342 @@
+/*
+ * Copyright (C) 2008-2020 The QXmpp developers
+ *
+ * Author:
+ * Linus Jahn
+ *
+ * Source:
+ * https://github.com/qxmpp-project/qxmpp
+ *
+ * This file is a part of QXmpp library.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ */
+
+#ifndef QXMPPPUBSUBMANAGER_H
+#define QXMPPPUBSUBMANAGER_H
+
+#include "QXmppClient.h"
+#include "QXmppClientExtension.h"
+#include "QXmppFutureUtils_p.h"
+#include "QXmppMessage.h"
+#include "QXmppPubSubIq.h"
+#include "QXmppPubSubPublishOptions.h"
+#include "QXmppResultSet.h"
+
+#include <QFuture>
+#include <QFutureWatcher>
+
+class QXmppPubSubPublishOptions;
+class QXmppPubSubSubscribeOptions;
+
+class QXMPP_EXPORT QXmppPubSubManager : public QXmppClientExtension
+{
+ Q_OBJECT
+
+public:
+ template<typename T>
+ struct Items
+ {
+ QVector<T> items;
+ std::optional<QXmppResultSetReply> continuation;
+ };
+
+ using Result = std::variant<QXmpp::Success, QXmppStanza::Error>;
+ using NodesResult = std::variant<QVector<QString>, QXmppStanza::Error>;
+ using InstantNodeResult = std::variant<QString, QXmppStanza::Error>;
+ template<typename T>
+ using ItemResult = std::variant<T, QXmppStanza::Error>;
+ template<typename T>
+ using ItemsResult = std::variant<Items<T>, QXmppStanza::Error>;
+ using PublishItemResult = std::variant<QString, QXmppStanza::Error>;
+ using PublishItemsResult = std::variant<QVector<QString>, QXmppStanza::Error>;
+ using SubscriptionsResult = std::variant<QVector<QXmppPubSubSubscription>, QXmppStanza::Error>;
+ using AffiliationsResult = std::variant<QVector<QXmppPubSubAffiliation>, QXmppStanza::Error>;
+ using OptionsResult = std::variant<QXmppPubSubSubscribeOptions, QXmppStanza::Error>;
+
+ QXmppPubSubManager();
+ ~QXmppPubSubManager();
+
+ // Generic PubSub (the PubSub service is the given entity)
+ QFuture<NodesResult> fetchNodes(const QString &jid);
+ QFuture<Result> createNode(const QString &jid, const QString &nodeName);
+ QFuture<InstantNodeResult> createInstantNode(const QString &jid);
+ QFuture<Result> deleteNode(const QString &jid, const QString &nodeName);
+ template<typename T = QXmppPubSubItem>
+ QFuture<ItemResult<T>> requestItem(const QString &jid, const QString &nodeName, const QString &itemId);
+ template<typename T = QXmppPubSubItem>
+ QFuture<ItemsResult<T>> requestItems(const QString &jid, const QString &nodeName);
+ template<typename T = QXmppPubSubItem>
+ QFuture<ItemsResult<T>> requestItems(const QString &jid, const QString &nodeName, const QStringList &itemIds);
+ template<typename T>
+ QFuture<PublishItemResult> publishItem(const QString &jid, const QString &nodeName, const T &item);
+ template<typename T>
+ QFuture<PublishItemResult> publishItem(const QString &jid, const QString &nodeName, const T &item, const QXmppPubSubPublishOptions &publishOptions);
+ template<typename T>
+ QFuture<PublishItemsResult> publishItems(const QString &jid, const QString &nodeName, const QVector<T> &items);
+ template<typename T>
+ QFuture<PublishItemsResult> publishItems(const QString &jid, const QString &nodeName, const QVector<T> &items, const QXmppPubSubPublishOptions &publishOptions);
+ QFuture<Result> retractItem(const QString &jid, const QString &nodeName, const QString &itemId);
+ QFuture<Result> purgeItems(const QString &jid, const QString &nodeName);
+ QFuture<SubscriptionsResult> requestSubscriptions(const QString &jid);
+ QFuture<SubscriptionsResult> requestSubscriptions(const QString &jid, const QString &nodeName);
+ QFuture<AffiliationsResult> requestNodeAffiliations(const QString &jid, const QString &nodeName);
+ QFuture<AffiliationsResult> requestAffiliations(const QString &jid);
+ QFuture<AffiliationsResult> requestAffiliations(const QString &jid, const QString &nodeName);
+ QFuture<OptionsResult> requestSubscribeOptions(const QString &service, const QString &nodeName);
+ QFuture<OptionsResult> requestSubscribeOptions(const QString &service, const QString &nodeName, const QString &subscriberJid);
+ QFuture<Result> setSubscribeOptions(const QString &service, const QString &nodeName, const QXmppPubSubSubscribeOptions &options);
+ QFuture<Result> setSubscribeOptions(const QString &service, const QString &nodeName, const QXmppPubSubSubscribeOptions &options, const QString &subscriberJid);
+
+ // PEP-specific (the PubSub service is the current account)
+ QFuture<Result> createPepNode(const QString &nodeName);
+ QFuture<Result> deletePepNode(const QString &nodeName);
+ template<typename T>
+ QFuture<PublishItemResult> publishPepItem(const QString &nodeName, const T &item, const QXmppPubSubPublishOptions &publishOptions);
+ template<typename T>
+ QFuture<PublishItemResult> publishPepItem(const QString &nodeName, const T &item);
+ template<typename T>
+ QFuture<PublishItemsResult> publishPepItems(const QString &nodeName, const QVector<T> &items, const QXmppPubSubPublishOptions &publishOptions);
+ template<typename T>
+ QFuture<PublishItemsResult> publishPepItems(const QString &nodeName, const QVector<T> &items);
+ QFuture<Result> retractPepItem(const QString &nodeName, const QString &itemId);
+ QFuture<Result> purgePepItems(const QString &nodeName);
+
+ /// \cond
+ QStringList discoveryFeatures() const override;
+ bool handleStanza(const QDomElement &element) override;
+ /// \endcond
+
+private:
+ /// \cond
+ QFuture<PublishItemResult> publishItem(QXmppPubSubIqBase &&iq);
+ QFuture<PublishItemsResult> publishItems(QXmppPubSubIqBase &&iq);
+ static QXmppPubSubIq<> requestItemsIq(const QString &jid, const QString &nodeName, const QStringList &itemIds);
+ /// \endcond
+
+ // We may need a d-ptr in the future.
+ void *d = nullptr;
+};
+
+///
+/// Requests a specific item of an entity's node.
+///
+/// \param jid Jabber ID of the entity hosting the pubsub service. For PEP this
+/// should be an account's bare JID
+/// \param nodeName the name of the node to query
+/// \param itemId the ID of the item to retrieve
+/// \return
+///
+template<typename T>
+QFuture<QXmppPubSubManager::ItemResult<T>> QXmppPubSubManager::requestItem(const QString &jid,
+ const QString &nodeName,
+ const QString &itemId)
+{
+ using namespace QXmpp::Private;
+ using Error = QXmppStanza::Error;
+ return chainIq(client()->sendIq(requestItemsIq(jid, nodeName, { itemId })), this,
+ [](QXmppPubSubIq<T> &&iq) -> ItemResult<T> {
+ if (!iq.items().isEmpty()) {
+ return iq.items().constFirst();
+ }
+ return Error(Error::Cancel, Error::ItemNotFound, QStringLiteral("No such item has been found."));
+ });
+}
+
+///
+/// Requests all items of an entity's node.
+///
+/// \param jid Jabber ID of the entity hosting the pubsub service. For PEP this
+/// should be an account's bare JID
+/// \param nodeName the name of the node to query
+/// \return
+///
+template<typename T>
+QFuture<QXmppPubSubManager::ItemsResult<T>> QXmppPubSubManager::requestItems(const QString &jid,
+ const QString &nodeName)
+{
+ return requestItems<T>(jid, nodeName, {});
+}
+
+///
+/// Requests items of an entity's node.
+///
+/// \param jid Jabber ID of the entity hosting the pubsub service. For PEP this
+/// should be an account's bare JID
+/// \param nodeName the name of the node to query
+/// \param itemIds the IDs of the items to retrieve. If empty, retrieves all
+/// items
+/// \return
+///
+template<typename T>
+QFuture<QXmppPubSubManager::ItemsResult<T>> QXmppPubSubManager::requestItems(const QString &jid,
+ const QString &nodeName,
+ const QStringList &itemIds)
+{
+ using namespace QXmpp::Private;
+ return chainIq(client()->sendIq(requestItemsIq(jid, nodeName, itemIds)), this,
+ [](QXmppPubSubIq<T> &&iq) -> ItemsResult<T> {
+ return Items<T> {
+ iq.items(),
+ iq.itemsContinuation(),
+ };
+ });
+}
+
+///
+/// Publishs one item to a pubsub node.
+///
+/// This is a convenience method equivalent to calling
+/// QXmppPubSubManager::publishItem with no publish options.
+///
+/// \param jid Jabber ID of the entity hosting the pubsub service
+/// \param nodeName the name of the node to publish the item to
+/// \param item the item to publish
+/// \return
+///
+template<typename T>
+QFuture<QXmppPubSubManager::PublishItemResult> QXmppPubSubManager::publishItem(const QString &jid,
+ const QString &nodeName,
+ const T &item)
+{
+ QXmppPubSubIq<T> request;
+ request.setTo(jid);
+ request.setItems({item});
+ request.setQueryNode(nodeName);
+ return publishItem(std::move(request));
+}
+
+///
+/// Publishs one item to a pubsub node.
+///
+/// This is a convenience method equivalent to calling
+/// QXmppPubSubManager::publishItem with no publish options.
+///
+/// \param jid Jabber ID of the entity hosting the pubsub service
+/// \param nodeName the name of the node to publish the item to
+/// \param item the item to publish
+/// \param publishOptions publish-options for the items
+/// \return
+///
+template<typename T>
+QFuture<QXmppPubSubManager::PublishItemResult> QXmppPubSubManager::publishItem(const QString &jid,
+ const QString &nodeName,
+ const T &item,
+ const QXmppPubSubPublishOptions &publishOptions)
+{
+ QXmppPubSubIq<T> request;
+ request.setTo(jid);
+ request.setItems({item});
+ request.setQueryNode(nodeName);
+ request.setDataForm(publishOptions.toDataForm());
+ return publishItem(std::move(request));
+}
+
+///
+/// Publishs items to a pubsub node.
+///
+/// \param jid Jabber ID of the entity hosting the pubsub service
+/// \param nodeName the name of the node to publish the items to
+/// \param items the items to publish
+/// \return
+///
+template<typename T>
+QFuture<QXmppPubSubManager::PublishItemsResult> QXmppPubSubManager::publishItems(const QString &jid,
+ const QString &nodeName,
+ const QVector<T> &items)
+{
+ QXmppPubSubIq<T> request;
+ request.setTo(jid);
+ request.setItems(items);
+ request.setQueryNode(nodeName);
+ return publishItems(std::move(request));
+}
+
+///
+/// Publishs items to a pubsub node.
+///
+/// \param jid Jabber ID of the entity hosting the pubsub service
+/// \param nodeName the name of the node to publish the items to
+/// \param items the items to publish
+/// \param publishOptions publish-options for the items
+/// \return
+///
+template<typename T>
+QFuture<QXmppPubSubManager::PublishItemsResult> QXmppPubSubManager::publishItems(const QString &jid,
+ const QString &nodeName,
+ const QVector<T> &items,
+ const QXmppPubSubPublishOptions &publishOptions)
+{
+ QXmppPubSubIq<T> request;
+ request.setTo(jid);
+ request.setItems(items);
+ request.setQueryNode(nodeName);
+ request.setDataForm(publishOptions.toDataForm());
+ return publishItems(std::move(request));
+}
+
+///
+/// Publishs one item to a PEP node.
+///
+/// \param nodeName the name of the PEP node to publish the item to
+/// \param item the item to publish
+/// \param publishOptions publish-options for fine tuning
+/// \return
+///
+template<typename T>
+QFuture<QXmppPubSubManager::PublishItemResult> QXmppPubSubManager::publishPepItem(const QString &nodeName, const T &item, const QXmppPubSubPublishOptions &publishOptions)
+{
+ return publishItem(client()->configuration().jidBare(), nodeName, item, publishOptions);
+}
+
+///
+/// Publishs one item to a PEP node.
+///
+/// \param nodeName the name of the PEP node to publish the item to
+/// \param item the item to publish
+/// \return
+///
+template<typename T>
+QFuture<QXmppPubSubManager::PublishItemResult> QXmppPubSubManager::publishPepItem(const QString &nodeName, const T &item)
+{
+ return publishItem(client()->configuration().jidBare(), nodeName, item);
+}
+
+///
+/// Publishs items to a PEP node.
+///
+/// \param nodeName the name of the PEP node to publish the items to
+/// \param items the items to publish
+/// \param publishOptions publish-options for fine tuning (optional). Pass
+/// an empty form to honor the default options of the PEP node
+/// \return
+///
+template<typename T>
+QFuture<QXmppPubSubManager::PublishItemsResult> QXmppPubSubManager::publishPepItems(const QString &nodeName, const QVector<T> &items, const QXmppPubSubPublishOptions &publishOptions)
+{
+ return publishItems(client()->configuration().jidBare(), nodeName, items, publishOptions);
+}
+
+///
+/// Publishs items to a PEP node.
+///
+/// \param nodeName the name of the PEP node to publish the items to
+/// \param items the items to publish
+/// \return
+///
+template<typename T>
+QFuture<QXmppPubSubManager::PublishItemsResult> QXmppPubSubManager::publishPepItems(const QString &nodeName, const QVector<T> &items)
+{
+ return publishItems(client()->configuration().jidBare(), nodeName, items);
+}
+
+#endif // QXMPPPUBSUBMANAGER_H