diff options
| author | Linus Jahn <lnj@kaidan.im> | 2020-07-05 01:32:09 +0200 |
|---|---|---|
| committer | Linus Jahn <lnj@kaidan.im> | 2021-08-22 16:09:02 +0200 |
| commit | 6172dad1d7cc2b5816540503644da7704188f92a (patch) | |
| tree | 8512a79c6a373ee228483111f02f22dc2a3fcaa7 /src/client/QXmppPubSubManager.h | |
| parent | bcc19801f86a155177791d36cce20d9227d17dd4 (diff) | |
| download | qxmpp-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.h | 342 |
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 |
