Mercurial > libervia-backend
diff sat_frontends/jp/cmd_avatar.py @ 3040:fee60f17ebac
jp: jp asyncio port:
/!\ this commit is huge. Jp is temporarily not working with `dbus` bridge /!\
This patch implements the port of jp to asyncio, so it is now correctly using the bridge
asynchronously, and it can be used with bridges like `pb`. This also simplify the code,
notably for things which were previously implemented with many callbacks (like pagination
with RSM).
During the process, some behaviours have been modified/fixed, in jp and backends, check
diff for details.
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 25 Sep 2019 08:56:41 +0200 |
parents | ab2696e34d29 |
children | 9d0df638c8b4 |
line wrap: on
line diff
--- a/sat_frontends/jp/cmd_avatar.py Wed Sep 25 08:53:38 2019 +0200 +++ b/sat_frontends/jp/cmd_avatar.py Wed Sep 25 08:56:41 2019 +0200 @@ -18,59 +18,24 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. -from . import base import os import os.path +import asyncio +from . import base from sat.core.i18n import _ from sat_frontends.jp.constants import Const as C from sat.tools import config -import subprocess __commands__ = ["Avatar"] DISPLAY_CMD = ["xv", "display", "gwenview", "showtell"] -class Set(base.CommandBase): - def __init__(self, host): - super(Set, self).__init__( - host, "set", use_verbose=True, help=_("set avatar of the profile") - ) - self.need_loop = True - - def add_parser_options(self): - self.parser.add_argument( - "image_path", type=str, help=_("path to the image to upload") - ) - - def start(self): - """Send files to jabber contact""" - path = self.args.image_path - if not os.path.exists(path): - self.disp(_("file [{}] doesn't exist !").format(path), error=True) - self.host.quit(1) - path = os.path.abspath(path) - self.host.bridge.avatarSet( - path, self.profile, callback=self._avatarCb, errback=self._avatarEb - ) - - def _avatarCb(self): - self.disp(_("avatar has been set"), 1) - self.host.quit() - - def _avatarEb(self, failure_): - self.disp( - _("error while uploading avatar: {msg}").format(msg=failure_), error=True - ) - self.host.quit(C.EXIT_ERROR) - - class Get(base.CommandBase): def __init__(self, host): super(Get, self).__init__( host, "get", use_verbose=True, help=_("retrieve avatar of an entity") ) - self.need_loop = True def add_parser_options(self): self.parser.add_argument("jid", help=_("entity")) @@ -78,54 +43,81 @@ "-s", "--show", action="store_true", help=_("show avatar") ) - def showImage(self, path): + async def showImage(self, path): sat_conf = config.parseMainConf() cmd = config.getConfig(sat_conf, "jp", "image_cmd") cmds = [cmd] + DISPLAY_CMD if cmd else DISPLAY_CMD for cmd in cmds: try: - ret = subprocess.call([cmd] + [path]) + process = await asyncio.create_subprocess_exec(cmd, path) + ret = await process.wait() except OSError: - pass - else: - if ret in (0, 2): - # we can get exit code 2 with display when stopping it with C-c - break + continue + + if ret in (0, 2): + # we can get exit code 2 with display when stopping it with C-c + break else: # didn't worked with commands, we try our luck with webbrowser - # in some cases, webbrowser can actually open the associated display program + # in some cases, webbrowser can actually open the associated display program. + # Note that this may be possibly blocking, depending on the platform and + # available browser import webbrowser webbrowser.open(path) - def _avatarGetCb(self, avatar_path): + async def start(self): + try: + avatar_path = await self.host.bridge.avatarGet( + self.args.jid, + False, + False, + self.profile, + ) + except Exception as e: + self.disp(f"can't retrieve avatar: {e}", error=True) + self.host.quit(C.EXIT_BRIDGE_ERRBACK) + if not avatar_path: self.disp(_("No avatar found."), 1) self.host.quit(C.EXIT_NOT_FOUND) self.disp(avatar_path) if self.args.show: - self.showImage(avatar_path) + await self.showImage(avatar_path) self.host.quit() - def _avatarGetEb(self, failure_): - self.disp(_("error while getting avatar: {msg}").format(msg=failure_), error=True) - self.host.quit(C.EXIT_ERROR) + +class Set(base.CommandBase): + def __init__(self, host): + super(Set, self).__init__( + host, "set", use_verbose=True, help=_("set avatar of the profile") + ) + + def add_parser_options(self): + self.parser.add_argument( + "image_path", type=str, help=_("path to the image to upload") + ) - def start(self): - self.host.bridge.avatarGet( - self.args.jid, - False, - False, - self.profile, - callback=self._avatarGetCb, - errback=self._avatarGetEb, - ) + 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.host.quit(C.EXIT_BAD_ARG) + path = os.path.abspath(path) + try: + await self.host.bridge.avatarSet(path, self.profile) + except Exception as e: + self.disp(f"can't set avatar: {e}", error=True) + self.host.quit(C.EXIT_BRIDGE_ERRBACK) + else: + self.disp(_("avatar has been set"), 1) + self.host.quit() class Avatar(base.CommandBase): - subcommands = (Set, Get) + subcommands = (Get, Set) def __init__(self, host): super(Avatar, self).__init__(