/* * 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 #include class QXmppPubSubPublishOptions; class QXmppPubSubSubscribeOptions; class QXMPP_EXPORT QXmppPubSubManager : public QXmppClientExtension { Q_OBJECT public: template struct Items { QVector items; std::optional continuation; }; using Result = std::variant; using NodesResult = std::variant, QXmppStanza::Error>; using InstantNodeResult = std::variant; template using ItemResult = std::variant; template using ItemsResult = std::variant, QXmppStanza::Error>; using PublishItemResult = std::variant; using PublishItemsResult = std::variant, QXmppStanza::Error>; using SubscriptionsResult = std::variant, QXmppStanza::Error>; using AffiliationsResult = std::variant, QXmppStanza::Error>; using OptionsResult = std::variant; QXmppPubSubManager(); ~QXmppPubSubManager(); // Generic PubSub (the PubSub service is the given entity) QFuture fetchNodes(const QString &jid); QFuture createNode(const QString &jid, const QString &nodeName); QFuture createInstantNode(const QString &jid); QFuture deleteNode(const QString &jid, const QString &nodeName); template QFuture> requestItem(const QString &jid, const QString &nodeName, const QString &itemId); template QFuture> requestItems(const QString &jid, const QString &nodeName); template QFuture> requestItems(const QString &jid, const QString &nodeName, const QStringList &itemIds); template QFuture publishItem(const QString &jid, const QString &nodeName, const T &item); template QFuture publishItem(const QString &jid, const QString &nodeName, const T &item, const QXmppPubSubPublishOptions &publishOptions); template QFuture publishItems(const QString &jid, const QString &nodeName, const QVector &items); template QFuture publishItems(const QString &jid, const QString &nodeName, const QVector &items, const QXmppPubSubPublishOptions &publishOptions); QFuture retractItem(const QString &jid, const QString &nodeName, const QString &itemId); QFuture purgeItems(const QString &jid, const QString &nodeName); QFuture requestSubscriptions(const QString &jid); QFuture requestSubscriptions(const QString &jid, const QString &nodeName); QFuture requestNodeAffiliations(const QString &jid, const QString &nodeName); QFuture requestAffiliations(const QString &jid); QFuture requestAffiliations(const QString &jid, const QString &nodeName); QFuture requestSubscribeOptions(const QString &service, const QString &nodeName); QFuture requestSubscribeOptions(const QString &service, const QString &nodeName, const QString &subscriberJid); QFuture setSubscribeOptions(const QString &service, const QString &nodeName, const QXmppPubSubSubscribeOptions &options); QFuture setSubscribeOptions(const QString &service, const QString &nodeName, const QXmppPubSubSubscribeOptions &options, const QString &subscriberJid); // PEP-specific (the PubSub service is the current account) QFuture createPepNode(const QString &nodeName); QFuture deletePepNode(const QString &nodeName); template QFuture publishPepItem(const QString &nodeName, const T &item, const QXmppPubSubPublishOptions &publishOptions); template QFuture publishPepItem(const QString &nodeName, const T &item); template QFuture publishPepItems(const QString &nodeName, const QVector &items, const QXmppPubSubPublishOptions &publishOptions); template QFuture publishPepItems(const QString &nodeName, const QVector &items); QFuture retractPepItem(const QString &nodeName, const QString &itemId); QFuture purgePepItems(const QString &nodeName); /// \cond QStringList discoveryFeatures() const override; bool handleStanza(const QDomElement &element) override; /// \endcond private: /// \cond QFuture publishItem(QXmppPubSubIqBase &&iq); QFuture 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 QFuture> 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 &&iq) -> ItemResult { 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 QFuture> QXmppPubSubManager::requestItems(const QString &jid, const QString &nodeName) { return requestItems(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 QFuture> 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 &&iq) -> ItemsResult { return Items { 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 QFuture QXmppPubSubManager::publishItem(const QString &jid, const QString &nodeName, const T &item) { QXmppPubSubIq 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 QFuture QXmppPubSubManager::publishItem(const QString &jid, const QString &nodeName, const T &item, const QXmppPubSubPublishOptions &publishOptions) { QXmppPubSubIq 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 QFuture QXmppPubSubManager::publishItems(const QString &jid, const QString &nodeName, const QVector &items) { QXmppPubSubIq 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 QFuture QXmppPubSubManager::publishItems(const QString &jid, const QString &nodeName, const QVector &items, const QXmppPubSubPublishOptions &publishOptions) { QXmppPubSubIq 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 QFuture 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 QFuture 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 QFuture QXmppPubSubManager::publishPepItems(const QString &nodeName, const QVector &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 QFuture QXmppPubSubManager::publishPepItems(const QString &nodeName, const QVector &items) { return publishItems(client()->configuration().jidBare(), nodeName, items); } #endif // QXMPPPUBSUBMANAGER_H