annotate sat_frontends/jp/cmd_avatar.py @ 3080:16925f494820

plugin XEP-0045: don't fail on `item-not-found` with MAM: Some servers don't store permanently the whole history of MUC with MAM. As a result, an "item-not-found" stanza error can be received when message id used as reference doesn't exist anymore on the server. When this case happens, the history is retrieved in the same way as for a newly joined room (i.e. last 50 messages are requested).
author Goffi <goffi@goffi.org>
date Thu, 05 Dec 2019 23:05:16 +0100
parents fee60f17ebac
children 9d0df638c8b4
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2074
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
1 #!/usr/bin/env python2
db5cda61740f jp (avatar): avatar get/set implementations, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
2 # -*- coding: utf-8 -*-
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
2771
003b8b4b56a7 date update
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
5 # Copyright (C) 2009-2019 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 )