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:
parent
d841a51a1a
commit
0aa9613693
3 changed files with 189 additions and 4 deletions
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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__(
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Reference in a new issue