annotate sat_frontends/jp/cmd_avatar.py @ 3193:65d89a339dd3

quick frontend (app): avoid crash when a listener is removed while being called
author Goffi <goffi@goffi.org>
date Fri, 28 Feb 2020 10:06:38 +0100
parents 559a625a236b
children 6cf4bd6972c2
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3137
559a625a236b fixed shebangs
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
1 #!/usr/bin/env python3
559a625a236b fixed shebangs
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
2
2074
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
3
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
4 # jp: a SAT command line tool
3136
9d0df638c8b4 dates update
Goffi <goffi@goffi.org>
parents: 3040
diff changeset
5 # Copyright (C) 2009-2020 Jérôme Poisson (goffi@goffi.org)
2074
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
6
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
7 # This program is free software: you can redistribute it and/or modify
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
8 # it under the terms of the GNU Affero General Public License as published by
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
9 # the Free Software Foundation, either version 3 of the License, or
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
10 # (at your option) any later version.
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
11
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
12 # This program is distributed in the hope that it will be useful,
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
15 # GNU Affero General Public License for more details.
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
16
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
17 # You should have received a copy of the GNU Affero General Public License
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
19
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
20
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
21 import os
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
22 import os.path
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
23 import asyncio
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
24 from . import base
2074
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
25 from sat.core.i18n import _
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
26 from sat_frontends.jp.constants import Const as C
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
27 from sat.tools import config
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
28
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
29
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
30 __commands__ = ["Avatar"]
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
31 DISPLAY_CMD = ["xv", "display", "gwenview", "showtell"]
2074
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
32
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
33
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
34 class Get(base.CommandBase):
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
35 def __init__(self, host):
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
36 super(Get, self).__init__(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
37 host, "get", use_verbose=True, help=_("retrieve avatar of an entity")
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
38 )
2074
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
39
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
40 def add_parser_options(self):
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2883
diff changeset
41 self.parser.add_argument("jid", help=_("entity"))
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
42 self.parser.add_argument(
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2883
diff changeset
43 "-s", "--show", action="store_true", help=_("show avatar")
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
44 )
2074
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
45
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
46 async def showImage(self, path):
2074
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
47 sat_conf = config.parseMainConf()
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
48 cmd = config.getConfig(sat_conf, "jp", "image_cmd")
2074
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
49 cmds = [cmd] + DISPLAY_CMD if cmd else DISPLAY_CMD
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
50 for cmd in cmds:
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
51 try:
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
52 process = await asyncio.create_subprocess_exec(cmd, path)
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
53 ret = await process.wait()
2074
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
54 except OSError:
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
55 continue
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
56
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
57 if ret in (0, 2):
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
58 # we can get exit code 2 with display when stopping it with C-c
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
59 break
2074
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
60 else:
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
61 # didn't worked with commands, we try our luck with webbrowser
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
62 # in some cases, webbrowser can actually open the associated display program.
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
63 # Note that this may be possibly blocking, depending on the platform and
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
64 # available browser
2074
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
65 import webbrowser
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
66
2074
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
67 webbrowser.open(path)
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
68
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
69 async def start(self):
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
70 try:
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
71 avatar_path = await self.host.bridge.avatarGet(
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
72 self.args.jid,
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
73 False,
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
74 False,
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
75 self.profile,
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
76 )
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
77 except Exception as e:
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
78 self.disp(f"can't retrieve avatar: {e}", error=True)
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
79 self.host.quit(C.EXIT_BRIDGE_ERRBACK)
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
80
2074
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
81 if not avatar_path:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2883
diff changeset
82 self.disp(_("No avatar found."), 1)
2074
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
83 self.host.quit(C.EXIT_NOT_FOUND)
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
84
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
85 self.disp(avatar_path)
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
86 if self.args.show:
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
87 await self.showImage(avatar_path)
2074
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
88
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
89 self.host.quit()
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
90
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
91
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
92 class Set(base.CommandBase):
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
93 def __init__(self, host):
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
94 super(Set, self).__init__(
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
95 host, "set", use_verbose=True, help=_("set avatar of the profile")
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
96 )
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
97
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
98 def add_parser_options(self):
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
99 self.parser.add_argument(
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
100 "image_path", type=str, help=_("path to the image to upload")
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
101 )
2074
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
102
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
103 async def start(self):
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
104 path = self.args.image_path
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
105 if not os.path.exists(path):
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
106 self.disp(_(f"file {path!r} doesn't exist!"), error=True)
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
107 self.host.quit(C.EXIT_BAD_ARG)
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
108 path = os.path.abspath(path)
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
109 try:
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
110 await self.host.bridge.avatarSet(path, self.profile)
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
111 except Exception as e:
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
112 self.disp(f"can't set avatar: {e}", error=True)
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
113 self.host.quit(C.EXIT_BRIDGE_ERRBACK)
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
114 else:
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
115 self.disp(_("avatar has been set"), 1)
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
116 self.host.quit()
2074
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
117
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
118
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
119 class Avatar(base.CommandBase):
3040
fee60f17ebac jp: jp asyncio port:
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
120 subcommands = (Get, Set)
2074
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
121
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
122 def __init__(self, host):
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
123 super(Avatar, self).__init__(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
124 host, "avatar", use_profile=False, help=_("avatar uploading/retrieving")
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
125 )