cli (blog, pubsub): new attachments subcommands:

`pubsub/attachments` subcommands has a `get` and a `set` subcommand to manage attachments
of a pubsub item.

`blog` has the same subcommands, the only difference is that if `--node` is not specified,
the default blog namespace will be used.

rel 370
This commit is contained in:
Goffi 2022-07-20 17:55:11 +02:00
commit 0aa9613693
3 changed files with 189 additions and 4 deletions

View file

@ -34,7 +34,7 @@ import tty
import termios
from pathlib import Path
from glob import iglob
from typing import Optional
from typing import Optional, Set
from importlib import import_module
from sat_frontends.tools.jid import JID
from sat.tools import config
@ -1319,6 +1319,14 @@ class CommandBase(object):
for cls in subcommands:
cls(self)
def overridePubsubFlags(self, new_flags: Set[str]) -> None:
"""Replace pubsub_flags given in __init__
useful when a command is extending an other command (e.g. blog command which does
the same as pubsub command, but with a default node)
"""
self._pubsub_flags = new_flags
async def run(self):
"""this method is called when a command is actually run

View file

@ -27,7 +27,7 @@ import subprocess
import asyncio
from asyncio.subprocess import DEVNULL
from pathlib import Path
from . import base
from . import base, cmd_pubsub
from sat.core.i18n import _
from sat_frontends.jp.constants import Const as C
from sat_frontends.jp import common
@ -1070,12 +1070,63 @@ class Import(base.CommandBase):
error=True,
)
self.host.quit(1)
else:
await self.set_progress_id(progress_id)
await self.set_progress_id(progress_id)
class AttachmentGet(cmd_pubsub.AttachmentGet):
def __init__(self, host):
super().__init__(host)
self.overridePubsubFlags({C.SERVICE, C.SINGLE_ITEM})
async def start(self):
if not self.args.node:
namespaces = await self.host.bridge.namespacesGet()
try:
ns_microblog = namespaces["microblog"]
except KeyError:
self.disp("XEP-0277 plugin is not loaded", error=True)
self.host.quit(C.EXIT_MISSING_FEATURE)
else:
self.args.node = ns_microblog
return await super().start()
class AttachmentSet(cmd_pubsub.AttachmentSet):
def __init__(self, host):
super().__init__(host)
self.overridePubsubFlags({C.SERVICE, C.SINGLE_ITEM})
async def start(self):
if not self.args.node:
namespaces = await self.host.bridge.namespacesGet()
try:
ns_microblog = namespaces["microblog"]
except KeyError:
self.disp("XEP-0277 plugin is not loaded", error=True)
self.host.quit(C.EXIT_MISSING_FEATURE)
else:
self.args.node = ns_microblog
return await super().start()
class Attachments(base.CommandBase):
subcommands = (AttachmentGet, AttachmentSet)
def __init__(self, host):
super().__init__(
host,
"attachments",
use_profile=False,
help=_("set or retrieve blog attachments"),
)
class Blog(base.CommandBase):
subcommands = (Set, Get, Edit, Rename, Repeat, Preview, Import)
subcommands = (Set, Get, Edit, Rename, Repeat, Preview, Import, Attachments)
def __init__(self, host):
super(Blog, self).__init__(

View file

@ -2419,6 +2419,131 @@ class Uri(base.CommandBase):
self.display_uri(None)
class AttachmentGet(base.CommandBase):
def __init__(self, host):
super().__init__(
host,
"get",
use_output=C.OUTPUT_LIST_DICT,
use_pubsub=True,
pubsub_flags={C.SERVICE, C.NODE, C.SINGLE_ITEM},
help=_("get data attached to an item"),
)
def add_parser_options(self):
self.parser.add_argument(
"-j",
"--jid",
action="append",
dest="jids",
help=_(
"get attached data published only by those JIDs (DEFAULT: get all "
"attached data)"
)
)
async def start(self):
try:
attached_data, __ = await self.host.bridge.psAttachmentsGet(
self.args.service,
self.args.node,
self.args.item,
self.args.jids or [],
"",
self.profile,
)
except Exception as e:
self.disp(f"can't get attached data: {e}", error=True)
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
else:
attached_data = data_format.deserialise(attached_data, type_check=list)
await self.output(attached_data)
self.host.quit(C.EXIT_OK)
class AttachmentSet(base.CommandBase):
def __init__(self, host):
super().__init__(
host,
"set",
use_pubsub=True,
pubsub_flags={C.SERVICE, C.NODE, C.SINGLE_ITEM},
help=_("attach data to an item"),
)
def add_parser_options(self):
self.parser.add_argument(
"-R",
"--replace",
action="store_true",
help=_(
"replace previous versions of attachments (DEFAULT: update previous "
"version)"
)
)
self.parser.add_argument(
"-N",
"--noticed",
metavar="BOOLEAN",
nargs="?",
default="keep",
help=_("mark item as (un)noticed (DEFAULT: keep current value))")
)
self.parser.add_argument(
"-r",
"--reactions",
# FIXME: to be replace by "extend" when we stop supporting python 3.7
action="append",
help=_("add emojis to react to an item")
)
async def start(self):
mb_data = {
"service": self.args.service,
"node": self.args.node,
"id": self.args.item,
"extra": {}
}
operation = "replace" if self.args.replace else "update"
if self.args.noticed != "keep":
if self.args.noticed is None:
self.args.noticed = C.BOOL_TRUE
mb_data["extra"]["noticed"] = C.bool(self.args.noticed)
if self.args.reactions is not None:
mb_data["extra"]["reaction"] = {
"operation": operation,
"reactions": [r for emojis in self.args.reactions for r in emojis]
}
if not mb_data["extra"]:
self.parser.error(_("At leat one attachment must be specified."))
try:
await self.host.bridge.psAttachmentsSet(
data_format.serialise(mb_data),
self.profile,
)
except Exception as e:
self.disp(f"can't attach data to item: {e}", error=True)
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
else:
self.disp("data attached")
self.host.quit(C.EXIT_OK)
class Attachments(base.CommandBase):
subcommands = (AttachmentGet, AttachmentSet)
def __init__(self, host):
super().__init__(
host,
"attachments",
use_profile=False,
help=_("set or retrieve items attachments"),
)
class HookCreate(base.CommandBase):
def __init__(self, host):
base.CommandBase.__init__(
@ -2580,6 +2705,7 @@ class Pubsub(base.CommandBase):
Reference,
Search,
Transform,
Attachments,
Hook,
Uri,
Node,