# HG changeset patch # User Goffi # Date 1702314627 -3600 # Node ID 5d056d524298f61d9358276c3895f2d80fb19169 # Parent 92551baea1158f1539fb7d123eb9feec94f47513 core, doc, cli (forums): new `forums set` commands + doc: - document the fact that if an empty `uri` is used, the forum node is created automatically - new `forums/set` CLI commands and its documentation diff -r 92551baea115 -r 5d056d524298 doc/libervia-cli/forums.rst --- a/doc/libervia-cli/forums.rst Mon Dec 11 18:07:58 2023 +0100 +++ b/doc/libervia-cli/forums.rst Mon Dec 11 18:10:27 2023 +0100 @@ -28,6 +28,22 @@ $ li forums get -k fr -O json +set +=== + +Set forums from JSON, the JSON must be given as input. + +Check :ref:`libervia-cli_blog_edit` for the data format. + +example +------- + +Set the forums structure from a ``forums.json`` file:: + + $ li forums set < forums.json + + +.. _libervia-cli_forums_edit: edit ==== @@ -51,6 +67,8 @@ ``uri`` URI to the PubSub node containing the messages of the topic (it's actually a blog node with suitable permissions). URI must only be set for topic, not for categories. + If ``uri`` is empty, a node will be created automatically and the ``uri`` will be filled + accordingly. ``sub-forums`` list of object with the same metadata (i.e. other topics or categories) diff -r 92551baea115 -r 5d056d524298 libervia/backend/plugins/plugin_misc_forums.py --- a/libervia/backend/plugins/plugin_misc_forums.py Mon Dec 11 18:07:58 2023 +0100 +++ b/libervia/backend/plugins/plugin_misc_forums.py Mon Dec 11 18:10:27 2023 +0100 @@ -17,6 +17,8 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +from typing import Iterable +from libervia.backend.core.core_types import SatXMPPEntity from libervia.backend.core.i18n import _ from libervia.backend.core.constants import Const as C from libervia.backend.core import exceptions @@ -80,8 +82,15 @@ method=self._create_topic, async_=True) - @defer.inlineCallbacks - def _create_forums(self, client, forums, service, node, forums_elt=None, names=None): + async def _create_forums( + self, + client: SatXMPPEntity, + forums: list[dict], + service: jid.JID, + node: str, + forums_elt: domish.Element|None = None, + names: Iterable = None + ) -> domish.Element: """Recursively create element(s) @param forums(list): forums which may have subforums @@ -111,10 +120,10 @@ for key, value in forum.items(): if key == 'name' and key in names: raise exceptions.ConflictError(_("following forum name is not unique: {name}").format(name=key)) - if key == 'uri' and not value.strip(): + if key == 'uri' and value is None or not value.strip(): log.info(_("creating missing forum node")) forum_node = FORUM_TOPICS_NODE_TPL.format(node=node, uuid=shortuuid.uuid()) - yield self._p.createNode(client, service, forum_node, self._node_options) + await self._p.createNode(client, service, forum_node, self._node_options) value = uri.build_xmpp_uri('pubsub', path=service.full(), node=forum_node) @@ -123,8 +132,9 @@ elif key in FORUM_SUB_ELTS: forum_elt.addElement(key, content=value) elif key == 'sub-forums': + assert isinstance(value, list) sub_forums_elt = forum_elt.addElement('forums') - yield self._create_forums(client, value, service, node, sub_forums_elt, names=names) + await self._create_forums(client, value, service, node, sub_forums_elt, names=names) else: log.warning(_("Unknown forum attribute: {key}").format(key=key)) if not forum_elt.getAttribute('title'): @@ -135,7 +145,7 @@ raise ValueError(_("forum need a title or a name")) if not forum_elt.getAttribute('uri') and not forum_elt.children: raise ValueError(_("forum need uri or sub-forums")) - defer.returnValue(forums_elt) + return forums_elt def _parse_forums(self, parent_elt=None, forums=None): """Recursivly parse a elements and return corresponding forums data diff -r 92551baea115 -r 5d056d524298 libervia/cli/cmd_forums.py --- a/libervia/cli/cmd_forums.py Mon Dec 11 18:07:58 2023 +0100 +++ b/libervia/cli/cmd_forums.py Mon Dec 11 18:10:27 2023 +0100 @@ -18,11 +18,13 @@ # along with this program. If not, see . +import sys from . import base from libervia.backend.core.i18n import _ from libervia.cli.constants import Const as C from libervia.cli import common from libervia.backend.tools.common.ansi import ANSI as A +from libervia.frontends.bridge.bridge_frontend import BridgeException import codecs import json @@ -82,7 +84,7 @@ self.args.key, self.profile, ) - except Exception as e: + except BridgeException as e: if e.classname == "NotFound": forums_json = "" else: @@ -169,11 +171,51 @@ self.host.quit(1) forums = json.loads(forums_raw) await self.output(forums) + + +class Set(base.CommandBase): + + def __init__(self, host): + base.CommandBase.__init__( + self, + host, + "set", + use_pubsub=True, + help=_("set forums"), + ) + + def add_parser_options(self): + self.parser.add_argument( + "-k", + "--key", + default="", + help=_("forum key (DEFAULT: default forums)"), + ) + + async def start(self): + forums_raw = sys.stdin.read() + try: + json.loads(forums_raw) + except Exception as e: + self.parser.error(f"Invalid JSON, a valid JSON must be used as input: {e}") + try: + await self.host.bridge.forums_set( + forums_raw, + self.args.service, + self.args.node, + self.args.key, + self.profile, + ) + except Exception as e: + self.disp(f"can't set forums: {e}", error=True) + self.host.quit(C.EXIT_BRIDGE_ERRBACK) + else: + self.disp(_("forums have been set")) self.host.quit() class Forums(base.CommandBase): - subcommands = (Get, Edit) + subcommands = (Get, Set, Edit) def __init__(self, host): super(Forums, self).__init__(