core, frontends: fix invalid translatable strings.
Some f-strings where used in translatable text, this has been fixed by using explicit `format()` call (using a script based on `tokenize`). As tokenize messes with spaces, a reformating tool (`black`) has been applied to some files afterwards.
This commit is contained in:
parent
8d8541015c
commit
7adbf3ead8
22 changed files with 823 additions and 601 deletions
|
|
@ -972,8 +972,12 @@ class Params(object):
|
|||
|
||||
if not self.checkSecurityLimit(node[1], security_limit):
|
||||
msg = _(
|
||||
f"{profile!r} is trying to set parameter {name!r} in category "
|
||||
f"{category!r} without authorization!!!")
|
||||
"{profile!r} is trying to set parameter {name!r} in category "
|
||||
"{category!r} without authorization!!!").format(
|
||||
profile=repr(profile),
|
||||
name=repr(name),
|
||||
category=repr(category)
|
||||
)
|
||||
log.warning(msg)
|
||||
raise exceptions.PermissionError(msg)
|
||||
|
||||
|
|
@ -986,8 +990,11 @@ class Params(object):
|
|||
int(value)
|
||||
except ValueError:
|
||||
log.warning(_(
|
||||
f"Trying to set parameter {name!r} in category {category!r} with"
|
||||
f"an non-integer value"
|
||||
"Trying to set parameter {name} in category {category} with"
|
||||
"an non-integer value"
|
||||
).format(
|
||||
name=repr(name),
|
||||
category=repr(category)
|
||||
))
|
||||
return defer.succeed(None)
|
||||
if node[1].hasAttribute("constraint"):
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ class ImportPlugin(object):
|
|||
@param name(unicode): import handler name
|
||||
"""
|
||||
assert name == name.lower().strip()
|
||||
log.info(_(f"initializing {name} import handler"))
|
||||
log.info(_("initializing {name} import handler").format(name=name))
|
||||
import_handler.name = name
|
||||
import_handler.register = partial(self.register, import_handler)
|
||||
import_handler.unregister = partial(self.unregister, import_handler)
|
||||
|
|
@ -155,7 +155,7 @@ class ImportPlugin(object):
|
|||
pass
|
||||
except ValueError:
|
||||
raise exceptions.DataError(
|
||||
_(f"invalid json option: {option}")
|
||||
_("invalid json option: {option}").format(option=option)
|
||||
)
|
||||
pubsub_service = jid.JID(pubsub_service) if pubsub_service else None
|
||||
return self.doImport(
|
||||
|
|
|
|||
|
|
@ -708,7 +708,8 @@ class XEP_0329(object):
|
|||
)
|
||||
else:
|
||||
log.warning(
|
||||
_(f"unexpected element, ignoring: {elt.toXml()}")
|
||||
_("unexpected element, ignoring: {elt}")
|
||||
.format(elt=elt.toXml())
|
||||
)
|
||||
continue
|
||||
files.append(file_data)
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ class CommandProtocol(protocol.ProcessProtocol):
|
|||
def processEnded(self, reason):
|
||||
data = b''.join(self.data)
|
||||
if (reason.value.exitCode == 0):
|
||||
log.debug(_(f'{self.command_name!r} command succeed'))
|
||||
log.debug(f'{self.command_name!r} command succeed')
|
||||
# we don't use "replace" on purpose, we want an exception if decoding
|
||||
# is not working properly
|
||||
self._deferred.callback(data)
|
||||
|
|
|
|||
|
|
@ -153,8 +153,10 @@ class LiberviaCli:
|
|||
background = self.guess_background()
|
||||
if background not in ('dark', 'light'):
|
||||
raise exceptions.ConfigError(_(
|
||||
f'Invalid value set for "background" ({background!r}), please check '
|
||||
f'your settings in libervia.conf'))
|
||||
'Invalid value set for "background" ({background}), please check '
|
||||
'your settings in libervia.conf').format(
|
||||
background=repr(background)
|
||||
))
|
||||
if background == 'light':
|
||||
C.A_HEADER = A.FG_MAGENTA
|
||||
C.A_SUBHEADER = A.BOLD + A.FG_RED
|
||||
|
|
@ -449,7 +451,8 @@ class LiberviaCli:
|
|||
if default:
|
||||
if type_ in self.default_output:
|
||||
self.disp(
|
||||
_(f'there is already a default output for {type_}, ignoring new one')
|
||||
_('there is already a default output for {type}, ignoring new one')
|
||||
.format(type=type_)
|
||||
)
|
||||
else:
|
||||
self.default_output[type_] = name
|
||||
|
|
@ -493,7 +496,8 @@ class LiberviaCli:
|
|||
self.import_plugin_module(module, type_)
|
||||
except ImportError as e:
|
||||
self.disp(
|
||||
_(f"Can't import {module_path} plugin, ignoring it: {e}"),
|
||||
_("Can't import {module_path} plugin, ignoring it: {e}")
|
||||
.format(module_path=module_path, e=e),
|
||||
error=True)
|
||||
except exceptions.CancelError:
|
||||
continue
|
||||
|
|
@ -512,7 +516,10 @@ class LiberviaCli:
|
|||
try:
|
||||
class_names = getattr(module, '__{}__'.format(type_))
|
||||
except AttributeError:
|
||||
log.disp(_(f"Invalid plugin module [{type_}] {module}"), error=True)
|
||||
log.disp(
|
||||
_("Invalid plugin module [{type}] {module}")
|
||||
.format(type=type_, module=module),
|
||||
error=True)
|
||||
raise ImportError
|
||||
else:
|
||||
for class_name in class_names:
|
||||
|
|
@ -601,7 +608,9 @@ class LiberviaCli:
|
|||
if not item_last:
|
||||
self.args.item = uri_item
|
||||
else:
|
||||
self.parser.error(_(f'XMPP URL is not a pubsub one: {url}'))
|
||||
self.parser.error(
|
||||
_('XMPP URL is not a pubsub one: {url}').format(url=url)
|
||||
)
|
||||
flags = self.args._cmd._pubsub_flags
|
||||
# we check required arguments here instead of using add_arguments' required option
|
||||
# because the required argument can be set in URL
|
||||
|
|
@ -647,13 +656,15 @@ class LiberviaCli:
|
|||
await self.bridge.bridgeConnect()
|
||||
except Exception as e:
|
||||
if isinstance(e, exceptions.BridgeExceptionNoService):
|
||||
print((_("Can't connect to SàT backend, are you sure it's launched ?")))
|
||||
print(_("Can't connect to SàT backend, are you sure it's launched ?"))
|
||||
self.quit(C.EXIT_BACKEND_NOT_FOUND, raise_exc=False)
|
||||
elif isinstance(e, exceptions.BridgeInitError):
|
||||
print((_("Can't init bridge")))
|
||||
print(_("Can't init bridge"))
|
||||
self.quit(C.EXIT_BRIDGE_ERROR, raise_exc=False)
|
||||
else:
|
||||
print((_(f"Error while initialising bridge: {e}")))
|
||||
print(
|
||||
_("Error while initialising bridge: {e}").format(e=e)
|
||||
)
|
||||
self.quit(C.EXIT_BRIDGE_ERROR, raise_exc=False)
|
||||
return
|
||||
self.version = await self.bridge.getVersion()
|
||||
|
|
@ -844,7 +855,10 @@ class LiberviaCli:
|
|||
self.profile = await self.bridge.profileNameGet(self.args.profile)
|
||||
|
||||
if not self.profile:
|
||||
log.error(_(f"The profile [{self.args.profile}] doesn't exist"))
|
||||
log.error(
|
||||
_("The profile [{profile}] doesn't exist")
|
||||
.format(profile=self.args.profile)
|
||||
)
|
||||
self.quit(C.EXIT_ERROR)
|
||||
|
||||
try:
|
||||
|
|
@ -861,9 +875,11 @@ class LiberviaCli:
|
|||
elif not await self.bridge.profileIsSessionStarted(self.profile):
|
||||
if not self.args.connect:
|
||||
self.disp(_(
|
||||
f"Session for [{self.profile}] is not started, please start it "
|
||||
f"before using jp, or use either --start-session or --connect "
|
||||
f"option"), error=True)
|
||||
"Session for [{profile}] is not started, please start it "
|
||||
"before using jp, or use either --start-session or --connect "
|
||||
"option"
|
||||
.format(profile=self.profile)
|
||||
), error=True)
|
||||
self.quit(1)
|
||||
elif not getattr(self.args, "connect", False):
|
||||
return
|
||||
|
|
@ -882,8 +898,10 @@ class LiberviaCli:
|
|||
else:
|
||||
if not await self.bridge.isConnected(self.profile):
|
||||
log.error(
|
||||
_(f"Profile [{self.profile}] is not connected, please connect it "
|
||||
f"before using jp, or use --connect option"))
|
||||
_("Profile [{profile}] is not connected, please connect it "
|
||||
"before using jp, or use --connect option")
|
||||
.format(profile=self.profile)
|
||||
)
|
||||
self.quit(1)
|
||||
|
||||
async def get_full_jid(self, param_jid):
|
||||
|
|
@ -1158,7 +1176,7 @@ class CommandBase(object):
|
|||
|
||||
@param error_msg(unicode): error message as sent by bridge.progressError
|
||||
"""
|
||||
self.disp(_(f"Error while doing operation: {e}"), error=True)
|
||||
self.disp(_("Error while doing operation: {e}").format(e=e), error=True)
|
||||
|
||||
def disp(self, msg, verbosity=0, error=False, end='\n'):
|
||||
return self.host.disp(msg, verbosity, error, end)
|
||||
|
|
|
|||
|
|
@ -73,7 +73,9 @@ class AccountCreate(base.CommandBase):
|
|||
"--port",
|
||||
type=int,
|
||||
default=0,
|
||||
help=_(f"server port (default: {C.XMPP_C2S_PORT})"),
|
||||
help=_("server port (default: {port})").format(
|
||||
port=C.XMPP_C2S_PORT
|
||||
),
|
||||
)
|
||||
|
||||
async def start(self):
|
||||
|
|
@ -124,8 +126,12 @@ class AccountCreate(base.CommandBase):
|
|||
self.host.quit(C.EXIT_CONFLICT)
|
||||
else:
|
||||
self.disp(
|
||||
_(f"Can't create profile {self.args.profile} to associate with jid "
|
||||
f"{self.args.jid}: {e}"),
|
||||
_("Can't create profile {profile} to associate with jid "
|
||||
"{jid}: {e}").format(
|
||||
profile=self.args.profile,
|
||||
jid=self.args.jid,
|
||||
e=e
|
||||
),
|
||||
error=True,
|
||||
)
|
||||
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
|
||||
|
|
|
|||
|
|
@ -97,7 +97,8 @@ class Remote(base.CommandBase):
|
|||
for method in methods:
|
||||
path, iface, command = method
|
||||
self.disp(
|
||||
_(f"Command found: (path:{path}, iface: {iface}) [{command}]"),
|
||||
_("Command found: (path:{path}, iface: {iface}) [{command}]")
|
||||
.format(path=path, iface=iface, command=command),
|
||||
1,
|
||||
)
|
||||
self.host.quit()
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ class Set(base.CommandBase):
|
|||
async def start(self):
|
||||
path = self.args.image_path
|
||||
if not os.path.exists(path):
|
||||
self.disp(_(f"file {path!r} doesn't exist!"), error=True)
|
||||
self.disp(_("file {path} doesn't exist!").format(path=repr(path)), error=True)
|
||||
self.host.quit(C.EXIT_BAD_ARG)
|
||||
path = os.path.abspath(path)
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ async def guessSyntaxFromPath(host, sat_conf, path):
|
|||
if k and ext == v:
|
||||
return k
|
||||
|
||||
# if not found, we use current syntax
|
||||
# if not found, we use current syntax
|
||||
return await host.bridge.getParamA("Syntax", "Composition", "value", host.profile)
|
||||
|
||||
|
||||
|
|
@ -125,15 +125,17 @@ class BlogPublishCommon(object):
|
|||
self.current_syntax = self.args.syntax = syntax
|
||||
except Exception as e:
|
||||
if e.classname == "NotFound":
|
||||
self.parser.error(_(f"unknown syntax requested ({self.args.syntax})"))
|
||||
self.parser.error(
|
||||
_("unknown syntax requested ({syntax})").format(
|
||||
syntax=self.args.syntax
|
||||
)
|
||||
)
|
||||
else:
|
||||
raise e
|
||||
return self.args.syntax
|
||||
|
||||
def add_parser_options(self):
|
||||
self.parser.add_argument(
|
||||
"-T", "--title", help=_("title of the item")
|
||||
)
|
||||
self.parser.add_argument("-T", "--title", help=_("title of the item"))
|
||||
self.parser.add_argument(
|
||||
"-t",
|
||||
"--tag",
|
||||
|
|
@ -148,13 +150,22 @@ class BlogPublishCommon(object):
|
|||
|
||||
comments_group = self.parser.add_mutually_exclusive_group()
|
||||
comments_group.add_argument(
|
||||
"-C", "--comments", action="store_const", const=True, dest="comments",
|
||||
help=_("enable comments (default: comments not enabled except if they "
|
||||
"already exist)")
|
||||
"-C",
|
||||
"--comments",
|
||||
action="store_const",
|
||||
const=True,
|
||||
dest="comments",
|
||||
help=_(
|
||||
"enable comments (default: comments not enabled except if they "
|
||||
"already exist)"
|
||||
),
|
||||
)
|
||||
comments_group.add_argument(
|
||||
"--no-comments", action="store_const", const=False, dest="comments",
|
||||
help=_("disable comments (will remove comments node if it exist)")
|
||||
"--no-comments",
|
||||
action="store_const",
|
||||
const=False,
|
||||
dest="comments",
|
||||
help=_("disable comments (will remove comments node if it exist)"),
|
||||
)
|
||||
|
||||
self.parser.add_argument(
|
||||
|
|
@ -182,7 +193,7 @@ class BlogPublishCommon(object):
|
|||
if self.args.comments is not None:
|
||||
mb_data["allow_comments"] = self.args.comments
|
||||
if self.args.tag:
|
||||
mb_data['tags'] = self.args.tag
|
||||
mb_data["tags"] = self.args.tag
|
||||
if self.args.title is not None:
|
||||
mb_data["title"] = self.args.title
|
||||
if self.args.language is not None:
|
||||
|
|
@ -222,9 +233,7 @@ class Set(base.CommandBase, BlogPublishCommon):
|
|||
self.profile,
|
||||
)
|
||||
except Exception as e:
|
||||
self.disp(
|
||||
f"can't send item: {e}", error=True
|
||||
)
|
||||
self.disp(f"can't send item: {e}", error=True)
|
||||
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
|
||||
else:
|
||||
self.disp("Item published")
|
||||
|
|
@ -261,12 +270,12 @@ class Get(base.CommandBase):
|
|||
|
||||
def template_data_mapping(self, data):
|
||||
items, blog_items = data
|
||||
blog_items['items'] = items
|
||||
blog_items["items"] = items
|
||||
return {"blog_items": blog_items}
|
||||
|
||||
def format_comments(self, item, keys):
|
||||
lines = []
|
||||
for data in item.get('comments', []):
|
||||
for data in item.get("comments", []):
|
||||
lines.append(data["uri"])
|
||||
for k in ("node", "service"):
|
||||
if OUTPUT_OPT_NO_HEADER in self.args.output_opts:
|
||||
|
|
@ -277,7 +286,7 @@ class Get(base.CommandBase):
|
|||
return "\n".join(lines)
|
||||
|
||||
def format_tags(self, item, keys):
|
||||
tags = item.pop('tags', [])
|
||||
tags = item.pop("tags", [])
|
||||
return ", ".join(tags)
|
||||
|
||||
def format_updated(self, item, keys):
|
||||
|
|
@ -359,7 +368,7 @@ class Get(base.CommandBase):
|
|||
if isinstance(value, bool):
|
||||
value = str(value).lower()
|
||||
self.disp(header + value)
|
||||
# we want a separation line after each item but the last one
|
||||
# we want a separation line after each item but the last one
|
||||
if idx < len(items) - 1:
|
||||
print("")
|
||||
|
||||
|
|
@ -393,7 +402,7 @@ class Get(base.CommandBase):
|
|||
else:
|
||||
author = published = updated = None
|
||||
if verbosity > 1:
|
||||
tags = item.pop('tags', [])
|
||||
tags = item.pop("tags", [])
|
||||
else:
|
||||
tags = None
|
||||
content = item.get("content")
|
||||
|
|
@ -428,14 +437,14 @@ class Get(base.CommandBase):
|
|||
self.args.max,
|
||||
self.args.items,
|
||||
self.getPubsubExtra(),
|
||||
self.profile
|
||||
self.profile,
|
||||
)
|
||||
)
|
||||
except Exception as e:
|
||||
self.disp(f"can't get blog items: {e}", error=True)
|
||||
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
|
||||
else:
|
||||
items = mb_data.pop('items')
|
||||
items = mb_data.pop("items")
|
||||
await self.output((items, mb_data))
|
||||
self.host.quit(C.EXIT_OK)
|
||||
|
||||
|
|
@ -483,7 +492,8 @@ class Edit(base.CommandBase, BlogPublishCommon, common.BaseEdit):
|
|||
# we first construct metadata from edited item ones and CLI argumments
|
||||
# or re-use the existing one if it exists
|
||||
meta_file_path = content_file_path.with_name(
|
||||
content_file_path.stem + common.METADATA_SUFF)
|
||||
content_file_path.stem + common.METADATA_SUFF
|
||||
)
|
||||
if meta_file_path.exists():
|
||||
self.disp("Metadata file already exists, we re-use it")
|
||||
try:
|
||||
|
|
@ -499,20 +509,20 @@ class Edit(base.CommandBase, BlogPublishCommon, common.BaseEdit):
|
|||
else:
|
||||
mb_data = {} if mb_data is None else mb_data.copy()
|
||||
|
||||
# in all cases, we want to remove unwanted keys
|
||||
# in all cases, we want to remove unwanted keys
|
||||
for key in KEY_TO_REMOVE_METADATA:
|
||||
try:
|
||||
del mb_data[key]
|
||||
except KeyError:
|
||||
pass
|
||||
# and override metadata with command-line arguments
|
||||
# and override metadata with command-line arguments
|
||||
self.setMbDataFromArgs(mb_data)
|
||||
|
||||
if self.args.no_publish:
|
||||
mb_data["publish"] = False
|
||||
|
||||
# then we create the file and write metadata there, as JSON dict
|
||||
# XXX: if we port jp one day on Windows, O_BINARY may need to be added here
|
||||
# then we create the file and write metadata there, as JSON dict
|
||||
# XXX: if we port jp one day on Windows, O_BINARY may need to be added here
|
||||
with os.fdopen(
|
||||
os.open(meta_file_path, os.O_RDWR | os.O_CREAT | os.O_TRUNC, 0o600), "w+b"
|
||||
) as f:
|
||||
|
|
@ -556,7 +566,7 @@ class Edit(base.CommandBase, BlogPublishCommon, common.BaseEdit):
|
|||
)
|
||||
)
|
||||
|
||||
# we launch editor
|
||||
# we launch editor
|
||||
coroutines.append(
|
||||
self.runEditor(
|
||||
"blog_editor_args",
|
||||
|
|
@ -590,11 +600,9 @@ class Edit(base.CommandBase, BlogPublishCommon, common.BaseEdit):
|
|||
items = [item] if item else []
|
||||
|
||||
mb_data = data_format.deserialise(
|
||||
await self.host.bridge.mbGet(
|
||||
service, node, 1, items, {}, self.profile
|
||||
)
|
||||
await self.host.bridge.mbGet(service, node, 1, items, {}, self.profile)
|
||||
)
|
||||
item = mb_data['items'][0]
|
||||
item = mb_data["items"][0]
|
||||
|
||||
try:
|
||||
content = item["content_xhtml"]
|
||||
|
|
@ -612,8 +620,8 @@ class Edit(base.CommandBase, BlogPublishCommon, common.BaseEdit):
|
|||
|
||||
if content and self.current_syntax == SYNTAX_XHTML:
|
||||
content = content.strip()
|
||||
if not content.startswith('<div>'):
|
||||
content = '<div>' + content + '</div>'
|
||||
if not content.startswith("<div>"):
|
||||
content = "<div>" + content + "</div>"
|
||||
try:
|
||||
from lxml import etree
|
||||
except ImportError:
|
||||
|
|
@ -630,15 +638,20 @@ class Edit(base.CommandBase, BlogPublishCommon, common.BaseEdit):
|
|||
SYNTAX_EXT.update(config.getConfig(self.sat_conf, "jp", CONF_SYNTAX_EXT, {}))
|
||||
self.current_syntax = await self.get_current_syntax()
|
||||
|
||||
(self.pubsub_service, self.pubsub_node, self.pubsub_item, content_file_path,
|
||||
content_file_obj, mb_data,) = await self.getItemPath()
|
||||
(
|
||||
self.pubsub_service,
|
||||
self.pubsub_node,
|
||||
self.pubsub_item,
|
||||
content_file_path,
|
||||
content_file_obj,
|
||||
mb_data,
|
||||
) = await self.getItemPath()
|
||||
|
||||
await self.edit(content_file_path, content_file_obj, mb_data=mb_data)
|
||||
self.host.quit()
|
||||
|
||||
|
||||
class Rename(base.CommandBase):
|
||||
|
||||
def __init__(self, host):
|
||||
base.CommandBase.__init__(
|
||||
self,
|
||||
|
|
@ -650,10 +663,7 @@ class Rename(base.CommandBase):
|
|||
)
|
||||
|
||||
def add_parser_options(self):
|
||||
self.parser.add_argument(
|
||||
"new_id",
|
||||
help=_("new item id to use")
|
||||
)
|
||||
self.parser.add_argument("new_id", help=_("new item id to use"))
|
||||
|
||||
async def start(self):
|
||||
try:
|
||||
|
|
@ -665,14 +675,13 @@ class Rename(base.CommandBase):
|
|||
self.profile,
|
||||
)
|
||||
except Exception as e:
|
||||
self.disp(
|
||||
f"can't rename item: {e}", error=True
|
||||
)
|
||||
self.disp(f"can't rename item: {e}", error=True)
|
||||
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
|
||||
else:
|
||||
self.disp("Item renamed")
|
||||
self.host.quit(C.EXIT_OK)
|
||||
|
||||
|
||||
class Preview(base.CommandBase, common.BaseEdit):
|
||||
# TODO: need to be rewritten with template output
|
||||
|
||||
|
|
@ -735,9 +744,9 @@ class Preview(base.CommandBase, common.BaseEdit):
|
|||
xhtml = (
|
||||
f'<html xmlns="http://www.w3.org/1999/xhtml">'
|
||||
f'<head><meta http-equiv="Content-Type" content="text/html;charset=utf-8" />'
|
||||
f'</head>'
|
||||
f'<body>{content}</body>'
|
||||
f'</html>'
|
||||
f"</head>"
|
||||
f"<body>{content}</body>"
|
||||
f"</html>"
|
||||
)
|
||||
|
||||
with open(self.preview_file_path, "wb") as f:
|
||||
|
|
@ -791,18 +800,19 @@ class Preview(base.CommandBase, common.BaseEdit):
|
|||
else:
|
||||
update_cb = self.updatePreviewExt
|
||||
|
||||
# which file do we need to edit?
|
||||
# which file do we need to edit?
|
||||
if self.args.file == "current":
|
||||
self.content_file_path = self.getCurrentFile(self.profile)
|
||||
else:
|
||||
try:
|
||||
self.content_file_path = Path(self.args.file).resolve(strict=True)
|
||||
except FileNotFoundError:
|
||||
self.disp(_(f'File "{self.args.file}" doesn\'t exist!'))
|
||||
self.disp(_('File "{file}" doesn\'t exist!').format(file=self.args.file))
|
||||
self.host.quit(C.EXIT_NOT_FOUND)
|
||||
|
||||
self.syntax = await guessSyntaxFromPath(
|
||||
self.host, sat_conf, self.content_file_path)
|
||||
self.host, sat_conf, self.content_file_path
|
||||
)
|
||||
|
||||
# at this point the syntax is converted, we can display the preview
|
||||
preview_file = tempfile.NamedTemporaryFile(suffix=".xhtml", delete=False)
|
||||
|
|
@ -825,10 +835,10 @@ class Preview(base.CommandBase, common.BaseEdit):
|
|||
watcher_kwargs = {
|
||||
# Watcher don't accept Path so we convert to string
|
||||
"path": str(self.content_file_path),
|
||||
"alias": 'content_file',
|
||||
"alias": "content_file",
|
||||
"flags": aionotify.Flags.CLOSE_WRITE
|
||||
| aionotify.Flags.DELETE_SELF
|
||||
| aionotify.Flags.MOVE_SELF,
|
||||
| aionotify.Flags.DELETE_SELF
|
||||
| aionotify.Flags.MOVE_SELF,
|
||||
}
|
||||
watcher.watch(**watcher_kwargs)
|
||||
|
||||
|
|
@ -839,14 +849,15 @@ class Preview(base.CommandBase, common.BaseEdit):
|
|||
while True:
|
||||
event = await watcher.get_event()
|
||||
self.disp("Content updated", 1)
|
||||
if event.flags & (aionotify.Flags.DELETE_SELF
|
||||
| aionotify.Flags.MOVE_SELF):
|
||||
if event.flags & (
|
||||
aionotify.Flags.DELETE_SELF | aionotify.Flags.MOVE_SELF
|
||||
):
|
||||
self.disp(
|
||||
"DELETE/MOVE event catched, changing the watch",
|
||||
2,
|
||||
)
|
||||
try:
|
||||
watcher.unwatch('content_file')
|
||||
watcher.unwatch("content_file")
|
||||
except IOError as e:
|
||||
self.disp(
|
||||
f"Can't remove the watch: {e}",
|
||||
|
|
@ -869,7 +880,7 @@ class Preview(base.CommandBase, common.BaseEdit):
|
|||
finally:
|
||||
os.unlink(self.preview_file_path)
|
||||
try:
|
||||
watcher.unwatch('content_file')
|
||||
watcher.unwatch("content_file")
|
||||
except IOError as e:
|
||||
self.disp(
|
||||
f"Can't remove the watch: {e}",
|
||||
|
|
@ -893,9 +904,7 @@ class Import(base.CommandBase):
|
|||
nargs="?",
|
||||
help=_("importer name, nothing to display importers list"),
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"--host", help=_("original blog host")
|
||||
)
|
||||
self.parser.add_argument("--host", help=_("original blog host"))
|
||||
self.parser.add_argument(
|
||||
"--no-images-upload",
|
||||
action="store_true",
|
||||
|
|
@ -954,13 +963,16 @@ class Import(base.CommandBase):
|
|||
)
|
||||
self.disp(
|
||||
_(
|
||||
f"\nTo redirect old URLs to new ones, put the following lines in your"
|
||||
f" sat.conf file, in [libervia] section:\n\n{conf}"
|
||||
)
|
||||
"\nTo redirect old URLs to new ones, put the following lines in your"
|
||||
" sat.conf file, in [libervia] section:\n\n{conf}"
|
||||
).format(conf=conf)
|
||||
)
|
||||
|
||||
async def onProgressError(self, error_msg):
|
||||
self.disp(_(f"Error while uploading blog: {error_msg}"), error=True)
|
||||
self.disp(
|
||||
_("Error while uploading blog: {error_msg}").format(error_msg=error_msg),
|
||||
error=True,
|
||||
)
|
||||
|
||||
async def start(self):
|
||||
if self.args.location is None:
|
||||
|
|
@ -968,8 +980,8 @@ class Import(base.CommandBase):
|
|||
if getattr(self.args, name):
|
||||
self.parser.error(
|
||||
_(
|
||||
f"{name} argument can't be used without location argument"
|
||||
)
|
||||
"{name} argument can't be used without location argument"
|
||||
).format(name=name)
|
||||
)
|
||||
if self.args.importer is None:
|
||||
self.disp(
|
||||
|
|
@ -1022,13 +1034,14 @@ class Import(base.CommandBase):
|
|||
)
|
||||
except Exception as e:
|
||||
self.disp(
|
||||
_(f"Error while trying to import a blog: {e}"),
|
||||
_("Error while trying to import a blog: {e}").format(e=e),
|
||||
error=True,
|
||||
)
|
||||
self.host.quit(1)
|
||||
|
||||
await self.set_progress_id(progress_id)
|
||||
|
||||
|
||||
class Blog(base.CommandBase):
|
||||
subcommands = (Set, Get, Edit, Rename, Preview, Import)
|
||||
|
||||
|
|
|
|||
|
|
@ -23,25 +23,41 @@ from sat_frontends.jp.constants import Const as C
|
|||
|
||||
__commands__ = ["Bookmarks"]
|
||||
|
||||
STORAGE_LOCATIONS = ('local', 'private', 'pubsub')
|
||||
TYPES = ('muc', 'url')
|
||||
STORAGE_LOCATIONS = ("local", "private", "pubsub")
|
||||
TYPES = ("muc", "url")
|
||||
|
||||
|
||||
class BookmarksCommon(base.CommandBase):
|
||||
"""Class used to group common options of bookmarks subcommands"""
|
||||
|
||||
def add_parser_options(self, location_default='all'):
|
||||
self.parser.add_argument('-l', '--location', type=str, choices=(location_default,) + STORAGE_LOCATIONS, default=location_default, help=_("storage location (default: %(default)s)"))
|
||||
self.parser.add_argument('-t', '--type', type=str, choices=TYPES, default=TYPES[0], help=_("bookmarks type (default: %(default)s)"))
|
||||
def add_parser_options(self, location_default="all"):
|
||||
self.parser.add_argument(
|
||||
"-l",
|
||||
"--location",
|
||||
type=str,
|
||||
choices=(location_default,) + STORAGE_LOCATIONS,
|
||||
default=location_default,
|
||||
help=_("storage location (default: %(default)s)"),
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"-t",
|
||||
"--type",
|
||||
type=str,
|
||||
choices=TYPES,
|
||||
default=TYPES[0],
|
||||
help=_("bookmarks type (default: %(default)s)"),
|
||||
)
|
||||
|
||||
|
||||
class BookmarksList(BookmarksCommon):
|
||||
|
||||
def __init__(self, host):
|
||||
super(BookmarksList, self).__init__(host, 'list', help=_('list bookmarks'))
|
||||
super(BookmarksList, self).__init__(host, "list", help=_("list bookmarks"))
|
||||
|
||||
async def start(self):
|
||||
try:
|
||||
data = await self.host.bridge.bookmarksList(
|
||||
self.args.type, self.args.location, self.host.profile)
|
||||
self.args.type, self.args.location, self.host.profile
|
||||
)
|
||||
except Exception as e:
|
||||
self.disp(f"can't get bookmarks list: {e}", error=True)
|
||||
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
|
||||
|
|
@ -54,32 +70,40 @@ class BookmarksList(BookmarksCommon):
|
|||
loc_mess.append(f"{location}:")
|
||||
book_mess = []
|
||||
for book_link, book_data in list(data[location].items()):
|
||||
name = book_data.get('name')
|
||||
autojoin = book_data.get('autojoin', 'false') == 'true'
|
||||
nick = book_data.get('nick')
|
||||
book_mess.append("\t%s[%s%s]%s" % ((name+' ') if name else '',
|
||||
book_link,
|
||||
' (%s)' % nick if nick else '',
|
||||
' (*)' if autojoin else ''))
|
||||
loc_mess.append('\n'.join(book_mess))
|
||||
mess.append('\n'.join(loc_mess))
|
||||
name = book_data.get("name")
|
||||
autojoin = book_data.get("autojoin", "false") == "true"
|
||||
nick = book_data.get("nick")
|
||||
book_mess.append(
|
||||
"\t%s[%s%s]%s"
|
||||
% (
|
||||
(name + " ") if name else "",
|
||||
book_link,
|
||||
" (%s)" % nick if nick else "",
|
||||
" (*)" if autojoin else "",
|
||||
)
|
||||
)
|
||||
loc_mess.append("\n".join(book_mess))
|
||||
mess.append("\n".join(loc_mess))
|
||||
|
||||
print('\n\n'.join(mess))
|
||||
print("\n\n".join(mess))
|
||||
self.host.quit()
|
||||
|
||||
|
||||
class BookmarksRemove(BookmarksCommon):
|
||||
|
||||
def __init__(self, host):
|
||||
super(BookmarksRemove, self).__init__(host, 'remove', help=_('remove a bookmark'))
|
||||
super(BookmarksRemove, self).__init__(host, "remove", help=_("remove a bookmark"))
|
||||
|
||||
def add_parser_options(self):
|
||||
super(BookmarksRemove, self).add_parser_options()
|
||||
self.parser.add_argument(
|
||||
'bookmark', help=_('jid (for muc bookmark) or url of to remove'))
|
||||
"bookmark", help=_("jid (for muc bookmark) or url of to remove")
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"-f", "--force", action="store_true",
|
||||
help=_("delete bookmark without confirmation"),)
|
||||
"-f",
|
||||
"--force",
|
||||
action="store_true",
|
||||
help=_("delete bookmark without confirmation"),
|
||||
)
|
||||
|
||||
async def start(self):
|
||||
if not self.args.force:
|
||||
|
|
@ -87,50 +111,58 @@ class BookmarksRemove(BookmarksCommon):
|
|||
|
||||
try:
|
||||
await self.host.bridge.bookmarksRemove(
|
||||
self.args.type, self.args.bookmark, self.args.location, self.host.profile)
|
||||
self.args.type, self.args.bookmark, self.args.location, self.host.profile
|
||||
)
|
||||
except Exception as e:
|
||||
self.disp(_(f"can't delete bookmark: {e}"), error=True)
|
||||
self.disp(_("can't delete bookmark: {e}").format(e=e), error=True)
|
||||
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
|
||||
else:
|
||||
self.disp(_('bookmark deleted'))
|
||||
self.disp(_("bookmark deleted"))
|
||||
self.host.quit()
|
||||
|
||||
|
||||
class BookmarksAdd(BookmarksCommon):
|
||||
|
||||
def __init__(self, host):
|
||||
super(BookmarksAdd, self).__init__(host, 'add', help=_('add a bookmark'))
|
||||
super(BookmarksAdd, self).__init__(host, "add", help=_("add a bookmark"))
|
||||
|
||||
def add_parser_options(self):
|
||||
super(BookmarksAdd, self).add_parser_options(location_default='auto')
|
||||
super(BookmarksAdd, self).add_parser_options(location_default="auto")
|
||||
self.parser.add_argument(
|
||||
'bookmark', help=_('jid (for muc bookmark) or url of to remove'))
|
||||
self.parser.add_argument('-n', '--name', help=_("bookmark name"))
|
||||
muc_group = self.parser.add_argument_group(_('MUC specific options'))
|
||||
muc_group.add_argument('-N', '--nick', help=_('nickname'))
|
||||
"bookmark", help=_("jid (for muc bookmark) or url of to remove")
|
||||
)
|
||||
self.parser.add_argument("-n", "--name", help=_("bookmark name"))
|
||||
muc_group = self.parser.add_argument_group(_("MUC specific options"))
|
||||
muc_group.add_argument("-N", "--nick", help=_("nickname"))
|
||||
muc_group.add_argument(
|
||||
'-a', '--autojoin', action='store_true',
|
||||
help=_('join room on profile connection'))
|
||||
"-a",
|
||||
"--autojoin",
|
||||
action="store_true",
|
||||
help=_("join room on profile connection"),
|
||||
)
|
||||
|
||||
async def start(self):
|
||||
if self.args.type == 'url' and (self.args.autojoin or self.args.nick is not None):
|
||||
if self.args.type == "url" and (self.args.autojoin or self.args.nick is not None):
|
||||
self.parser.error(_("You can't use --autojoin or --nick with --type url"))
|
||||
data = {}
|
||||
if self.args.autojoin:
|
||||
data['autojoin'] = 'true'
|
||||
data["autojoin"] = "true"
|
||||
if self.args.nick is not None:
|
||||
data['nick'] = self.args.nick
|
||||
data["nick"] = self.args.nick
|
||||
if self.args.name is not None:
|
||||
data['name'] = self.args.name
|
||||
data["name"] = self.args.name
|
||||
try:
|
||||
await self.host.bridge.bookmarksAdd(
|
||||
self.args.type, self.args.bookmark, data, self.args.location,
|
||||
self.host.profile)
|
||||
self.args.type,
|
||||
self.args.bookmark,
|
||||
data,
|
||||
self.args.location,
|
||||
self.host.profile,
|
||||
)
|
||||
except Exception as e:
|
||||
self.disp(f"can't add bookmark: {e}", error=True)
|
||||
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
|
||||
else:
|
||||
self.disp(_('bookmark successfully added'))
|
||||
self.disp(_("bookmark successfully added"))
|
||||
self.host.quit()
|
||||
|
||||
|
||||
|
|
@ -138,4 +170,6 @@ class Bookmarks(base.CommandBase):
|
|||
subcommands = (BookmarksList, BookmarksRemove, BookmarksAdd)
|
||||
|
||||
def __init__(self, host):
|
||||
super(Bookmarks, self).__init__(host, 'bookmarks', use_profile=False, help=_('manage bookmarks'))
|
||||
super(Bookmarks, self).__init__(
|
||||
host, "bookmarks", use_profile=False, help=_("manage bookmarks")
|
||||
)
|
||||
|
|
|
|||
|
|
@ -53,20 +53,19 @@ class Method(base.CommandBase, BridgeCommon):
|
|||
self.parser.add_argument(
|
||||
"method", type=str, help=_("name of the method to execute")
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"arg", nargs="*", help=_("argument of the method")
|
||||
)
|
||||
self.parser.add_argument("arg", nargs="*", help=_("argument of the method"))
|
||||
|
||||
async def start(self):
|
||||
method = getattr(self.host.bridge, self.args.method)
|
||||
import inspect
|
||||
|
||||
argspec = inspect.getargspec(method)
|
||||
|
||||
kwargs = {}
|
||||
if 'profile_key' in argspec.args:
|
||||
kwargs['profile_key'] = self.profile
|
||||
elif 'profile' in argspec.args:
|
||||
kwargs['profile'] = self.profile
|
||||
if "profile_key" in argspec.args:
|
||||
kwargs["profile_key"] = self.profile
|
||||
elif "profile" in argspec.args:
|
||||
kwargs["profile"] = self.profile
|
||||
|
||||
args = self.evalArgs()
|
||||
|
||||
|
|
@ -76,7 +75,12 @@ class Method(base.CommandBase, BridgeCommon):
|
|||
**kwargs,
|
||||
)
|
||||
except Exception as e:
|
||||
self.disp(_(f"Error while executing {self.args.method}: {e}"), error=True)
|
||||
self.disp(
|
||||
_("Error while executing {method}: {e}").format(
|
||||
method=self.args.method, e=e
|
||||
),
|
||||
error=True,
|
||||
)
|
||||
self.host.quit(C.EXIT_ERROR)
|
||||
else:
|
||||
if ret is not None:
|
||||
|
|
@ -92,12 +96,8 @@ class Signal(base.CommandBase, BridgeCommon):
|
|||
BridgeCommon.__init__(self)
|
||||
|
||||
def add_parser_options(self):
|
||||
self.parser.add_argument(
|
||||
"signal", type=str, help=_("name of the signal to send")
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"arg", nargs="*", help=_("argument of the signal")
|
||||
)
|
||||
self.parser.add_argument("signal", type=str, help=_("name of the signal to send"))
|
||||
self.parser.add_argument("arg", nargs="*", help=_("argument of the signal"))
|
||||
|
||||
async def start(self):
|
||||
args = self.evalArgs()
|
||||
|
|
@ -105,9 +105,11 @@ class Signal(base.CommandBase, BridgeCommon):
|
|||
# XXX: we use self.args.profile and not self.profile
|
||||
# because we want the raw profile_key (so plugin handle C.PROF_KEY_NONE)
|
||||
try:
|
||||
await self.host.bridge.debugFakeSignal(self.args.signal, json_args, self.args.profile)
|
||||
await self.host.bridge.debugFakeSignal(
|
||||
self.args.signal, json_args, self.args.profile
|
||||
)
|
||||
except Exception as e:
|
||||
self.disp(_(f"Can't send fake signal: {e}"), error=True)
|
||||
self.disp(_("Can't send fake signal: {e}").format(e=e), error=True)
|
||||
self.host.quit(C.EXIT_ERROR)
|
||||
else:
|
||||
self.host.quit()
|
||||
|
|
@ -198,18 +200,17 @@ class Theme(base.CommandBase):
|
|||
|
||||
async def start(self):
|
||||
for attr in dir(C):
|
||||
if not attr.startswith('A_'):
|
||||
if not attr.startswith("A_"):
|
||||
continue
|
||||
color = getattr(C, attr)
|
||||
if attr == 'A_LEVEL_COLORS':
|
||||
if attr == "A_LEVEL_COLORS":
|
||||
# This constant contains multiple colors
|
||||
self.disp('LEVEL COLORS: ', end=' ')
|
||||
self.disp("LEVEL COLORS: ", end=" ")
|
||||
for idx, c in enumerate(color):
|
||||
last = idx == len(color)-1
|
||||
end = '\n' if last else ' '
|
||||
last = idx == len(color) - 1
|
||||
end = "\n" if last else " "
|
||||
self.disp(
|
||||
c + f'LEVEL_{idx}' + A.RESET + (', ' if not last else ''),
|
||||
end=end
|
||||
c + f"LEVEL_{idx}" + A.RESET + (", " if not last else ""), end=end
|
||||
)
|
||||
else:
|
||||
text = attr[2:]
|
||||
|
|
|
|||
|
|
@ -107,9 +107,7 @@ class EventBase(object):
|
|||
default="",
|
||||
help=_("ID of the PubSub Item"),
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"-d", "--date", type=str, help=_("date of the event")
|
||||
)
|
||||
self.parser.add_argument("-d", "--date", type=str, help=_("date of the event"))
|
||||
self.parser.add_argument(
|
||||
"-f",
|
||||
"--field",
|
||||
|
|
@ -169,7 +167,7 @@ class Create(EventBase, base.CommandBase):
|
|||
self.disp(f"can't create event: {e}", error=True)
|
||||
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
|
||||
else:
|
||||
self.disp(_(f"Event created successfuly on node {node}"))
|
||||
self.disp(_("Event created successfuly on node {node}").format(node=node))
|
||||
self.host.quit()
|
||||
|
||||
|
||||
|
|
@ -350,9 +348,7 @@ class InviteesList(base.CommandBase):
|
|||
table = common.Table.fromListDict(
|
||||
self.host,
|
||||
data,
|
||||
("nick",)
|
||||
+ (("jid",) if self.host.verbosity else ())
|
||||
+ ("attend", "guests"),
|
||||
("nick",) + (("jid",) if self.host.verbosity else ()) + ("attend", "guests"),
|
||||
headers=None,
|
||||
filters={
|
||||
"nick": A.color(C.A_HEADER, "{}" if show_table else "{} "),
|
||||
|
|
@ -402,9 +398,7 @@ class InviteesList(base.CommandBase):
|
|||
)
|
||||
)
|
||||
self.disp(
|
||||
A.color(
|
||||
C.A_SUBHEADER, _("total: "), A.RESET, str(guests + guests_maybe)
|
||||
)
|
||||
A.color(C.A_SUBHEADER, _("total: "), A.RESET, str(guests + guests_maybe))
|
||||
)
|
||||
if attendees_missing:
|
||||
self.disp("")
|
||||
|
|
@ -453,7 +447,7 @@ class InviteesList(base.CommandBase):
|
|||
self.disp(f"can't get event data: {e}", error=True)
|
||||
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
|
||||
|
||||
# we fill nicknames and keep only requested people
|
||||
# we fill nicknames and keep only requested people
|
||||
|
||||
if self.args.no_rsvp:
|
||||
for jid_ in event_data:
|
||||
|
|
@ -462,21 +456,23 @@ class InviteesList(base.CommandBase):
|
|||
try:
|
||||
del prefilled[jid_]
|
||||
except KeyError:
|
||||
self.disp(A.color(
|
||||
C.A_WARNING,
|
||||
f"We got a RSVP from somebody who was not in invitees "
|
||||
f"list: {jid_}"
|
||||
self.disp(
|
||||
A.color(
|
||||
C.A_WARNING,
|
||||
f"We got a RSVP from somebody who was not in invitees "
|
||||
f"list: {jid_}",
|
||||
),
|
||||
error=True)
|
||||
error=True,
|
||||
)
|
||||
else:
|
||||
# we replace empty dicts for existing people with R.S.V.P. data
|
||||
prefilled.update(event_data)
|
||||
|
||||
# we get nicknames for everybody, make it easier for organisers
|
||||
# we get nicknames for everybody, make it easier for organisers
|
||||
for jid_, data in prefilled.items():
|
||||
id_data = await self.host.bridge.identityGet(jid_, [], True, self.profile)
|
||||
id_data = data_format.deserialise(id_data)
|
||||
data["nick"] = id_data['nicknames'][0]
|
||||
data["nick"] = id_data["nicknames"][0]
|
||||
|
||||
await self.output(prefilled)
|
||||
self.host.quit()
|
||||
|
|
|
|||
|
|
@ -54,9 +54,7 @@ class Send(base.CommandBase):
|
|||
self.parser.add_argument(
|
||||
"files", type=str, nargs="+", metavar="file", help=_("a list of file")
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"jid", help=_("the destination jid")
|
||||
)
|
||||
self.parser.add_argument("jid", help=_("the destination jid"))
|
||||
self.parser.add_argument(
|
||||
"-b", "--bz2", action="store_true", help=_("make a bzip2 tarball")
|
||||
)
|
||||
|
|
@ -101,19 +99,21 @@ class Send(base.CommandBase):
|
|||
await self.set_progress_id(data["progress"])
|
||||
except KeyError:
|
||||
# TODO: if 'xmlui' key is present, manage xmlui message display
|
||||
self.disp(
|
||||
_("Can't send file to {jid}".format(jid=self.args.jid)), error=True
|
||||
)
|
||||
self.disp(_("Can't send file to {jid}".format(jid=self.args.jid)), error=True)
|
||||
self.host.quit(2)
|
||||
|
||||
async def start(self):
|
||||
for file_ in self.args.files:
|
||||
if not os.path.exists(file_):
|
||||
self.disp(_(f"file {file_!r} doesn't exist!"), error=True)
|
||||
self.disp(
|
||||
_("file {file_} doesn't exist!").format(file_=repr(file_)), error=True
|
||||
)
|
||||
self.host.quit(C.EXIT_BAD_ARG)
|
||||
if not self.args.bz2 and os.path.isdir(file_):
|
||||
self.disp(
|
||||
_(f"{file_!r} is a dir! Please send files inside or use compression")
|
||||
_(
|
||||
"{file_} is a dir! Please send files inside or use compression"
|
||||
).format(file_=repr(file_))
|
||||
)
|
||||
self.host.quit(C.EXIT_BAD_ARG)
|
||||
|
||||
|
|
@ -188,9 +188,7 @@ class Request(base.CommandBase):
|
|||
return self.args.name or self.args.hash or "output"
|
||||
|
||||
def add_parser_options(self):
|
||||
self.parser.add_argument(
|
||||
"jid", help=_("the destination jid")
|
||||
)
|
||||
self.parser.add_argument("jid", help=_("the destination jid"))
|
||||
self.parser.add_argument(
|
||||
"-D",
|
||||
"--dest",
|
||||
|
|
@ -258,7 +256,8 @@ class Request(base.CommandBase):
|
|||
|
||||
if os.path.exists(path) and not self.args.force:
|
||||
message = _("File {path} already exists! Do you want to overwrite?").format(
|
||||
path = path)
|
||||
path=path
|
||||
)
|
||||
await self.host.confirmOrQuit(message, _("file request cancelled"))
|
||||
|
||||
self.full_dest_jid = await self.host.get_full_jid(self.args.jid)
|
||||
|
|
@ -278,7 +277,7 @@ class Request(base.CommandBase):
|
|||
self.profile,
|
||||
)
|
||||
except Exception as e:
|
||||
self.disp(msg=_(f"can't request file: {e}"), error=True)
|
||||
self.disp(msg=_("can't request file: {e}").format(e=e), error=True)
|
||||
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
|
||||
else:
|
||||
await self.set_progress_id(progress_id)
|
||||
|
|
@ -334,15 +333,16 @@ class Receive(base.CommandAnswering):
|
|||
self.disp(_("File received successfully"), 2)
|
||||
if metadata.get("hash_verified", False):
|
||||
try:
|
||||
self.disp(_(
|
||||
f"hash checked: {metadata['hash_algo']}:{metadata['hash']}"), 1)
|
||||
self.disp(
|
||||
_("hash checked: {metadata['hash_algo']}:{metadata['hash']}"), 1
|
||||
)
|
||||
except KeyError:
|
||||
self.disp(_("hash is checked but hash value is missing", 1), error=True)
|
||||
else:
|
||||
self.disp(_("hash can't be verified"), 1)
|
||||
|
||||
async def onProgressError(self, e):
|
||||
self.disp(_(f"Error while receiving file: {e}"), error=True)
|
||||
self.disp(_("Error while receiving file: {e}").format(e=e), error=True)
|
||||
|
||||
def getXmluiId(self, action_data):
|
||||
# FIXME: we temporarily use ElementTree, but a real XMLUI managing module
|
||||
|
|
@ -413,8 +413,12 @@ class Receive(base.CommandAnswering):
|
|||
try:
|
||||
from_jid = jid.JID(action_data["meta_from_jid"])
|
||||
except ValueError:
|
||||
self.disp(_('invalid "from_jid" value received, ignoring: {value}').format(
|
||||
value=from_jid), error=True)
|
||||
self.disp(
|
||||
_('invalid "from_jid" value received, ignoring: {value}').format(
|
||||
value=from_jid
|
||||
),
|
||||
error=True,
|
||||
)
|
||||
return
|
||||
except KeyError:
|
||||
self.disp(_('ignoring action without "from_jid" value'), error=True)
|
||||
|
|
@ -448,18 +452,23 @@ class Receive(base.CommandAnswering):
|
|||
|
||||
|
||||
class Get(base.CommandBase):
|
||||
|
||||
def __init__(self, host):
|
||||
super(Get, self).__init__(
|
||||
host, "get", use_progress=True, use_verbose=True,
|
||||
help=_("download a file from URI")
|
||||
host,
|
||||
"get",
|
||||
use_progress=True,
|
||||
use_verbose=True,
|
||||
help=_("download a file from URI"),
|
||||
)
|
||||
|
||||
def add_parser_options(self):
|
||||
self.parser.add_argument(
|
||||
'-o', '--dest-file', type=str, default='',
|
||||
help=_("destination file (DEFAULT: filename from URL)")
|
||||
)
|
||||
"-o",
|
||||
"--dest-file",
|
||||
type=str,
|
||||
default="",
|
||||
help=_("destination file (DEFAULT: filename from URL)"),
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"-f",
|
||||
"--force",
|
||||
|
|
@ -482,8 +491,8 @@ class Get(base.CommandBase):
|
|||
try:
|
||||
await self.set_progress_id(data["progress"])
|
||||
except KeyError:
|
||||
if 'xmlui' in data:
|
||||
ui = xmlui_manager.create(self.host, data['xmlui'])
|
||||
if "xmlui" in data:
|
||||
ui = xmlui_manager.create(self.host, data["xmlui"])
|
||||
await ui.show()
|
||||
else:
|
||||
self.disp(_("Can't download file"), error=True)
|
||||
|
|
@ -499,7 +508,8 @@ class Get(base.CommandBase):
|
|||
dest_file = Path(dest_file).expanduser().resolve()
|
||||
if dest_file.exists() and not self.args.force:
|
||||
message = _("File {path} already exists! Do you want to overwrite?").format(
|
||||
path = dest_file)
|
||||
path=dest_file
|
||||
)
|
||||
await self.host.confirmOrQuit(message, _("file download cancelled"))
|
||||
|
||||
options = {}
|
||||
|
|
@ -569,8 +579,8 @@ class Upload(base.CommandBase):
|
|||
try:
|
||||
await self.set_progress_id(data["progress"])
|
||||
except KeyError:
|
||||
if 'xmlui' in data:
|
||||
ui = xmlui_manager.create(self.host, data['xmlui'])
|
||||
if "xmlui" in data:
|
||||
ui = xmlui_manager.create(self.host, data["xmlui"])
|
||||
await ui.show()
|
||||
else:
|
||||
self.disp(_("Can't upload file"), error=True)
|
||||
|
|
@ -579,10 +589,12 @@ class Upload(base.CommandBase):
|
|||
async def start(self):
|
||||
file_ = self.args.file
|
||||
if not os.path.exists(file_):
|
||||
self.disp(_(f"file {file_!r} doesn't exist !"), error=True)
|
||||
self.disp(
|
||||
_("file {file_} doesn't exist !").format(file_=repr(file_)), error=True
|
||||
)
|
||||
self.host.quit(C.EXIT_BAD_ARG)
|
||||
if os.path.isdir(file_):
|
||||
self.disp(_(f"{file_!r} is a dir! Can't upload a dir"))
|
||||
self.disp(_("{file_} is a dir! Can't upload a dir").format(file_=repr(file_)))
|
||||
self.host.quit(C.EXIT_BAD_ARG)
|
||||
|
||||
if self.args.jid is None:
|
||||
|
|
@ -613,7 +625,6 @@ class Upload(base.CommandBase):
|
|||
|
||||
|
||||
class ShareAffiliationsSet(base.CommandBase):
|
||||
|
||||
def __init__(self, host):
|
||||
super(ShareAffiliationsSet, self).__init__(
|
||||
host,
|
||||
|
|
@ -720,7 +731,6 @@ class ShareAffiliations(base.CommandBase):
|
|||
|
||||
|
||||
class ShareConfigurationSet(base.CommandBase):
|
||||
|
||||
def __init__(self, host):
|
||||
super(ShareConfigurationSet, self).__init__(
|
||||
host,
|
||||
|
|
@ -822,8 +832,10 @@ class ShareConfiguration(base.CommandBase):
|
|||
|
||||
def __init__(self, host):
|
||||
super(ShareConfiguration, self).__init__(
|
||||
host, "configuration", use_profile=False,
|
||||
help=_("file sharing node configuration")
|
||||
host,
|
||||
"configuration",
|
||||
use_profile=False,
|
||||
help=_("file sharing node configuration"),
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -962,7 +974,11 @@ class SharePath(base.CommandBase):
|
|||
self.disp(f"can't share path: {e}", error=True)
|
||||
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
|
||||
else:
|
||||
self.disp(_(f'{self.path} shared under the name "{name}"'))
|
||||
self.disp(
|
||||
_('{path} shared under the name "{name}"').format(
|
||||
path=self.path, name=name
|
||||
)
|
||||
)
|
||||
self.host.quit()
|
||||
|
||||
|
||||
|
|
@ -1015,10 +1031,10 @@ class ShareInvite(base.CommandBase):
|
|||
self.path = os.path.normpath(self.args.path) if self.args.path else ""
|
||||
extra = {}
|
||||
if self.args.thumbnail is not None:
|
||||
if not self.args.thumbnail.startswith('http'):
|
||||
if not self.args.thumbnail.startswith("http"):
|
||||
self.parser.error(_("only http(s) links are allowed with --thumbnail"))
|
||||
else:
|
||||
extra['thumb_url'] = self.args.thumbnail
|
||||
extra["thumb_url"] = self.args.thumbnail
|
||||
try:
|
||||
await self.host.bridge.FISInvite(
|
||||
self.args.jid,
|
||||
|
|
@ -1034,15 +1050,18 @@ class ShareInvite(base.CommandBase):
|
|||
self.disp(f"can't send invitation: {e}", error=True)
|
||||
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
|
||||
else:
|
||||
self.disp(
|
||||
_(f'invitation sent to {self.args.jid}')
|
||||
)
|
||||
self.disp(_("invitation sent to {jid}").format(jid=self.args.jid))
|
||||
self.host.quit()
|
||||
|
||||
|
||||
class Share(base.CommandBase):
|
||||
subcommands = (
|
||||
ShareList, SharePath, ShareInvite, ShareAffiliations, ShareConfiguration)
|
||||
ShareList,
|
||||
SharePath,
|
||||
ShareInvite,
|
||||
ShareAffiliations,
|
||||
ShareConfiguration,
|
||||
)
|
||||
|
||||
def __init__(self, host):
|
||||
super(Share, self).__init__(
|
||||
|
|
|
|||
|
|
@ -28,35 +28,47 @@ __commands__ = ["Info"]
|
|||
|
||||
|
||||
class Disco(base.CommandBase):
|
||||
|
||||
def __init__(self, host):
|
||||
extra_outputs = {'default': self.default_output}
|
||||
extra_outputs = {"default": self.default_output}
|
||||
super(Disco, self).__init__(
|
||||
host, 'disco', use_output='complex', extra_outputs=extra_outputs,
|
||||
help=_('service discovery'))
|
||||
host,
|
||||
"disco",
|
||||
use_output="complex",
|
||||
extra_outputs=extra_outputs,
|
||||
help=_("service discovery"),
|
||||
)
|
||||
|
||||
def add_parser_options(self):
|
||||
self.parser.add_argument("jid", help=_("entity to discover"))
|
||||
self.parser.add_argument(
|
||||
"-t", "--type", type=str, choices=('infos', 'items', 'both'), default='both',
|
||||
help=_("type of data to discover"))
|
||||
self.parser.add_argument("-n", "--node", default='', help=_("node to use"))
|
||||
"-t",
|
||||
"--type",
|
||||
type=str,
|
||||
choices=("infos", "items", "both"),
|
||||
default="both",
|
||||
help=_("type of data to discover"),
|
||||
)
|
||||
self.parser.add_argument("-n", "--node", default="", help=_("node to use"))
|
||||
self.parser.add_argument(
|
||||
"-C", "--no-cache", dest='use_cache', action="store_false",
|
||||
help=_("ignore cache"))
|
||||
"-C",
|
||||
"--no-cache",
|
||||
dest="use_cache",
|
||||
action="store_false",
|
||||
help=_("ignore cache"),
|
||||
)
|
||||
|
||||
def default_output(self, data):
|
||||
features = data.get('features', [])
|
||||
identities = data.get('identities', [])
|
||||
extensions = data.get('extensions', {})
|
||||
items = data.get('items', [])
|
||||
features = data.get("features", [])
|
||||
identities = data.get("identities", [])
|
||||
extensions = data.get("extensions", {})
|
||||
items = data.get("items", [])
|
||||
|
||||
identities_table = common.Table(self.host,
|
||||
identities,
|
||||
headers=(_('category'),
|
||||
_('type'),
|
||||
_('name')),
|
||||
use_buffer=True)
|
||||
identities_table = common.Table(
|
||||
self.host,
|
||||
identities,
|
||||
headers=(_("category"), _("type"), _("name")),
|
||||
use_buffer=True,
|
||||
)
|
||||
|
||||
extensions_tpl = []
|
||||
extensions_types = list(extensions.keys())
|
||||
|
|
@ -69,30 +81,35 @@ class Disco(base.CommandBase):
|
|||
data_keys = list(data.keys())
|
||||
data_keys.sort()
|
||||
for key in data_keys:
|
||||
field_lines.append(A.color('\t', C.A_SUBHEADER, key, A.RESET, ': ',
|
||||
data[key]))
|
||||
field_lines.append(
|
||||
A.color("\t", C.A_SUBHEADER, key, A.RESET, ": ", data[key])
|
||||
)
|
||||
if len(values) == 1:
|
||||
field_lines.append(A.color('\t', C.A_SUBHEADER, "value", A.RESET,
|
||||
': ', values[0] or (A.BOLD + "UNSET")))
|
||||
field_lines.append(
|
||||
A.color(
|
||||
"\t",
|
||||
C.A_SUBHEADER,
|
||||
"value",
|
||||
A.RESET,
|
||||
": ",
|
||||
values[0] or (A.BOLD + "UNSET"),
|
||||
)
|
||||
)
|
||||
elif len(values) > 1:
|
||||
field_lines.append(A.color('\t', C.A_SUBHEADER, "values", A.RESET,
|
||||
': '))
|
||||
field_lines.append(
|
||||
A.color("\t", C.A_SUBHEADER, "values", A.RESET, ": ")
|
||||
)
|
||||
|
||||
for value in values:
|
||||
field_lines.append(A.color('\t - ', A.BOLD, value))
|
||||
fields.append('\n'.join(field_lines))
|
||||
extensions_tpl.append('{type_}\n{fields}'.format(
|
||||
type_=type_,
|
||||
fields='\n\n'.join(fields)))
|
||||
field_lines.append(A.color("\t - ", A.BOLD, value))
|
||||
fields.append("\n".join(field_lines))
|
||||
extensions_tpl.append(
|
||||
"{type_}\n{fields}".format(type_=type_, fields="\n\n".join(fields))
|
||||
)
|
||||
|
||||
items_table = common.Table(
|
||||
self.host,
|
||||
items,
|
||||
headers=(
|
||||
_('entity'),
|
||||
_('node'),
|
||||
_('name')),
|
||||
use_buffer=True)
|
||||
self.host, items, headers=(_("entity"), _("node"), _("name")), use_buffer=True
|
||||
)
|
||||
|
||||
template = []
|
||||
if features:
|
||||
|
|
@ -104,16 +121,18 @@ class Disco(base.CommandBase):
|
|||
if items:
|
||||
template.append(A.color(C.A_HEADER, _("Items")) + "\n\n{items}")
|
||||
|
||||
print("\n\n".join(template).format(
|
||||
features = '\n'.join(features),
|
||||
identities = identities_table.display().string,
|
||||
extensions = '\n'.join(extensions_tpl),
|
||||
items = items_table.display().string,
|
||||
))
|
||||
print(
|
||||
"\n\n".join(template).format(
|
||||
features="\n".join(features),
|
||||
identities=identities_table.display().string,
|
||||
extensions="\n".join(extensions_tpl),
|
||||
items=items_table.display().string,
|
||||
)
|
||||
)
|
||||
|
||||
async def start(self):
|
||||
infos_requested = self.args.type in ('infos', 'both')
|
||||
items_requested = self.args.type in ('items', 'both')
|
||||
infos_requested = self.args.type in ("infos", "both")
|
||||
items_requested = self.args.type in ("items", "both")
|
||||
jids = await self.host.check_jids([self.args.jid])
|
||||
jid = jids[0]
|
||||
|
||||
|
|
@ -126,13 +145,13 @@ class Disco(base.CommandBase):
|
|||
jid,
|
||||
node=self.args.node,
|
||||
use_cache=self.args.use_cache,
|
||||
profile_key=self.host.profile
|
||||
profile_key=self.host.profile,
|
||||
)
|
||||
except Exception as e:
|
||||
self.disp(_(f"error while doing discovery: {e}"), error=True)
|
||||
self.disp(_("error while doing discovery: {e}").format(e=e), error=True)
|
||||
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
|
||||
|
||||
# items
|
||||
# items
|
||||
if not items_requested:
|
||||
items = None
|
||||
else:
|
||||
|
|
@ -141,35 +160,34 @@ class Disco(base.CommandBase):
|
|||
jid,
|
||||
node=self.args.node,
|
||||
use_cache=self.args.use_cache,
|
||||
profile_key=self.host.profile
|
||||
profile_key=self.host.profile,
|
||||
)
|
||||
except Exception as e:
|
||||
self.disp(_(f"error while doing discovery: {e}"), error=True)
|
||||
self.disp(_("error while doing discovery: {e}").format(e=e), error=True)
|
||||
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
|
||||
|
||||
# output
|
||||
# output
|
||||
data = {}
|
||||
|
||||
if infos_requested:
|
||||
features, identities, extensions = infos
|
||||
features.sort()
|
||||
identities.sort(key=lambda identity: identity[2])
|
||||
data.update({
|
||||
'features': features,
|
||||
'identities': identities,
|
||||
'extensions': extensions})
|
||||
data.update(
|
||||
{"features": features, "identities": identities, "extensions": extensions}
|
||||
)
|
||||
|
||||
if items_requested:
|
||||
items.sort(key=lambda item: item[2])
|
||||
data['items'] = items
|
||||
data["items"] = items
|
||||
|
||||
await self.output(data)
|
||||
self.host.quit()
|
||||
|
||||
class Version(base.CommandBase):
|
||||
|
||||
class Version(base.CommandBase):
|
||||
def __init__(self, host):
|
||||
super(Version, self).__init__(host, 'version', help=_('software version'))
|
||||
super(Version, self).__init__(host, "version", help=_("software version"))
|
||||
|
||||
def add_parser_options(self):
|
||||
self.parser.add_argument("jid", type=str, help=_("Entity to request"))
|
||||
|
|
@ -180,45 +198,49 @@ class Version(base.CommandBase):
|
|||
try:
|
||||
data = await self.host.bridge.getSoftwareVersion(jid, self.host.profile)
|
||||
except Exception as e:
|
||||
self.disp(_(f"error while trying to get version: {e}"), error=True)
|
||||
self.disp(_("error while trying to get version: {e}").format(e=e), error=True)
|
||||
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
|
||||
else:
|
||||
infos = []
|
||||
name, version, os = data
|
||||
if name:
|
||||
infos.append(_(f"Software name: {name}"))
|
||||
infos.append(_("Software name: {name}").format(name=name))
|
||||
if version:
|
||||
infos.append(_(f"Software version: {version}"))
|
||||
infos.append(_("Software version: {version}").format(version=version))
|
||||
if os:
|
||||
infos.append(_(f"Operating System: {os}"))
|
||||
infos.append(_("Operating System: {os}").format(os=os))
|
||||
|
||||
print("\n".join(infos))
|
||||
self.host.quit()
|
||||
|
||||
|
||||
class Session(base.CommandBase):
|
||||
|
||||
def __init__(self, host):
|
||||
extra_outputs = {'default': self.default_output}
|
||||
extra_outputs = {"default": self.default_output}
|
||||
super(Session, self).__init__(
|
||||
host, 'session', use_output='dict', extra_outputs=extra_outputs,
|
||||
help=_('running session'))
|
||||
host,
|
||||
"session",
|
||||
use_output="dict",
|
||||
extra_outputs=extra_outputs,
|
||||
help=_("running session"),
|
||||
)
|
||||
|
||||
def add_parser_options(self):
|
||||
pass
|
||||
|
||||
async def default_output(self, data):
|
||||
started = data['started']
|
||||
data['started'] = '{short} (UTC, {relative})'.format(
|
||||
started = data["started"]
|
||||
data["started"] = "{short} (UTC, {relative})".format(
|
||||
short=date_utils.date_fmt(started),
|
||||
relative=date_utils.date_fmt(started, 'relative'))
|
||||
await self.host.output(C.OUTPUT_DICT, 'simple', {}, data)
|
||||
relative=date_utils.date_fmt(started, "relative"),
|
||||
)
|
||||
await self.host.output(C.OUTPUT_DICT, "simple", {}, data)
|
||||
|
||||
async def start(self):
|
||||
try:
|
||||
data = await self.host.bridge.sessionInfosGet(self.host.profile)
|
||||
except Exception as e:
|
||||
self.disp(_(f'Error getting session infos: {e}'), error=True)
|
||||
self.disp(_("Error getting session infos: {e}").format(e=e), error=True)
|
||||
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
|
||||
else:
|
||||
await self.output(data)
|
||||
|
|
@ -226,22 +248,23 @@ class Session(base.CommandBase):
|
|||
|
||||
|
||||
class Devices(base.CommandBase):
|
||||
|
||||
def __init__(self, host):
|
||||
super(Devices, self).__init__(
|
||||
host, 'devices', use_output=C.OUTPUT_LIST_DICT,
|
||||
help=_('devices of an entity'))
|
||||
host, "devices", use_output=C.OUTPUT_LIST_DICT, help=_("devices of an entity")
|
||||
)
|
||||
|
||||
def add_parser_options(self):
|
||||
self.parser.add_argument(
|
||||
"jid", type=str, nargs='?', default='', help=_("Entity to request"))
|
||||
"jid", type=str, nargs="?", default="", help=_("Entity to request")
|
||||
)
|
||||
|
||||
async def start(self):
|
||||
try:
|
||||
data = await self.host.bridge.devicesInfosGet(
|
||||
self.args.jid, self.host.profile)
|
||||
self.args.jid, self.host.profile
|
||||
)
|
||||
except Exception as e:
|
||||
self.disp(_(f'Error getting devices infos: {e}'), error=True)
|
||||
self.disp(_("Error getting devices infos: {e}").format(e=e), error=True)
|
||||
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
|
||||
else:
|
||||
data = data_format.deserialise(data, type_check=list)
|
||||
|
|
@ -254,5 +277,8 @@ class Info(base.CommandBase):
|
|||
|
||||
def __init__(self, host):
|
||||
super(Info, self).__init__(
|
||||
host, 'info', use_profile=False,
|
||||
help=_('Get various pieces of information on entities'))
|
||||
host,
|
||||
"info",
|
||||
use_profile=False,
|
||||
help=_("Get various pieces of information on entities"),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -162,9 +162,7 @@ class Get(base.CommandBase):
|
|||
)
|
||||
|
||||
def add_parser_options(self):
|
||||
self.parser.add_argument(
|
||||
"id", help=_("invitation UUID")
|
||||
)
|
||||
self.parser.add_argument("id", help=_("invitation UUID"))
|
||||
self.parser.add_argument(
|
||||
"-j",
|
||||
"--with-jid",
|
||||
|
|
@ -184,7 +182,7 @@ class Get(base.CommandBase):
|
|||
self.args.id,
|
||||
)
|
||||
except Exception as e:
|
||||
self.disp(msg=_(f"can't get invitation data: {e}"), error=True)
|
||||
self.disp(msg=_("can't get invitation data: {e}").format(e=e), error=True)
|
||||
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
|
||||
|
||||
if not self.args.with_jid:
|
||||
|
|
@ -197,7 +195,7 @@ class Get(base.CommandBase):
|
|||
profile,
|
||||
)
|
||||
except Exception as e:
|
||||
self.disp(msg=_(f"can't start session: {e}"), error=True)
|
||||
self.disp(msg=_("can't start session: {e}").format(e=e), error=True)
|
||||
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
|
||||
|
||||
try:
|
||||
|
|
@ -207,7 +205,7 @@ class Get(base.CommandBase):
|
|||
profile_key=profile,
|
||||
)
|
||||
except Exception as e:
|
||||
self.disp(msg=_(f"can't retrieve jid: {e}"), error=True)
|
||||
self.disp(msg=_("can't retrieve jid: {e}").format(e=e), error=True)
|
||||
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
|
||||
|
||||
await self.output_data(invitation_data, jid_)
|
||||
|
|
@ -224,9 +222,7 @@ class Delete(base.CommandBase):
|
|||
)
|
||||
|
||||
def add_parser_options(self):
|
||||
self.parser.add_argument(
|
||||
"id", help=_("invitation UUID")
|
||||
)
|
||||
self.parser.add_argument("id", help=_("invitation UUID"))
|
||||
|
||||
async def start(self):
|
||||
try:
|
||||
|
|
@ -234,7 +230,7 @@ class Delete(base.CommandBase):
|
|||
self.args.id,
|
||||
)
|
||||
except Exception as e:
|
||||
self.disp(msg=_(f"can't delete guest account: {e}"), error=True)
|
||||
self.disp(msg=_("can't delete guest account: {e}").format(e=e), error=True)
|
||||
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
|
||||
|
||||
self.host.quit()
|
||||
|
|
@ -290,9 +286,7 @@ class Modify(base.CommandBase):
|
|||
default="",
|
||||
help="profile doing the invitation (default: don't associate profile",
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"id", help=_("invitation UUID")
|
||||
)
|
||||
self.parser.add_argument("id", help=_("invitation UUID"))
|
||||
|
||||
async def start(self):
|
||||
extra = dict(self.args.extra)
|
||||
|
|
@ -302,7 +296,9 @@ class Modify(base.CommandBase):
|
|||
continue
|
||||
if arg_name in extra:
|
||||
self.parser.error(
|
||||
_(f"you can't set {arg_name} in both optional argument and extra")
|
||||
_(
|
||||
"you can't set {arg_name} in both optional argument and extra"
|
||||
).format(arg_name=arg_name)
|
||||
)
|
||||
extra[arg_name] = value
|
||||
try:
|
||||
|
|
@ -312,9 +308,7 @@ class Modify(base.CommandBase):
|
|||
self.args.replace,
|
||||
)
|
||||
except Exception as e:
|
||||
self.disp(
|
||||
f"can't modify invitation: {e}", error=True
|
||||
)
|
||||
self.disp(f"can't modify invitation: {e}", error=True)
|
||||
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
|
||||
else:
|
||||
self.disp(_("invitations have been modified successfuly"))
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ class Get(base.CommandBase):
|
|||
self.getPubsubExtra(),
|
||||
self.profile,
|
||||
),
|
||||
type_check=list
|
||||
type_check=list,
|
||||
)
|
||||
except Exception as e:
|
||||
self.disp(f"can't get lists: {e}", error=True)
|
||||
|
|
@ -72,7 +72,6 @@ class Get(base.CommandBase):
|
|||
|
||||
|
||||
class Set(base.CommandBase):
|
||||
|
||||
def __init__(self, host):
|
||||
base.CommandBase.__init__(
|
||||
self,
|
||||
|
|
@ -128,10 +127,10 @@ class Set(base.CommandBase):
|
|||
self.args.service,
|
||||
self.args.node,
|
||||
values,
|
||||
'',
|
||||
"",
|
||||
self.args.item,
|
||||
data_format.serialise(extra),
|
||||
self.profile
|
||||
self.profile,
|
||||
)
|
||||
except Exception as e:
|
||||
self.disp(f"can't set list item: {e}", error=True)
|
||||
|
|
@ -142,7 +141,6 @@ class Set(base.CommandBase):
|
|||
|
||||
|
||||
class Delete(base.CommandBase):
|
||||
|
||||
def __init__(self, host):
|
||||
base.CommandBase.__init__(
|
||||
self,
|
||||
|
|
@ -183,10 +181,10 @@ class Delete(base.CommandBase):
|
|||
self.profile,
|
||||
)
|
||||
except Exception as e:
|
||||
self.disp(_(f"can't delete item: {e}"), error=True)
|
||||
self.disp(_("can't delete item: {e}").format(e=e), error=True)
|
||||
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
|
||||
else:
|
||||
self.disp(_(f"item {self.args.item} has been deleted"))
|
||||
self.disp(_("item {item} has been deleted").format(item=self.args.item))
|
||||
self.host.quit(C.EXIT_OK)
|
||||
|
||||
|
||||
|
|
@ -262,7 +260,10 @@ class Import(base.CommandBase):
|
|||
self.disp(_("Tickets uploaded successfully"), 2)
|
||||
|
||||
async def onProgressError(self, error_msg):
|
||||
self.disp(_(f"Error while uploading tickets: {error_msg}"), error=True)
|
||||
self.disp(
|
||||
_("Error while uploading tickets: {error_msg}").format(error_msg=error_msg),
|
||||
error=True,
|
||||
)
|
||||
|
||||
async def start(self):
|
||||
if self.args.location is None:
|
||||
|
|
@ -270,7 +271,10 @@ class Import(base.CommandBase):
|
|||
for name in ("option", "service", "node"):
|
||||
if getattr(self.args, name):
|
||||
self.parser.error(
|
||||
_(f"{name} argument can't be used without location argument"))
|
||||
_(
|
||||
"{name} argument can't be used without location argument"
|
||||
).format(name=name)
|
||||
)
|
||||
if self.args.importer is None:
|
||||
self.disp(
|
||||
"\n".join(
|
||||
|
|
@ -297,8 +301,14 @@ class Import(base.CommandBase):
|
|||
if self.args.progress:
|
||||
# we use a custom progress bar template as we want a counter
|
||||
self.pbar_template = [
|
||||
_("Progress: "), ["Percentage"], " ", ["Bar"], " ",
|
||||
["Counter"], " ", ["ETA"]
|
||||
_("Progress: "),
|
||||
["Percentage"],
|
||||
" ",
|
||||
["Bar"],
|
||||
" ",
|
||||
["Counter"],
|
||||
" ",
|
||||
["ETA"],
|
||||
]
|
||||
|
||||
options = {key: value for key, value in self.args.option}
|
||||
|
|
@ -306,8 +316,10 @@ class Import(base.CommandBase):
|
|||
if fields_map:
|
||||
if FIELDS_MAP in options:
|
||||
self.parser.error(
|
||||
_("fields_map must be specified either preencoded in --option or "
|
||||
"using --map, but not both at the same time")
|
||||
_(
|
||||
"fields_map must be specified either preencoded in --option or "
|
||||
"using --map, but not both at the same time"
|
||||
)
|
||||
)
|
||||
options[FIELDS_MAP] = json.dumps(fields_map)
|
||||
|
||||
|
|
@ -322,7 +334,7 @@ class Import(base.CommandBase):
|
|||
)
|
||||
except Exception as e:
|
||||
self.disp(
|
||||
_(f"Error while trying to import tickets: {e}"),
|
||||
_("Error while trying to import tickets: {e}").format(e=e),
|
||||
error=True,
|
||||
)
|
||||
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@ __commands__ = ["MergeRequest"]
|
|||
|
||||
|
||||
class Set(base.CommandBase):
|
||||
|
||||
def __init__(self, host):
|
||||
base.CommandBase.__init__(
|
||||
self,
|
||||
|
|
@ -74,11 +73,12 @@ class Set(base.CommandBase):
|
|||
await common.fill_well_known_uri(self, self.repository, "merge requests")
|
||||
if not self.args.force:
|
||||
message = _(
|
||||
f"You are going to publish your changes to service "
|
||||
f"[{self.args.service}], are you sure ?"
|
||||
)
|
||||
"You are going to publish your changes to service "
|
||||
"[{service}], are you sure ?"
|
||||
).format(service=self.args.service)
|
||||
await self.host.confirmOrQuit(
|
||||
message, _("merge request publication cancelled"))
|
||||
message, _("merge request publication cancelled")
|
||||
)
|
||||
|
||||
extra = {"update": True} if self.args.item else {}
|
||||
values = {}
|
||||
|
|
@ -101,7 +101,11 @@ class Set(base.CommandBase):
|
|||
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
|
||||
|
||||
if published_id:
|
||||
self.disp(_(f"Merge request published at {published_id}"))
|
||||
self.disp(
|
||||
_("Merge request published at {published_id}").format(
|
||||
published_id=published_id
|
||||
)
|
||||
)
|
||||
else:
|
||||
self.disp(_("Merge request published"))
|
||||
|
||||
|
|
@ -125,8 +129,7 @@ class Get(base.CommandBase):
|
|||
pass
|
||||
|
||||
async def start(self):
|
||||
await common.fill_well_known_uri(
|
||||
self, os.getcwd(), "merge requests", meta_map={})
|
||||
await common.fill_well_known_uri(self, os.getcwd(), "merge requests", meta_map={})
|
||||
extra = {}
|
||||
try:
|
||||
requests_data = data_format.deserialise(
|
||||
|
|
@ -148,7 +151,7 @@ class Get(base.CommandBase):
|
|||
whitelist = None
|
||||
else:
|
||||
whitelist = {"id", "title", "body"}
|
||||
for request_xmlui in requests_data['items']:
|
||||
for request_xmlui in requests_data["items"]:
|
||||
xmlui = xmlui_manager.create(self.host, request_xmlui, whitelist=whitelist)
|
||||
await xmlui.show(values_only=True)
|
||||
self.disp("")
|
||||
|
|
@ -179,7 +182,8 @@ class Import(base.CommandBase):
|
|||
async def start(self):
|
||||
self.repository = os.path.expanduser(os.path.abspath(self.args.repository))
|
||||
await common.fill_well_known_uri(
|
||||
self, self.repository, "merge requests", meta_map={})
|
||||
self, self.repository, "merge requests", meta_map={}
|
||||
)
|
||||
extra = {}
|
||||
try:
|
||||
await self.host.bridge.mergeRequestsImport(
|
||||
|
|
|
|||
|
|
@ -22,23 +22,31 @@
|
|||
from . import base
|
||||
from sat.core.i18n import _
|
||||
from .constants import Const as C
|
||||
|
||||
__commands__ = ["Param"]
|
||||
|
||||
|
||||
class Get(base.CommandBase):
|
||||
def __init__(self, host):
|
||||
super(Get, self).__init__(
|
||||
host, 'get', need_connect=False, help=_('get a parameter value'))
|
||||
host, "get", need_connect=False, help=_("get a parameter value")
|
||||
)
|
||||
|
||||
def add_parser_options(self):
|
||||
self.parser.add_argument(
|
||||
"category", nargs='?', help=_("category of the parameter"))
|
||||
self.parser.add_argument("name", nargs='?', help=_("name of the parameter"))
|
||||
"category", nargs="?", help=_("category of the parameter")
|
||||
)
|
||||
self.parser.add_argument("name", nargs="?", help=_("name of the parameter"))
|
||||
self.parser.add_argument(
|
||||
"-a", "--attribute", type=str, default="value",
|
||||
help=_("name of the attribute to get"))
|
||||
"-a",
|
||||
"--attribute",
|
||||
type=str,
|
||||
default="value",
|
||||
help=_("name of the attribute to get"),
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"--security-limit", type=int, default=-1, help=_("security limit"))
|
||||
"--security-limit", type=int, default=-1, help=_("security limit")
|
||||
)
|
||||
|
||||
async def start(self):
|
||||
if self.args.category is None:
|
||||
|
|
@ -47,9 +55,12 @@ class Get(base.CommandBase):
|
|||
elif self.args.name is None:
|
||||
try:
|
||||
values_dict = await self.host.bridge.asyncGetParamsValuesFromCategory(
|
||||
self.args.category, self.args.security_limit, "", "", self.profile)
|
||||
self.args.category, self.args.security_limit, "", "", self.profile
|
||||
)
|
||||
except Exception as e:
|
||||
self.disp(_(f"can't find requested parameters: {e}"), error=True)
|
||||
self.disp(
|
||||
_("can't find requested parameters: {e}").format(e=e), error=True
|
||||
)
|
||||
self.host.quit(C.EXIT_NOT_FOUND)
|
||||
else:
|
||||
for name, value in values_dict.items():
|
||||
|
|
@ -57,10 +68,16 @@ class Get(base.CommandBase):
|
|||
else:
|
||||
try:
|
||||
value = await self.host.bridge.asyncGetParamA(
|
||||
self.args.name, self.args.category, self.args.attribute,
|
||||
self.args.security_limit, self.profile)
|
||||
self.args.name,
|
||||
self.args.category,
|
||||
self.args.attribute,
|
||||
self.args.security_limit,
|
||||
self.profile,
|
||||
)
|
||||
except Exception as e:
|
||||
self.disp(_(f"can't find requested parameter: {e}"), error=True)
|
||||
self.disp(
|
||||
_("can't find requested parameter: {e}").format(e=e), error=True
|
||||
)
|
||||
self.host.quit(C.EXIT_NOT_FOUND)
|
||||
else:
|
||||
print(value)
|
||||
|
|
@ -69,21 +86,29 @@ class Get(base.CommandBase):
|
|||
|
||||
class Set(base.CommandBase):
|
||||
def __init__(self, host):
|
||||
super(Set, self).__init__(host, 'set', need_connect=False, help=_('set a parameter value'))
|
||||
super(Set, self).__init__(
|
||||
host, "set", need_connect=False, help=_("set a parameter value")
|
||||
)
|
||||
|
||||
def add_parser_options(self):
|
||||
self.parser.add_argument("category", help=_("category of the parameter"))
|
||||
self.parser.add_argument("name", help=_("name of the parameter"))
|
||||
self.parser.add_argument("value", help=_("name of the parameter"))
|
||||
self.parser.add_argument("--security-limit", type=int, default=-1, help=_("security limit"))
|
||||
self.parser.add_argument(
|
||||
"--security-limit", type=int, default=-1, help=_("security limit")
|
||||
)
|
||||
|
||||
async def start(self):
|
||||
try:
|
||||
await self.host.bridge.setParam(
|
||||
self.args.name, self.args.value, self.args.category,
|
||||
self.args.security_limit, self.profile)
|
||||
self.args.name,
|
||||
self.args.value,
|
||||
self.args.category,
|
||||
self.args.security_limit,
|
||||
self.profile,
|
||||
)
|
||||
except Exception as e:
|
||||
self.disp(_(f"can't set requested parameter: {e}"), error=True)
|
||||
self.disp(_("can't set requested parameter: {e}").format(e=e), error=True)
|
||||
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
|
||||
else:
|
||||
self.host.quit()
|
||||
|
|
@ -94,8 +119,11 @@ class SaveTemplate(base.CommandBase):
|
|||
|
||||
def __init__(self, host):
|
||||
super(SaveTemplate, self).__init__(
|
||||
host, 'save', use_profile=False,
|
||||
help=_('save parameters template to xml file'))
|
||||
host,
|
||||
"save",
|
||||
use_profile=False,
|
||||
help=_("save parameters template to xml file"),
|
||||
)
|
||||
|
||||
def add_parser_options(self):
|
||||
self.parser.add_argument("filename", type=str, help=_("output file"))
|
||||
|
|
@ -105,10 +133,14 @@ class SaveTemplate(base.CommandBase):
|
|||
try:
|
||||
await self.host.bridge.saveParamsTemplate(self.args.filename)
|
||||
except Exception as e:
|
||||
self.disp(_(f"can't save parameters to file: {e}"), error=True)
|
||||
self.disp(_("can't save parameters to file: {e}").format(e=e), error=True)
|
||||
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
|
||||
else:
|
||||
self.disp(_(f"parameters saved to file {self.args.filename}"))
|
||||
self.disp(
|
||||
_("parameters saved to file {filename}").format(
|
||||
filename=self.args.filename
|
||||
)
|
||||
)
|
||||
self.host.quit()
|
||||
|
||||
|
||||
|
|
@ -117,8 +149,11 @@ class LoadTemplate(base.CommandBase):
|
|||
|
||||
def __init__(self, host):
|
||||
super(LoadTemplate, self).__init__(
|
||||
host, 'load', use_profile=False,
|
||||
help=_('load parameters template from xml file'))
|
||||
host,
|
||||
"load",
|
||||
use_profile=False,
|
||||
help=_("load parameters template from xml file"),
|
||||
)
|
||||
|
||||
def add_parser_options(self):
|
||||
self.parser.add_argument("filename", type=str, help=_("input file"))
|
||||
|
|
@ -128,10 +163,14 @@ class LoadTemplate(base.CommandBase):
|
|||
try:
|
||||
self.host.bridge.loadParamsTemplate(self.args.filename)
|
||||
except Exception as e:
|
||||
self.disp(_(f"can't load parameters from file: {e}"), error=True)
|
||||
self.disp(_("can't load parameters from file: {e}").format(e=e), error=True)
|
||||
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
|
||||
else:
|
||||
self.disp(_(f"parameters loaded from file {self.args.filename}"))
|
||||
self.disp(
|
||||
_("parameters loaded from file {filename}").format(
|
||||
filename=self.args.filename
|
||||
)
|
||||
)
|
||||
self.host.quit()
|
||||
|
||||
|
||||
|
|
@ -139,4 +178,6 @@ class Param(base.CommandBase):
|
|||
subcommands = (Get, Set, SaveTemplate, LoadTemplate)
|
||||
|
||||
def __init__(self, host):
|
||||
super(Param, self).__init__(host, 'param', use_profile=False, help=_('Save/load parameters template'))
|
||||
super(Param, self).__init__(
|
||||
host, "param", use_profile=False, help=_("Save/load parameters template")
|
||||
)
|
||||
|
|
|
|||
|
|
@ -25,14 +25,11 @@ __commands__ = ["Ping"]
|
|||
|
||||
|
||||
class Ping(base.CommandBase):
|
||||
|
||||
def __init__(self, host):
|
||||
super(Ping, self).__init__(host, 'ping', help=_('ping XMPP entity'))
|
||||
super(Ping, self).__init__(host, "ping", help=_("ping XMPP entity"))
|
||||
|
||||
def add_parser_options(self):
|
||||
self.parser.add_argument(
|
||||
"jid", help=_("jid to ping")
|
||||
)
|
||||
self.parser.add_argument("jid", help=_("jid to ping"))
|
||||
self.parser.add_argument(
|
||||
"-d", "--delay-only", action="store_true", help=_("output delay only (in s)")
|
||||
)
|
||||
|
|
@ -41,9 +38,9 @@ class Ping(base.CommandBase):
|
|||
try:
|
||||
pong_time = await self.host.bridge.ping(self.args.jid, self.profile)
|
||||
except Exception as e:
|
||||
self.disp(msg=_(f"can't do the ping: {e}"), error=True)
|
||||
self.disp(msg=_("can't do the ping: {e}").format(e=e), error=True)
|
||||
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
|
||||
else:
|
||||
msg = pong_time if self.args.delay_only else f"PONG ({pong_time} s)"
|
||||
msg = pong_time if self.args.delay_only else f"PONG ({pong_time} s)"
|
||||
self.disp(msg)
|
||||
self.host.quit()
|
||||
|
|
|
|||
|
|
@ -82,10 +82,10 @@ class NodeInfo(base.CommandBase):
|
|||
self.profile,
|
||||
)
|
||||
except BridgeException as e:
|
||||
if e.condition == 'item-not-found':
|
||||
if e.condition == "item-not-found":
|
||||
self.disp(
|
||||
f"The node {self.args.node} doesn't exist on {self.args.service}",
|
||||
error=True
|
||||
error=True,
|
||||
)
|
||||
self.host.quit(C.EXIT_NOT_FOUND)
|
||||
else:
|
||||
|
|
@ -155,7 +155,7 @@ class NodeCreate(base.CommandBase):
|
|||
self.profile,
|
||||
)
|
||||
except Exception as e:
|
||||
self.disp(msg=_(f"can't create node: {e}"), error=True)
|
||||
self.disp(msg=_("can't create node: {e}").format(e=e), error=True)
|
||||
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
|
||||
else:
|
||||
if self.host.verbosity:
|
||||
|
|
@ -167,7 +167,6 @@ class NodeCreate(base.CommandBase):
|
|||
|
||||
|
||||
class NodePurge(base.CommandBase):
|
||||
|
||||
def __init__(self, host):
|
||||
super(NodePurge, self).__init__(
|
||||
host,
|
||||
|
|
@ -189,12 +188,14 @@ class NodePurge(base.CommandBase):
|
|||
if not self.args.force:
|
||||
if not self.args.service:
|
||||
message = _(
|
||||
f"Are you sure to purge PEP node [{self.args.node}]? This will "
|
||||
f"delete ALL items from it!")
|
||||
"Are you sure to purge PEP node [{node}]? This will "
|
||||
"delete ALL items from it!"
|
||||
).format(node=self.args.node)
|
||||
else:
|
||||
message = _(
|
||||
f"Are you sure to delete node [{self.args.node}] on service "
|
||||
f"[{self.args.service}]? This will delete ALL items from it!")
|
||||
"Are you sure to delete node [{node}] on service "
|
||||
"[{service}]? This will delete ALL items from it!"
|
||||
).format(node=self.args.node, service=self.args.service)
|
||||
await self.host.confirmOrQuit(message, _("node purge cancelled"))
|
||||
|
||||
try:
|
||||
|
|
@ -204,10 +205,10 @@ class NodePurge(base.CommandBase):
|
|||
self.profile,
|
||||
)
|
||||
except Exception as e:
|
||||
self.disp(msg=_(f"can't purge node: {e}"), error=True)
|
||||
self.disp(msg=_("can't purge node: {e}").format(e=e), error=True)
|
||||
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
|
||||
else:
|
||||
self.disp(_(f"node [{self.args.node}] purged successfully"))
|
||||
self.disp(_("node [{node}] purged successfully").format(node=self.args.node))
|
||||
self.host.quit()
|
||||
|
||||
|
||||
|
|
@ -233,10 +234,13 @@ class NodeDelete(base.CommandBase):
|
|||
async def start(self):
|
||||
if not self.args.force:
|
||||
if not self.args.service:
|
||||
message = _(f"Are you sure to delete PEP node [{self.args.node}] ?")
|
||||
message = _("Are you sure to delete PEP node [{node}] ?").format(
|
||||
node=self.args.node
|
||||
)
|
||||
else:
|
||||
message = _(f"Are you sure to delete node [{self.args.node}] on "
|
||||
f"service [{self.args.service}]?")
|
||||
message = _(
|
||||
"Are you sure to delete node [{node}] on " "service [{service}]?"
|
||||
).format(node=self.args.node, service=self.args.service)
|
||||
await self.host.confirmOrQuit(message, _("node deletion cancelled"))
|
||||
|
||||
try:
|
||||
|
|
@ -249,7 +253,7 @@ class NodeDelete(base.CommandBase):
|
|||
self.disp(f"can't delete node: {e}", error=True)
|
||||
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
|
||||
else:
|
||||
self.disp(_(f"node [{self.args.node}] deleted successfully"))
|
||||
self.disp(_("node [{node}] deleted successfully").format(node=self.args.node))
|
||||
self.host.quit()
|
||||
|
||||
|
||||
|
|
@ -307,7 +311,6 @@ class NodeSet(base.CommandBase):
|
|||
|
||||
|
||||
class NodeImport(base.CommandBase):
|
||||
|
||||
def __init__(self, host):
|
||||
super(NodeImport, self).__init__(
|
||||
host,
|
||||
|
|
@ -326,16 +329,20 @@ class NodeImport(base.CommandBase):
|
|||
self.parser.add_argument(
|
||||
"import_file",
|
||||
type=argparse.FileType(),
|
||||
help=_("path to the XML file with data to import. The file must contain "
|
||||
"whole XML of each item to import."),
|
||||
help=_(
|
||||
"path to the XML file with data to import. The file must contain "
|
||||
"whole XML of each item to import."
|
||||
),
|
||||
)
|
||||
|
||||
async def start(self):
|
||||
try:
|
||||
element, etree = xml_tools.etreeParse(self, self.args.import_file,
|
||||
reraise=True)
|
||||
element, etree = xml_tools.etreeParse(
|
||||
self, self.args.import_file, reraise=True
|
||||
)
|
||||
except Exception as e:
|
||||
from lxml.etree import XMLSyntaxError
|
||||
|
||||
if isinstance(e, XMLSyntaxError) and e.code == 5:
|
||||
# we have extra content, this probaby means that item are not wrapped
|
||||
# so we wrap them here and try again
|
||||
|
|
@ -343,14 +350,15 @@ class NodeImport(base.CommandBase):
|
|||
xml_buf = "<import>" + self.args.import_file.read() + "</import>"
|
||||
element, etree = xml_tools.etreeParse(self, xml_buf)
|
||||
|
||||
# we reverse element as we expect to have most recently published element first
|
||||
# TODO: make this more explicit and add an option
|
||||
# we reverse element as we expect to have most recently published element first
|
||||
# TODO: make this more explicit and add an option
|
||||
element[:] = reversed(element)
|
||||
|
||||
if not all([i.tag == '{http://jabber.org/protocol/pubsub}item' for i in element]):
|
||||
if not all([i.tag == "{http://jabber.org/protocol/pubsub}item" for i in element]):
|
||||
self.disp(
|
||||
_("You are not using list of pubsub items, we can't import this file"),
|
||||
error=True)
|
||||
error=True,
|
||||
)
|
||||
self.host.quit(C.EXIT_DATA_ERROR)
|
||||
return
|
||||
|
||||
|
|
@ -358,8 +366,12 @@ class NodeImport(base.CommandBase):
|
|||
if self.args.admin:
|
||||
method = self.host.bridge.psAdminItemsSend
|
||||
else:
|
||||
self.disp(_("Items are imported without using admin mode, publisher can't "
|
||||
"be changed"))
|
||||
self.disp(
|
||||
_(
|
||||
"Items are imported without using admin mode, publisher can't "
|
||||
"be changed"
|
||||
)
|
||||
)
|
||||
method = self.host.bridge.psItemsSend
|
||||
|
||||
try:
|
||||
|
|
@ -375,10 +387,13 @@ class NodeImport(base.CommandBase):
|
|||
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
|
||||
else:
|
||||
if items_ids:
|
||||
self.disp(_('items published with id(s) {items_ids}').format(
|
||||
items_ids=', '.join(items_ids)))
|
||||
self.disp(
|
||||
_("items published with id(s) {items_ids}").format(
|
||||
items_ids=", ".join(items_ids)
|
||||
)
|
||||
)
|
||||
else:
|
||||
self.disp(_('items published'))
|
||||
self.disp(_("items published"))
|
||||
self.host.quit()
|
||||
|
||||
|
||||
|
|
@ -645,8 +660,9 @@ class NodeSchemaEdit(base.CommandBase, common.BaseEdit):
|
|||
try:
|
||||
from lxml import etree
|
||||
except ImportError:
|
||||
self.disp('lxml module must be installed to use edit, please install it '
|
||||
'with "pip install lxml"',
|
||||
self.disp(
|
||||
"lxml module must be installed to use edit, please install it "
|
||||
'with "pip install lxml"',
|
||||
error=True,
|
||||
)
|
||||
self.host.quit(1)
|
||||
|
|
@ -659,7 +675,9 @@ class NodeSchemaEdit(base.CommandBase, common.BaseEdit):
|
|||
etree.tostring(schema_elt, encoding="utf-8", pretty_print=True)
|
||||
)
|
||||
content_file_obj.seek(0)
|
||||
await self.runEditor("pubsub_schema_editor_args", content_file_path, content_file_obj)
|
||||
await self.runEditor(
|
||||
"pubsub_schema_editor_args", content_file_path, content_file_obj
|
||||
)
|
||||
|
||||
async def start(self):
|
||||
try:
|
||||
|
|
@ -669,7 +687,7 @@ class NodeSchemaEdit(base.CommandBase, common.BaseEdit):
|
|||
self.profile,
|
||||
)
|
||||
except BridgeException as e:
|
||||
if e.condition == 'item-not-found' or e.classname=="NotFound":
|
||||
if e.condition == "item-not-found" or e.classname == "NotFound":
|
||||
schema = ""
|
||||
else:
|
||||
self.disp(f"can't edit schema: {e}", error=True)
|
||||
|
|
@ -702,7 +720,7 @@ class NodeSchemaGet(base.CommandBase):
|
|||
self.profile,
|
||||
)
|
||||
except BridgeException as e:
|
||||
if e.condition == 'item-not-found' or e.classname=="NotFound":
|
||||
if e.condition == "item-not-found" or e.classname == "NotFound":
|
||||
schema = None
|
||||
else:
|
||||
self.disp(f"can't get schema: {e}", error=True)
|
||||
|
|
@ -772,7 +790,7 @@ class Set(base.CommandBase):
|
|||
extra = {}
|
||||
publish_options = NodeCreate.get_config_options(self.args)
|
||||
if publish_options:
|
||||
extra['publish_options'] = publish_options
|
||||
extra["publish_options"] = publish_options
|
||||
|
||||
try:
|
||||
published_id = await self.host.bridge.psItemSend(
|
||||
|
|
@ -784,12 +802,12 @@ class Set(base.CommandBase):
|
|||
self.profile,
|
||||
)
|
||||
except Exception as e:
|
||||
self.disp(_(f"can't send item: {e}"), error=True)
|
||||
self.disp(_("can't send item: {e}").format(e=e), error=True)
|
||||
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
|
||||
else:
|
||||
if published_id:
|
||||
if self.args.quiet:
|
||||
self.disp(published_id, end='')
|
||||
self.disp(published_id, end="")
|
||||
else:
|
||||
self.disp(f"Item published at {published_id}")
|
||||
else:
|
||||
|
|
@ -833,10 +851,10 @@ class Get(base.CommandBase):
|
|||
)
|
||||
)
|
||||
except BridgeException as e:
|
||||
if e.condition == 'item-not-found' or e.classname=="NotFound":
|
||||
if e.condition == "item-not-found" or e.classname == "NotFound":
|
||||
self.disp(
|
||||
f"The node {self.args.node} doesn't exist on {self.args.service}",
|
||||
error=True
|
||||
error=True,
|
||||
)
|
||||
self.host.quit(C.EXIT_NOT_FOUND)
|
||||
else:
|
||||
|
|
@ -846,7 +864,7 @@ class Get(base.CommandBase):
|
|||
self.disp(f"Internal error: {e}", error=True)
|
||||
self.host.quit(C.EXIT_INTERNAL_ERROR)
|
||||
else:
|
||||
await self.output(ps_result['items'])
|
||||
await self.output(ps_result["items"])
|
||||
self.host.quit(C.EXIT_OK)
|
||||
|
||||
|
||||
|
|
@ -886,10 +904,10 @@ class Delete(base.CommandBase):
|
|||
self.profile,
|
||||
)
|
||||
except Exception as e:
|
||||
self.disp(_(f"can't delete item: {e}"), error=True)
|
||||
self.disp(_("can't delete item: {e}").format(e=e), error=True)
|
||||
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
|
||||
else:
|
||||
self.disp(_(f"item {self.args.item} has been deleted"))
|
||||
self.disp(_("item {item} has been deleted").format(item=self.args.item))
|
||||
self.host.quit(C.EXIT_OK)
|
||||
|
||||
|
||||
|
|
@ -928,8 +946,9 @@ class Edit(base.CommandBase, common.BaseEdit):
|
|||
try:
|
||||
from lxml import etree
|
||||
except ImportError:
|
||||
self.disp('lxml module must be installed to use edit, please install it '
|
||||
'with "pip install lxml"',
|
||||
self.disp(
|
||||
"lxml module must be installed to use edit, please install it "
|
||||
'with "pip install lxml"',
|
||||
error=True,
|
||||
)
|
||||
self.host.quit(1)
|
||||
|
|
@ -939,7 +958,7 @@ class Edit(base.CommandBase, common.BaseEdit):
|
|||
service, node, 1, items, "", {}, self.profile
|
||||
)
|
||||
)
|
||||
item_raw = ps_result['items'][0]
|
||||
item_raw = ps_result["items"][0]
|
||||
parser = etree.XMLParser(remove_blank_text=True, recover=True)
|
||||
item_elt = etree.fromstring(item_raw, parser)
|
||||
item_id = item_elt.get("id")
|
||||
|
|
@ -951,17 +970,18 @@ class Edit(base.CommandBase, common.BaseEdit):
|
|||
return etree.tostring(payload, encoding="unicode", pretty_print=True), item_id
|
||||
|
||||
async def start(self):
|
||||
(self.pubsub_service,
|
||||
self.pubsub_node,
|
||||
self.pubsub_item,
|
||||
content_file_path,
|
||||
content_file_obj) = await self.getItemPath()
|
||||
(
|
||||
self.pubsub_service,
|
||||
self.pubsub_node,
|
||||
self.pubsub_item,
|
||||
content_file_path,
|
||||
content_file_obj,
|
||||
) = await self.getItemPath()
|
||||
await self.runEditor("pubsub_editor_args", content_file_path, content_file_obj)
|
||||
self.host.quit()
|
||||
|
||||
|
||||
class Rename(base.CommandBase):
|
||||
|
||||
def __init__(self, host):
|
||||
base.CommandBase.__init__(
|
||||
self,
|
||||
|
|
@ -973,10 +993,7 @@ class Rename(base.CommandBase):
|
|||
)
|
||||
|
||||
def add_parser_options(self):
|
||||
self.parser.add_argument(
|
||||
"new_id",
|
||||
help=_("new item id to use")
|
||||
)
|
||||
self.parser.add_argument("new_id", help=_("new item id to use"))
|
||||
|
||||
async def start(self):
|
||||
try:
|
||||
|
|
@ -988,9 +1005,7 @@ class Rename(base.CommandBase):
|
|||
self.profile,
|
||||
)
|
||||
except Exception as e:
|
||||
self.disp(
|
||||
f"can't rename item: {e}", error=True
|
||||
)
|
||||
self.disp(f"can't rename item: {e}", error=True)
|
||||
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
|
||||
else:
|
||||
self.disp("Item renamed")
|
||||
|
|
@ -1021,7 +1036,7 @@ class Subscribe(base.CommandBase):
|
|||
self.profile,
|
||||
)
|
||||
except Exception as e:
|
||||
self.disp(_(f"can't subscribe to node: {e}"), error=True)
|
||||
self.disp(_("can't subscribe to node: {e}").format(e=e), error=True)
|
||||
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
|
||||
else:
|
||||
self.disp(_("subscription done"), 1)
|
||||
|
|
@ -1055,7 +1070,7 @@ class Unsubscribe(base.CommandBase):
|
|||
self.profile,
|
||||
)
|
||||
except Exception as e:
|
||||
self.disp(_(f"can't unsubscribe from node: {e}"), error=True)
|
||||
self.disp(_("can't unsubscribe from node: {e}").format(e=e), error=True)
|
||||
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
|
||||
else:
|
||||
self.disp(_("subscription removed"), 1)
|
||||
|
|
@ -1084,7 +1099,7 @@ class Subscriptions(base.CommandBase):
|
|||
self.profile,
|
||||
)
|
||||
except Exception as e:
|
||||
self.disp(_(f"can't retrieve subscriptions: {e}"), error=True)
|
||||
self.disp(_("can't retrieve subscriptions: {e}").format(e=e), error=True)
|
||||
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
|
||||
else:
|
||||
await self.output(subscriptions)
|
||||
|
|
@ -1113,9 +1128,7 @@ class Affiliations(base.CommandBase):
|
|||
self.profile,
|
||||
)
|
||||
except Exception as e:
|
||||
self.disp(
|
||||
f"can't get node affiliations: {e}", error=True
|
||||
)
|
||||
self.disp(f"can't get node affiliations: {e}", error=True)
|
||||
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
|
||||
else:
|
||||
await self.output(affiliations)
|
||||
|
|
@ -1169,16 +1182,20 @@ class Search(base.CommandBase):
|
|||
"--max-depth",
|
||||
type=int,
|
||||
default=0,
|
||||
help=_("maximum depth of recursion (will search linked nodes if > 0, "
|
||||
"DEFAULT: 0)"),
|
||||
help=_(
|
||||
"maximum depth of recursion (will search linked nodes if > 0, "
|
||||
"DEFAULT: 0)"
|
||||
),
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"-M",
|
||||
"--node-max",
|
||||
type=int,
|
||||
default=30,
|
||||
help=_("maximum number of items to get per node ({} to get all items, "
|
||||
"DEFAULT: 30)".format( C.NO_LIMIT)),
|
||||
help=_(
|
||||
"maximum number of items to get per node ({} to get all items, "
|
||||
"DEFAULT: 30)".format(C.NO_LIMIT)
|
||||
),
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"-N",
|
||||
|
|
@ -1233,9 +1250,10 @@ class Search(base.CommandBase):
|
|||
dest="filters",
|
||||
type=filter_python,
|
||||
metavar="PYTHON_CODE",
|
||||
help=_('Python expression which much return a bool (True to keep item, '
|
||||
'False to reject it). "item" is raw text item, "item_xml" is '
|
||||
'lxml\'s etree.Element'
|
||||
help=_(
|
||||
"Python expression which much return a bool (True to keep item, "
|
||||
'False to reject it). "item" is raw text item, "item_xml" is '
|
||||
"lxml's etree.Element"
|
||||
),
|
||||
)
|
||||
|
||||
|
|
@ -1362,8 +1380,10 @@ class Search(base.CommandBase):
|
|||
return self.etree.fromstring(item)
|
||||
except self.etree.XMLSyntaxError:
|
||||
self.disp(
|
||||
_("item doesn't looks like XML, you have probably used --only-matching "
|
||||
"somewhere before and we have no more XML"),
|
||||
_(
|
||||
"item doesn't looks like XML, you have probably used --only-matching "
|
||||
"somewhere before and we have no more XML"
|
||||
),
|
||||
error=True,
|
||||
)
|
||||
self.host.quit(C.EXIT_BAD_ARG)
|
||||
|
|
@ -1397,9 +1417,7 @@ class Search(base.CommandBase):
|
|||
# doesn't really make sens to keep a fixed string
|
||||
# so we raise an error
|
||||
self.host.disp(
|
||||
_(
|
||||
"--only-matching used with fixed --text string, are you sure?"
|
||||
),
|
||||
_("--only-matching used with fixed --text string, are you sure?"),
|
||||
error=True,
|
||||
)
|
||||
self.host.quit(C.EXIT_BAD_ARG)
|
||||
|
|
@ -1420,9 +1438,7 @@ class Search(base.CommandBase):
|
|||
try:
|
||||
elts = item_xml.xpath(value, namespaces=self.args.namespace)
|
||||
except self.etree.XPathEvalError as e:
|
||||
self.disp(
|
||||
_("can't use xpath: {reason}").format(reason=e), error=True
|
||||
)
|
||||
self.disp(_("can't use xpath: {reason}").format(reason=e), error=True)
|
||||
self.host.quit(C.EXIT_BAD_ARG)
|
||||
keep = bool(elts)
|
||||
if keep and only_matching:
|
||||
|
|
@ -1436,18 +1452,14 @@ class Search(base.CommandBase):
|
|||
elif type_ == "python":
|
||||
if item_xml is None:
|
||||
item_xml = self.parseXml(item)
|
||||
cmd_ns = {
|
||||
"etree": self.etree,
|
||||
"item": item,
|
||||
"item_xml": item_xml
|
||||
}
|
||||
cmd_ns = {"etree": self.etree, "item": item, "item_xml": item_xml}
|
||||
try:
|
||||
keep = eval(value, cmd_ns)
|
||||
except SyntaxError as e:
|
||||
self.disp(str(e), error=True)
|
||||
self.host.quit(C.EXIT_BAD_ARG)
|
||||
|
||||
## flags
|
||||
## flags
|
||||
|
||||
elif type_ == "ignore-case":
|
||||
ignore_case = value
|
||||
|
|
@ -1512,15 +1524,14 @@ class Search(base.CommandBase):
|
|||
p = await asyncio.create_subprocess_exec(*cmd_args)
|
||||
ret = await p.wait()
|
||||
else:
|
||||
p = await asyncio.create_subprocess_exec(*cmd_args,
|
||||
stdin=subprocess.PIPE)
|
||||
p = await asyncio.create_subprocess_exec(*cmd_args, stdin=subprocess.PIPE)
|
||||
await p.communicate(item.encode(sys.getfilesystemencoding()))
|
||||
ret = p.returncode
|
||||
if ret != 0:
|
||||
self.disp(
|
||||
A.color(
|
||||
C.A_FAILURE,
|
||||
_(f"executed command failed with exit code {ret}"),
|
||||
_("executed command failed with exit code {ret}").format(ret=ret),
|
||||
)
|
||||
)
|
||||
|
||||
|
|
@ -1533,7 +1544,7 @@ class Search(base.CommandBase):
|
|||
@param depth(int): current depth level
|
||||
0 for first node, 1 for first children, and so on
|
||||
"""
|
||||
for item in ps_result['items']:
|
||||
for item in ps_result["items"]:
|
||||
if depth < self.args.max_depth:
|
||||
await self.getSubNodes(item, depth)
|
||||
keep, item = self.filter(item)
|
||||
|
|
@ -1541,7 +1552,7 @@ class Search(base.CommandBase):
|
|||
continue
|
||||
await self.doItemAction(item, ps_result)
|
||||
|
||||
# we check if we got all getItems results
|
||||
# we check if we got all getItems results
|
||||
self.to_get -= 1
|
||||
if self.to_get == 0:
|
||||
# yes, we can quit
|
||||
|
|
@ -1562,8 +1573,8 @@ class Search(base.CommandBase):
|
|||
if not self.args.node:
|
||||
# TODO: handle get service affiliations when node is not set
|
||||
self.parser.error(_("empty node is not handled yet"))
|
||||
# to_get is increased on each get and decreased on each answer
|
||||
# when it reach 0 again, the command is finished
|
||||
# to_get is increased on each get and decreased on each answer
|
||||
# when it reach 0 again, the command is finished
|
||||
self.to_get = 0
|
||||
self._etree = None
|
||||
if self.args.filters is None:
|
||||
|
|
@ -1601,27 +1612,33 @@ class Transform(base.CommandBase):
|
|||
"--ignore-errors",
|
||||
action="store_true",
|
||||
help=_(
|
||||
"if command return a non zero exit code, ignore the item and continue"),
|
||||
"if command return a non zero exit code, ignore the item and continue"
|
||||
),
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"-A",
|
||||
"--all",
|
||||
action="store_true",
|
||||
help=_("get all items by looping over all pages using RSM")
|
||||
help=_("get all items by looping over all pages using RSM"),
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"command_path",
|
||||
help=_("path to the command to use. Will be called repetitivly with an "
|
||||
"item as input. Output (full item XML) will be used as new one. "
|
||||
'Return "DELETE" string to delete the item, and "SKIP" to ignore it'),
|
||||
help=_(
|
||||
"path to the command to use. Will be called repetitivly with an "
|
||||
"item as input. Output (full item XML) will be used as new one. "
|
||||
'Return "DELETE" string to delete the item, and "SKIP" to ignore it'
|
||||
),
|
||||
)
|
||||
|
||||
async def psItemsSendCb(self, item_ids, metadata):
|
||||
if item_ids:
|
||||
self.disp(_('items published with ids {item_ids}').format(
|
||||
item_ids=', '.join(item_ids)))
|
||||
self.disp(
|
||||
_("items published with ids {item_ids}").format(
|
||||
item_ids=", ".join(item_ids)
|
||||
)
|
||||
)
|
||||
else:
|
||||
self.disp(_('items published'))
|
||||
self.disp(_("items published"))
|
||||
if self.args.all:
|
||||
return await self.handleNextPage(metadata)
|
||||
else:
|
||||
|
|
@ -1634,30 +1651,34 @@ class Transform(base.CommandBase):
|
|||
@param metadata(dict): metadata as returned by psItemsGet
|
||||
"""
|
||||
try:
|
||||
last = metadata['rsm']['last']
|
||||
index = int(metadata['rsm']['index'])
|
||||
count = int(metadata['rsm']['count'])
|
||||
last = metadata["rsm"]["last"]
|
||||
index = int(metadata["rsm"]["index"])
|
||||
count = int(metadata["rsm"]["count"])
|
||||
except KeyError:
|
||||
self.disp(_("Can't retrieve all items, RSM metadata not available"),
|
||||
error=True)
|
||||
self.disp(
|
||||
_("Can't retrieve all items, RSM metadata not available"), error=True
|
||||
)
|
||||
self.host.quit(C.EXIT_MISSING_FEATURE)
|
||||
except ValueError as e:
|
||||
self.disp(_("Can't retrieve all items, bad RSM metadata: {msg}")
|
||||
.format(msg=e), error=True)
|
||||
self.disp(
|
||||
_("Can't retrieve all items, bad RSM metadata: {msg}").format(msg=e),
|
||||
error=True,
|
||||
)
|
||||
self.host.quit(C.EXIT_ERROR)
|
||||
|
||||
if index + self.args.rsm_max >= count:
|
||||
self.disp(_('All items transformed'))
|
||||
self.disp(_("All items transformed"))
|
||||
self.host.quit(0)
|
||||
|
||||
self.disp(_('Retrieving next page ({page_idx}/{page_total})').format(
|
||||
page_idx = int(index/self.args.rsm_max) + 1,
|
||||
page_total = int(count/self.args.rsm_max),
|
||||
self.disp(
|
||||
_("Retrieving next page ({page_idx}/{page_total})").format(
|
||||
page_idx=int(index / self.args.rsm_max) + 1,
|
||||
page_total=int(count / self.args.rsm_max),
|
||||
)
|
||||
)
|
||||
|
||||
extra = self.getPubsubExtra()
|
||||
extra['rsm_after'] = last
|
||||
extra["rsm_after"] = last
|
||||
try:
|
||||
ps_result = await data_format.deserialise(
|
||||
self.host.bridge.psItemsGet(
|
||||
|
|
@ -1671,36 +1692,36 @@ class Transform(base.CommandBase):
|
|||
)
|
||||
)
|
||||
except Exception as e:
|
||||
self.disp(
|
||||
f"can't retrieve items: {e}", error=True
|
||||
)
|
||||
self.disp(f"can't retrieve items: {e}", error=True)
|
||||
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
|
||||
else:
|
||||
await self.psItemsGetCb(ps_result)
|
||||
|
||||
async def psItemsGetCb(self, ps_result):
|
||||
encoding = 'utf-8'
|
||||
encoding = "utf-8"
|
||||
new_items = []
|
||||
|
||||
for item in ps_result['items']:
|
||||
for item in ps_result["items"]:
|
||||
if self.check_duplicates:
|
||||
# this is used when we are not ordering by creation
|
||||
# to avoid infinite loop
|
||||
item_elt, __ = xml_tools.etreeParse(self, item)
|
||||
item_id = item_elt.get('id')
|
||||
item_id = item_elt.get("id")
|
||||
if item_id in self.items_ids:
|
||||
self.disp(_(
|
||||
"Duplicate found on item {item_id}, we have probably handled "
|
||||
"all items.").format(item_id=item_id))
|
||||
self.disp(
|
||||
_(
|
||||
"Duplicate found on item {item_id}, we have probably handled "
|
||||
"all items."
|
||||
).format(item_id=item_id)
|
||||
)
|
||||
self.host.quit()
|
||||
self.items_ids.append(item_id)
|
||||
|
||||
# we launch the command to filter the item
|
||||
# we launch the command to filter the item
|
||||
try:
|
||||
p = await asyncio.create_subprocess_exec(
|
||||
self.args.command_path,
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE)
|
||||
self.args.command_path, stdin=subprocess.PIPE, stdout=subprocess.PIPE
|
||||
)
|
||||
except OSError as e:
|
||||
exit_code = C.EXIT_CMD_NOT_FOUND if e.errno == 2 else C.EXIT_ERROR
|
||||
self.disp(f"Can't execute the command: {e}", error=True)
|
||||
|
|
@ -1709,20 +1730,23 @@ class Transform(base.CommandBase):
|
|||
cmd_std_out, cmd_std_err = await p.communicate(item.encode(encoding))
|
||||
ret = p.returncode
|
||||
if ret != 0:
|
||||
self.disp(f"The command returned a non zero status while parsing the "
|
||||
f"following item:\n\n{item}", error=True)
|
||||
self.disp(
|
||||
f"The command returned a non zero status while parsing the "
|
||||
f"following item:\n\n{item}",
|
||||
error=True,
|
||||
)
|
||||
if self.args.ignore_errors:
|
||||
continue
|
||||
else:
|
||||
self.host.quit(C.EXIT_CMD_ERROR)
|
||||
if cmd_std_err is not None:
|
||||
cmd_std_err = cmd_std_err.decode(encoding, errors='ignore')
|
||||
cmd_std_err = cmd_std_err.decode(encoding, errors="ignore")
|
||||
self.disp(cmd_std_err, error=True)
|
||||
cmd_std_out = cmd_std_out.decode(encoding).strip()
|
||||
if cmd_std_out == "DELETE":
|
||||
item_elt, __ = xml_tools.etreeParse(self, item)
|
||||
item_id = item_elt.get('id')
|
||||
self.disp(_(f"Deleting item {item_id}"))
|
||||
item_id = item_elt.get("id")
|
||||
self.disp(_("Deleting item {item_id}").format(item_id=item_id))
|
||||
if self.args.apply:
|
||||
try:
|
||||
await self.host.bridge.psItemRetract(
|
||||
|
|
@ -1733,28 +1757,31 @@ class Transform(base.CommandBase):
|
|||
self.profile,
|
||||
)
|
||||
except Exception as e:
|
||||
self.disp(
|
||||
f"can't delete item {item_id}: {e}", error=True
|
||||
)
|
||||
self.disp(f"can't delete item {item_id}: {e}", error=True)
|
||||
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
|
||||
continue
|
||||
elif cmd_std_out == "SKIP":
|
||||
item_elt, __ = xml_tools.etreeParse(self, item)
|
||||
item_id = item_elt.get('id')
|
||||
item_id = item_elt.get("id")
|
||||
self.disp(_("Skipping item {item_id}").format(item_id=item_id))
|
||||
continue
|
||||
element, etree = xml_tools.etreeParse(self, cmd_std_out)
|
||||
|
||||
# at this point command has been run and we have a etree.Element object
|
||||
if element.tag not in ("item", "{http://jabber.org/protocol/pubsub}item"):
|
||||
self.disp("your script must return a whole item, this is not:\n{xml}"
|
||||
.format(xml=etree.tostring(element, encoding="unicode")), error=True)
|
||||
self.disp(
|
||||
"your script must return a whole item, this is not:\n{xml}".format(
|
||||
xml=etree.tostring(element, encoding="unicode")
|
||||
),
|
||||
error=True,
|
||||
)
|
||||
self.host.quit(C.EXIT_DATA_ERROR)
|
||||
|
||||
if not self.args.apply:
|
||||
# we have a dry run, we just display filtered items
|
||||
serialised = etree.tostring(element, encoding='unicode',
|
||||
pretty_print=True)
|
||||
serialised = etree.tostring(
|
||||
element, encoding="unicode", pretty_print=True
|
||||
)
|
||||
self.disp(serialised)
|
||||
else:
|
||||
new_items.append(etree.tostring(element, encoding="unicode"))
|
||||
|
|
@ -1788,13 +1815,17 @@ class Transform(base.CommandBase):
|
|||
if self.args.all and self.args.order_by != C.ORDER_BY_CREATION:
|
||||
self.check_duplicates = True
|
||||
self.items_ids = []
|
||||
self.disp(A.color(
|
||||
A.FG_RED, A.BOLD,
|
||||
'/!\\ "--all" should be used with "--order-by creation" /!\\\n',
|
||||
A.RESET,
|
||||
"We'll update items, so order may change during transformation,\n"
|
||||
"we'll try to mitigate that by stopping on first duplicate,\n"
|
||||
"but this method is not safe, and some items may be missed.\n---\n"))
|
||||
self.disp(
|
||||
A.color(
|
||||
A.FG_RED,
|
||||
A.BOLD,
|
||||
'/!\\ "--all" should be used with "--order-by creation" /!\\\n',
|
||||
A.RESET,
|
||||
"We'll update items, so order may change during transformation,\n"
|
||||
"we'll try to mitigate that by stopping on first duplicate,\n"
|
||||
"but this method is not safe, and some items may be missed.\n---\n",
|
||||
)
|
||||
)
|
||||
else:
|
||||
self.check_duplicates = False
|
||||
|
||||
|
|
@ -1855,9 +1886,7 @@ class Uri(base.CommandBase):
|
|||
if not self.args.service:
|
||||
try:
|
||||
jid_ = await self.host.bridge.asyncGetParamA(
|
||||
"JabberID",
|
||||
"Connection",
|
||||
profile_key=self.args.profile
|
||||
"JabberID", "Connection", profile_key=self.args.profile
|
||||
)
|
||||
except Exception as e:
|
||||
self.disp(f"can't retrieve jid: {e}", error=True)
|
||||
|
|
@ -1968,7 +1997,9 @@ class HookDelete(base.CommandBase):
|
|||
self.disp(f"can't delete hook: {e}", error=True)
|
||||
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
|
||||
else:
|
||||
self.disp(_(f"{nb_deleted} hook(s) have been deleted"))
|
||||
self.disp(
|
||||
_("{nb_deleted} hook(s) have been deleted").format(nb_deleted=nb_deleted)
|
||||
)
|
||||
self.host.quit()
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -143,12 +143,11 @@ class BaseEdit(object):
|
|||
raise OSError("path must link to a regular file")
|
||||
if path.parent != getTmpDir(self.sat_conf, self.cat_dir):
|
||||
self.disp(
|
||||
f"File {path} is not in SàT temporary hierarchy, we do not remove "
|
||||
f"it",
|
||||
f"File {path} is not in SàT temporary hierarchy, we do not remove " f"it",
|
||||
2,
|
||||
)
|
||||
return
|
||||
# we have 2 files per draft with use_metadata, so we double max
|
||||
# we have 2 files per draft with use_metadata, so we double max
|
||||
unlink_max = SECURE_UNLINK_MAX * 2 if self.use_metadata else SECURE_UNLINK_MAX
|
||||
backup_dir = getTmpDir(self.sat_conf, self.cat_dir, SECURE_UNLINK_DIR)
|
||||
if not os.path.exists(backup_dir):
|
||||
|
|
@ -157,9 +156,7 @@ class BaseEdit(object):
|
|||
backup_path = os.path.join(backup_dir, filename)
|
||||
# we move file to backup dir
|
||||
self.host.disp(
|
||||
"Backuping file {src} to {dst}".format(
|
||||
src=path, dst=backup_path
|
||||
),
|
||||
"Backuping file {src} to {dst}".format(src=path, dst=backup_path),
|
||||
1,
|
||||
)
|
||||
os.rename(path, backup_path)
|
||||
|
|
@ -171,8 +168,14 @@ class BaseEdit(object):
|
|||
self.host.disp("Purging backup file {}".format(path), 2)
|
||||
os.unlink(path)
|
||||
|
||||
async def runEditor(self, editor_args_opt, content_file_path, content_file_obj,
|
||||
meta_file_path=None, meta_ori=None):
|
||||
async def runEditor(
|
||||
self,
|
||||
editor_args_opt,
|
||||
content_file_path,
|
||||
content_file_obj,
|
||||
meta_file_path=None,
|
||||
meta_ori=None,
|
||||
):
|
||||
"""Run editor to edit content and metadata
|
||||
|
||||
@param editor_args_opt(unicode): option in [jp] section in configuration for
|
||||
|
|
@ -188,7 +191,7 @@ class BaseEdit(object):
|
|||
assert meta_file_path is None
|
||||
assert meta_ori is None
|
||||
|
||||
# we calculate hashes to check for modifications
|
||||
# we calculate hashes to check for modifications
|
||||
import hashlib
|
||||
|
||||
content_file_obj.seek(0)
|
||||
|
|
@ -217,9 +220,10 @@ class BaseEdit(object):
|
|||
if not args:
|
||||
args = [content_file_path]
|
||||
|
||||
# actual editing
|
||||
# actual editing
|
||||
editor_process = await asyncio.create_subprocess_exec(
|
||||
editor, *[str(a) for a in args])
|
||||
editor, *[str(a) for a in args]
|
||||
)
|
||||
editor_exit = await editor_process.wait()
|
||||
|
||||
# edition will now be checked, and data will be sent if it was a success
|
||||
|
|
@ -243,7 +247,7 @@ class BaseEdit(object):
|
|||
)
|
||||
self.host.quit(C.EXIT_NOT_FOUND)
|
||||
|
||||
# metadata
|
||||
# metadata
|
||||
if self.use_metadata:
|
||||
try:
|
||||
with meta_file_path.open("rb") as f:
|
||||
|
|
@ -268,8 +272,8 @@ class BaseEdit(object):
|
|||
if self.use_metadata and not metadata.get("publish", True):
|
||||
self.disp(
|
||||
f'Publication blocked by "publish" key in metadata, cancelling '
|
||||
f'edition.\n\ntemporary file path:\t{content_file_path}\nmetadata '
|
||||
f'file path:\t{meta_file_path}',
|
||||
f"edition.\n\ntemporary file path:\t{content_file_path}\nmetadata "
|
||||
f"file path:\t{meta_file_path}",
|
||||
error=True,
|
||||
)
|
||||
self.host.quit()
|
||||
|
|
@ -289,7 +293,7 @@ class BaseEdit(object):
|
|||
os.unlink(meta_file_path)
|
||||
self.host.quit()
|
||||
|
||||
# time to re-check the hash
|
||||
# time to re-check the hash
|
||||
elif tmp_ori_hash == hashlib.sha1(content).digest() and (
|
||||
not self.use_metadata or meta_ori == metadata
|
||||
):
|
||||
|
|
@ -354,9 +358,7 @@ class BaseEdit(object):
|
|||
)
|
||||
return os.fdopen(fd, "w+b"), Path(path)
|
||||
except OSError as e:
|
||||
self.disp(
|
||||
f"Can't create temporary file: {e}", error=True
|
||||
)
|
||||
self.disp(f"Can't create temporary file: {e}", error=True)
|
||||
self.host.quit(1)
|
||||
|
||||
def getCurrentFile(self, profile):
|
||||
|
|
@ -371,7 +373,7 @@ class BaseEdit(object):
|
|||
tmp_dir = getTmpDir(self.sat_conf, self.cat_dir, profile)
|
||||
available = [
|
||||
p
|
||||
for p in tmp_dir.glob(f'{self.cat_dir}_*')
|
||||
for p in tmp_dir.glob(f"{self.cat_dir}_*")
|
||||
if not p.match(f"*{METADATA_SUFF}")
|
||||
]
|
||||
if not available:
|
||||
|
|
@ -436,9 +438,9 @@ class BaseEdit(object):
|
|||
else:
|
||||
self.disp(
|
||||
_(
|
||||
f'item "{item}" not found, we create a new item with'
|
||||
f'this id'
|
||||
),
|
||||
'item "{item}" not found, we create a new item with'
|
||||
"this id"
|
||||
).format(item=item),
|
||||
2,
|
||||
)
|
||||
content_file_obj.seek(0)
|
||||
|
|
@ -453,9 +455,7 @@ class BaseEdit(object):
|
|||
content_file_obj.write("\n*****\n")
|
||||
content_file_obj.write(content.encode("utf-8"))
|
||||
content_file_obj.seek(0)
|
||||
self.disp(
|
||||
_(f'item "{item}" found, we edit it'), 2
|
||||
)
|
||||
self.disp(_('item "{item}" found, we edit it').format(item=item), 2)
|
||||
else:
|
||||
self.disp("Editing a new item", 2)
|
||||
if self.use_metadata:
|
||||
|
|
@ -498,7 +498,7 @@ class Table(object):
|
|||
size = None
|
||||
if headers:
|
||||
# we use a namedtuple to make the value easily accessible from filters
|
||||
headers_safe = [re.sub(r'[^a-zA-Z_]', '_', h) for h in headers]
|
||||
headers_safe = [re.sub(r"[^a-zA-Z_]", "_", h) for h in headers]
|
||||
row_cls = namedtuple("RowData", headers_safe)
|
||||
else:
|
||||
row_cls = tuple
|
||||
|
|
@ -516,8 +516,8 @@ class Table(object):
|
|||
col_value = filter_(value, row_cls(*row_data_list))
|
||||
except TypeError:
|
||||
col_value = filter_(value)
|
||||
# we count size without ANSI code as they will change length of the
|
||||
# string when it's mostly style/color changes.
|
||||
# we count size without ANSI code as they will change length of the
|
||||
# string when it's mostly style/color changes.
|
||||
col_size = len(regex.ansiRemove(col_value))
|
||||
else:
|
||||
col_value = str(value)
|
||||
|
|
@ -562,7 +562,8 @@ class Table(object):
|
|||
|
||||
@classmethod
|
||||
def fromListDict(
|
||||
cls, host, data, keys=None, headers=None, filters=None, defaults=None):
|
||||
cls, host, data, keys=None, headers=None, filters=None, defaults=None
|
||||
):
|
||||
"""Create a table from a list of dictionaries
|
||||
|
||||
each dictionary is a row of the table, keys being columns names.
|
||||
|
|
@ -694,13 +695,13 @@ class Table(object):
|
|||
bottom_sep = col_sep_size * bottom
|
||||
if not show_borders:
|
||||
left = right = head_line_left = head_line_right = ""
|
||||
# top border
|
||||
# top border
|
||||
if show_borders:
|
||||
self._disp(
|
||||
top_left + top_sep.join([top * size for size in sizes]) + top_right
|
||||
)
|
||||
|
||||
# headers
|
||||
# headers
|
||||
if show_header and self.headers is not None:
|
||||
self._disp(
|
||||
left
|
||||
|
|
@ -714,7 +715,7 @@ class Table(object):
|
|||
+ head_line_right
|
||||
)
|
||||
|
||||
# content
|
||||
# content
|
||||
if columns_alignment == "left":
|
||||
alignment = lambda idx, s: ansi_ljust(s, sizes[idx])
|
||||
elif columns_alignment == "center":
|
||||
|
|
@ -740,7 +741,7 @@ class Table(object):
|
|||
+ bottom_sep.join([bottom * size for size in sizes])
|
||||
+ bottom_right
|
||||
)
|
||||
# we return self so string can be used after display (table.display().string)
|
||||
# we return self so string can be used after display (table.display().string)
|
||||
return self
|
||||
|
||||
def display_blank(self, **kwargs):
|
||||
|
|
@ -781,8 +782,10 @@ async def fill_well_known_uri(command, path, key, meta_map=None):
|
|||
uri_data = uris_data[key]
|
||||
except KeyError:
|
||||
host.disp(
|
||||
_(f"No {key} URI specified for this project, please specify service and "
|
||||
f"node"),
|
||||
_(
|
||||
"No {key} URI specified for this project, please specify service and "
|
||||
"node"
|
||||
).format(key=key),
|
||||
error=True,
|
||||
)
|
||||
host.quit(C.EXIT_NOT_FOUND)
|
||||
|
|
@ -790,7 +793,7 @@ async def fill_well_known_uri(command, path, key, meta_map=None):
|
|||
uri = uri_data["uri"]
|
||||
|
||||
# set extra metadata if they are specified
|
||||
for data_key in ['labels']:
|
||||
for data_key in ["labels"]:
|
||||
new_values_json = uri_data.get(data_key)
|
||||
if uri_data is not None:
|
||||
if meta_map is None:
|
||||
|
|
@ -803,7 +806,7 @@ async def fill_well_known_uri(command, path, key, meta_map=None):
|
|||
try:
|
||||
values = getattr(args, data_key)
|
||||
except AttributeError:
|
||||
raise exceptions.InternalError(f'there is no {data_key!r} arguments')
|
||||
raise exceptions.InternalError(f"there is no {data_key!r} arguments")
|
||||
else:
|
||||
if values is None:
|
||||
values = []
|
||||
|
|
@ -815,5 +818,5 @@ async def fill_well_known_uri(command, path, key, meta_map=None):
|
|||
args.service = parsed_uri["path"]
|
||||
args.node = parsed_uri["node"]
|
||||
except KeyError:
|
||||
host.disp(_(f"Invalid URI found: {uri}"), error=True)
|
||||
host.disp(_("Invalid URI found: {uri}").format(uri=uri), error=True)
|
||||
host.quit(C.EXIT_DATA_ERROR)
|
||||
|
|
|
|||
|
|
@ -174,12 +174,11 @@ class OptionsWidget(Widget):
|
|||
|
||||
|
||||
class EmptyWidget(xmlui_base.EmptyWidget, Widget):
|
||||
|
||||
def __init__(self, xmlui_parent):
|
||||
Widget.__init__(self, xmlui_parent)
|
||||
|
||||
async def show(self):
|
||||
self.host.disp('')
|
||||
self.host.disp("")
|
||||
|
||||
|
||||
class TextWidget(xmlui_base.TextWidget, ValueWidget):
|
||||
|
|
@ -199,7 +198,7 @@ class LabelWidget(xmlui_base.LabelWidget, ValueWidget):
|
|||
except AttributeError:
|
||||
return None
|
||||
|
||||
async def show(self, end='\n', ansi=""):
|
||||
async def show(self, end="\n", ansi=""):
|
||||
"""show label
|
||||
|
||||
@param end(str): same as for [JP.disp]
|
||||
|
|
@ -211,6 +210,7 @@ class LabelWidget(xmlui_base.LabelWidget, ValueWidget):
|
|||
class JidWidget(xmlui_base.JidWidget, TextWidget):
|
||||
type = "jid"
|
||||
|
||||
|
||||
class StringWidget(xmlui_base.StringWidget, InputWidget):
|
||||
type = "string"
|
||||
|
||||
|
|
@ -221,7 +221,7 @@ class StringWidget(xmlui_base.StringWidget, InputWidget):
|
|||
elems = []
|
||||
self.verboseName(elems)
|
||||
if self.value:
|
||||
elems.append(_(f"(enter: {self.value})"))
|
||||
elems.append(_("(enter: {value})").format(value=self.value))
|
||||
elems.extend([C.A_HEADER, "> "])
|
||||
value = await self.host.ainput(A.color(*elems))
|
||||
if value:
|
||||
|
|
@ -244,21 +244,24 @@ class TextBoxWidget(xmlui_base.TextWidget, StringWidget):
|
|||
self.disp(self.value)
|
||||
else:
|
||||
if self.value:
|
||||
self.disp(A.color(C.A_HEADER, "↓ current value ↓\n", A.FG_CYAN, self.value,
|
||||
""))
|
||||
self.disp(
|
||||
A.color(C.A_HEADER, "↓ current value ↓\n", A.FG_CYAN, self.value, "")
|
||||
)
|
||||
|
||||
values = []
|
||||
while True:
|
||||
try:
|
||||
if not values:
|
||||
line = await self.host.ainput(A.color(C.A_HEADER, "[Ctrl-D to finish]> "))
|
||||
line = await self.host.ainput(
|
||||
A.color(C.A_HEADER, "[Ctrl-D to finish]> ")
|
||||
)
|
||||
else:
|
||||
line = await self.host.ainput()
|
||||
values.append(line)
|
||||
except EOFError:
|
||||
break
|
||||
break
|
||||
|
||||
self.value = '\n'.join(values).rstrip()
|
||||
self.value = "\n".join(values).rstrip()
|
||||
|
||||
|
||||
class XHTMLBoxWidget(xmlui_base.XHTMLBoxWidget, StringWidget):
|
||||
|
|
@ -269,7 +272,8 @@ class XHTMLBoxWidget(xmlui_base.XHTMLBoxWidget, StringWidget):
|
|||
# this only for now to make it simpler, it must be refactored
|
||||
# to use async when jp will be fully async (expected for 0.8)
|
||||
self.value = await self.host.bridge.syntaxConvert(
|
||||
self.value, C.SYNTAX_XHTML, "markdown", False, self.host.profile)
|
||||
self.value, C.SYNTAX_XHTML, "markdown", False, self.host.profile
|
||||
)
|
||||
await super(XHTMLBoxWidget, self).show()
|
||||
|
||||
|
||||
|
|
@ -285,7 +289,7 @@ class ListWidget(xmlui_base.ListWidget, OptionsWidget):
|
|||
if not self.options:
|
||||
return
|
||||
|
||||
# list display
|
||||
# list display
|
||||
self.verboseName()
|
||||
|
||||
for idx, (value, label) in enumerate(self.options):
|
||||
|
|
@ -304,12 +308,15 @@ class ListWidget(xmlui_base.ListWidget, OptionsWidget):
|
|||
self.value = self.options[0][0]
|
||||
return
|
||||
|
||||
# we ask use to choose an option
|
||||
# we ask use to choose an option
|
||||
choice = None
|
||||
limit_max = len(self.options) - 1
|
||||
while choice is None or choice < 0 or choice > limit_max:
|
||||
choice = await self.host.ainput(
|
||||
A.color(C.A_HEADER, _(f"your choice (0-{limit_max}): "))
|
||||
A.color(
|
||||
C.A_HEADER,
|
||||
_("your choice (0-{limit_max}): ").format(limit_max=limit_max),
|
||||
)
|
||||
)
|
||||
try:
|
||||
choice = int(choice)
|
||||
|
|
@ -328,12 +335,14 @@ class BoolWidget(xmlui_base.BoolWidget, InputWidget):
|
|||
if self.read_only or self.root.read_only:
|
||||
self.disp(disp_true if self.value else disp_false)
|
||||
else:
|
||||
self.disp(A.color(C.A_HEADER, "0: ",
|
||||
disp_false, A.RESET,
|
||||
" *" if not self.value else ""))
|
||||
self.disp(A.color(C.A_HEADER, "1: ",
|
||||
disp_true, A.RESET,
|
||||
" *" if self.value else ""))
|
||||
self.disp(
|
||||
A.color(
|
||||
C.A_HEADER, "0: ", disp_false, A.RESET, " *" if not self.value else ""
|
||||
)
|
||||
)
|
||||
self.disp(
|
||||
A.color(C.A_HEADER, "1: ", disp_true, A.RESET, " *" if self.value else "")
|
||||
)
|
||||
choice = None
|
||||
while choice not in ("0", "1"):
|
||||
elems = [C.A_HEADER, _("your choice (0,1): ")]
|
||||
|
|
@ -345,8 +354,7 @@ class BoolWidget(xmlui_base.BoolWidget, InputWidget):
|
|||
def _xmluiGetValue(self):
|
||||
return C.boolConst(self.value)
|
||||
|
||||
|
||||
## Containers ##
|
||||
## Containers ##
|
||||
|
||||
|
||||
class Container(Base):
|
||||
|
|
@ -383,7 +391,7 @@ class LabelContainer(xmlui_base.PairsContainer, Container):
|
|||
|
||||
async def show(self):
|
||||
for child in self.children:
|
||||
end = '\n'
|
||||
end = "\n"
|
||||
# we check linked widget type
|
||||
# to see if we want the label on the same line or not
|
||||
if child.type == "label":
|
||||
|
|
@ -396,15 +404,14 @@ class LabelContainer(xmlui_base.PairsContainer, Container):
|
|||
"string",
|
||||
"jid_input",
|
||||
):
|
||||
end = ' '
|
||||
end = " "
|
||||
elif wid_type == "bool" and for_widget.read_only:
|
||||
end = ' '
|
||||
end = " "
|
||||
await child.show(end=end, ansi=A.FG_CYAN)
|
||||
else:
|
||||
await child.show()
|
||||
|
||||
|
||||
## Dialogs ##
|
||||
## Dialogs ##
|
||||
|
||||
|
||||
class Dialog(object):
|
||||
|
|
@ -422,8 +429,8 @@ class Dialog(object):
|
|||
"""
|
||||
raise NotImplementedError(self.__class__)
|
||||
|
||||
class MessageDialog(xmlui_base.MessageDialog, Dialog):
|
||||
|
||||
class MessageDialog(xmlui_base.MessageDialog, Dialog):
|
||||
def __init__(self, xmlui_parent, title, message, level):
|
||||
Dialog.__init__(self, xmlui_parent)
|
||||
xmlui_base.MessageDialog.__init__(self, xmlui_parent)
|
||||
|
|
@ -437,7 +444,6 @@ class MessageDialog(xmlui_base.MessageDialog, Dialog):
|
|||
|
||||
|
||||
class NoteDialog(xmlui_base.NoteDialog, Dialog):
|
||||
|
||||
def __init__(self, xmlui_parent, title, message, level):
|
||||
Dialog.__init__(self, xmlui_parent)
|
||||
xmlui_base.NoteDialog.__init__(self, xmlui_parent)
|
||||
|
|
@ -456,12 +462,15 @@ class NoteDialog(xmlui_base.NoteDialog, Dialog):
|
|||
|
||||
|
||||
class ConfirmDialog(xmlui_base.ConfirmDialog, Dialog):
|
||||
|
||||
def __init__(self, xmlui_parent, title, message, level, buttons_set):
|
||||
Dialog.__init__(self, xmlui_parent)
|
||||
xmlui_base.ConfirmDialog.__init__(self, xmlui_parent)
|
||||
self.title, self.message, self.level, self.buttons_set = (
|
||||
title, message, level, buttons_set)
|
||||
title,
|
||||
message,
|
||||
level,
|
||||
buttons_set,
|
||||
)
|
||||
|
||||
async def show(self):
|
||||
# TODO: handle buttons_set and level
|
||||
|
|
@ -469,16 +478,15 @@ class ConfirmDialog(xmlui_base.ConfirmDialog, Dialog):
|
|||
if self.title:
|
||||
self.disp(A.color(C.A_HEADER, self.title))
|
||||
input_ = None
|
||||
while input_ not in ('y', 'n'):
|
||||
while input_ not in ("y", "n"):
|
||||
input_ = await self.host.ainput(f"{self.message} (y/n)? ")
|
||||
input_ = input_.lower()
|
||||
if input_ == 'y':
|
||||
if input_ == "y":
|
||||
self._xmluiValidated()
|
||||
else:
|
||||
self._xmluiCancelled()
|
||||
|
||||
|
||||
## Factory ##
|
||||
## Factory ##
|
||||
|
||||
|
||||
class WidgetFactory(object):
|
||||
|
|
@ -496,8 +504,17 @@ class XMLUIPanel(xmlui_base.AIOXMLUIPanel):
|
|||
workflow = None
|
||||
_submit_cb = None
|
||||
|
||||
def __init__(self, host, parsed_dom, title=None, flags=None, callback=None,
|
||||
ignore=None, whitelist=None, profile=None):
|
||||
def __init__(
|
||||
self,
|
||||
host,
|
||||
parsed_dom,
|
||||
title=None,
|
||||
flags=None,
|
||||
callback=None,
|
||||
ignore=None,
|
||||
whitelist=None,
|
||||
profile=None,
|
||||
):
|
||||
xmlui_base.XMLUIPanel.__init__(
|
||||
self,
|
||||
host,
|
||||
|
|
@ -588,7 +605,7 @@ class XMLUIPanel(xmlui_base.AIOXMLUIPanel):
|
|||
await xmlui.show()
|
||||
if xmlui.submit_id:
|
||||
await xmlui.onFormSubmitted()
|
||||
# TODO: handle data other than XMLUI
|
||||
# TODO: handle data other than XMLUI
|
||||
if not XMLUIPanel._actions:
|
||||
if self._submit_cb is None:
|
||||
self.host.quit()
|
||||
|
|
@ -622,6 +639,7 @@ class XMLUIDialog(xmlui_base.XMLUIDialog):
|
|||
pass
|
||||
|
||||
|
||||
create = partial(xmlui_base.create, class_map={
|
||||
xmlui_base.CLASS_PANEL: XMLUIPanel,
|
||||
xmlui_base.CLASS_DIALOG: XMLUIDialog})
|
||||
create = partial(
|
||||
xmlui_base.create,
|
||||
class_map={xmlui_base.CLASS_PANEL: XMLUIPanel, xmlui_base.CLASS_DIALOG: XMLUIDialog},
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in a new issue