comparison libervia/frontends/jp/cmd_invitation.py @ 4074:26b7ed2817da

refactoring: rename `sat_frontends` to `libervia.frontends`
author Goffi <goffi@goffi.org>
date Fri, 02 Jun 2023 14:12:38 +0200
parents sat_frontends/jp/cmd_invitation.py@4b842c1fb686
children
comparison
equal deleted inserted replaced
4073:7c5654c54fed 4074:26b7ed2817da
1 #!/usr/bin/env python3
2
3
4 # jp: a SàT command line tool
5 # Copyright (C) 2009-2021 Jérôme Poisson (goffi@goffi.org)
6
7 # This program is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU Affero General Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
11
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU Affero General Public License for more details.
16
17 # You should have received a copy of the GNU Affero General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19
20
21 from . import base
22 from libervia.backend.core.i18n import _
23 from libervia.frontends.jp.constants import Const as C
24 from libervia.backend.tools.common.ansi import ANSI as A
25 from libervia.backend.tools.common import data_format
26
27 __commands__ = ["Invitation"]
28
29
30 class Create(base.CommandBase):
31 def __init__(self, host):
32 base.CommandBase.__init__(
33 self,
34 host,
35 "create",
36 use_profile=False,
37 use_output=C.OUTPUT_DICT,
38 help=_("create and send an invitation"),
39 )
40
41 def add_parser_options(self):
42 self.parser.add_argument(
43 "-j",
44 "--jid",
45 default="",
46 help="jid of the invitee (default: generate one)",
47 )
48 self.parser.add_argument(
49 "-P",
50 "--password",
51 default="",
52 help="password of the invitee profile/XMPP account (default: generate one)",
53 )
54 self.parser.add_argument(
55 "-n",
56 "--name",
57 default="",
58 help="name of the invitee",
59 )
60 self.parser.add_argument(
61 "-N",
62 "--host-name",
63 default="",
64 help="name of the host",
65 )
66 self.parser.add_argument(
67 "-e",
68 "--email",
69 action="append",
70 default=[],
71 help="email(s) to send the invitation to (if --no-email is set, email will just be saved)",
72 )
73 self.parser.add_argument(
74 "--no-email", action="store_true", help="do NOT send invitation email"
75 )
76 self.parser.add_argument(
77 "-l",
78 "--lang",
79 default="",
80 help="main language spoken by the invitee",
81 )
82 self.parser.add_argument(
83 "-u",
84 "--url",
85 default="",
86 help="template to construct the URL",
87 )
88 self.parser.add_argument(
89 "-s",
90 "--subject",
91 default="",
92 help="subject of the invitation email (default: generic subject)",
93 )
94 self.parser.add_argument(
95 "-b",
96 "--body",
97 default="",
98 help="body of the invitation email (default: generic body)",
99 )
100 self.parser.add_argument(
101 "-x",
102 "--extra",
103 metavar=("KEY", "VALUE"),
104 action="append",
105 nargs=2,
106 default=[],
107 help="extra data to associate with invitation/invitee",
108 )
109 self.parser.add_argument(
110 "-p",
111 "--profile",
112 default="",
113 help="profile doing the invitation (default: don't associate profile)",
114 )
115
116 async def start(self):
117 extra = dict(self.args.extra)
118 email = self.args.email[0] if self.args.email else None
119 emails_extra = self.args.email[1:]
120 if self.args.no_email:
121 if email:
122 extra["email"] = email
123 data_format.iter2dict("emails_extra", emails_extra)
124 else:
125 if not email:
126 self.parser.error(
127 _("you need to specify an email address to send email invitation")
128 )
129
130 try:
131 invitation_data = await self.host.bridge.invitation_create(
132 email,
133 emails_extra,
134 self.args.jid,
135 self.args.password,
136 self.args.name,
137 self.args.host_name,
138 self.args.lang,
139 self.args.url,
140 self.args.subject,
141 self.args.body,
142 extra,
143 self.args.profile,
144 )
145 except Exception as e:
146 self.disp(f"can't create invitation: {e}", error=True)
147 self.host.quit(C.EXIT_BRIDGE_ERRBACK)
148 else:
149 await self.output(invitation_data)
150 self.host.quit(C.EXIT_OK)
151
152
153 class Get(base.CommandBase):
154 def __init__(self, host):
155 base.CommandBase.__init__(
156 self,
157 host,
158 "get",
159 use_profile=False,
160 use_output=C.OUTPUT_DICT,
161 help=_("get invitation data"),
162 )
163
164 def add_parser_options(self):
165 self.parser.add_argument("id", help=_("invitation UUID"))
166 self.parser.add_argument(
167 "-j",
168 "--with-jid",
169 action="store_true",
170 help=_("start profile session and retrieve jid"),
171 )
172
173 async def output_data(self, data, jid_=None):
174 if jid_ is not None:
175 data["jid"] = jid_
176 await self.output(data)
177 self.host.quit()
178
179 async def start(self):
180 try:
181 invitation_data = await self.host.bridge.invitation_get(
182 self.args.id,
183 )
184 except Exception as e:
185 self.disp(msg=_("can't get invitation data: {e}").format(e=e), error=True)
186 self.host.quit(C.EXIT_BRIDGE_ERRBACK)
187
188 if not self.args.with_jid:
189 await self.output_data(invitation_data)
190 else:
191 profile = invitation_data["guest_profile"]
192 try:
193 await self.host.bridge.profile_start_session(
194 invitation_data["password"],
195 profile,
196 )
197 except Exception as e:
198 self.disp(msg=_("can't start session: {e}").format(e=e), error=True)
199 self.host.quit(C.EXIT_BRIDGE_ERRBACK)
200
201 try:
202 jid_ = await self.host.bridge.param_get_a_async(
203 "JabberID",
204 "Connection",
205 profile_key=profile,
206 )
207 except Exception as e:
208 self.disp(msg=_("can't retrieve jid: {e}").format(e=e), error=True)
209 self.host.quit(C.EXIT_BRIDGE_ERRBACK)
210
211 await self.output_data(invitation_data, jid_)
212
213
214 class Delete(base.CommandBase):
215 def __init__(self, host):
216 base.CommandBase.__init__(
217 self,
218 host,
219 "delete",
220 use_profile=False,
221 help=_("delete guest account"),
222 )
223
224 def add_parser_options(self):
225 self.parser.add_argument("id", help=_("invitation UUID"))
226
227 async def start(self):
228 try:
229 await self.host.bridge.invitation_delete(
230 self.args.id,
231 )
232 except Exception as e:
233 self.disp(msg=_("can't delete guest account: {e}").format(e=e), error=True)
234 self.host.quit(C.EXIT_BRIDGE_ERRBACK)
235
236 self.host.quit()
237
238
239 class Modify(base.CommandBase):
240 def __init__(self, host):
241 base.CommandBase.__init__(
242 self, host, "modify", use_profile=False, help=_("modify existing invitation")
243 )
244
245 def add_parser_options(self):
246 self.parser.add_argument(
247 "--replace", action="store_true", help="replace the whole data"
248 )
249 self.parser.add_argument(
250 "-n",
251 "--name",
252 default="",
253 help="name of the invitee",
254 )
255 self.parser.add_argument(
256 "-N",
257 "--host-name",
258 default="",
259 help="name of the host",
260 )
261 self.parser.add_argument(
262 "-e",
263 "--email",
264 default="",
265 help="email to send the invitation to (if --no-email is set, email will just be saved)",
266 )
267 self.parser.add_argument(
268 "-l",
269 "--lang",
270 dest="language",
271 default="",
272 help="main language spoken by the invitee",
273 )
274 self.parser.add_argument(
275 "-x",
276 "--extra",
277 metavar=("KEY", "VALUE"),
278 action="append",
279 nargs=2,
280 default=[],
281 help="extra data to associate with invitation/invitee",
282 )
283 self.parser.add_argument(
284 "-p",
285 "--profile",
286 default="",
287 help="profile doing the invitation (default: don't associate profile",
288 )
289 self.parser.add_argument("id", help=_("invitation UUID"))
290
291 async def start(self):
292 extra = dict(self.args.extra)
293 for arg_name in ("name", "host_name", "email", "language", "profile"):
294 value = getattr(self.args, arg_name)
295 if not value:
296 continue
297 if arg_name in extra:
298 self.parser.error(
299 _(
300 "you can't set {arg_name} in both optional argument and extra"
301 ).format(arg_name=arg_name)
302 )
303 extra[arg_name] = value
304 try:
305 await self.host.bridge.invitation_modify(
306 self.args.id,
307 extra,
308 self.args.replace,
309 )
310 except Exception as e:
311 self.disp(f"can't modify invitation: {e}", error=True)
312 self.host.quit(C.EXIT_BRIDGE_ERRBACK)
313 else:
314 self.disp(_("invitations have been modified successfuly"))
315 self.host.quit(C.EXIT_OK)
316
317
318 class List(base.CommandBase):
319 def __init__(self, host):
320 extra_outputs = {"default": self.default_output}
321 base.CommandBase.__init__(
322 self,
323 host,
324 "list",
325 use_profile=False,
326 use_output=C.OUTPUT_COMPLEX,
327 extra_outputs=extra_outputs,
328 help=_("list invitations data"),
329 )
330
331 def default_output(self, data):
332 for idx, datum in enumerate(data.items()):
333 if idx:
334 self.disp("\n")
335 key, invitation_data = datum
336 self.disp(A.color(C.A_HEADER, key))
337 indent = " "
338 for k, v in invitation_data.items():
339 self.disp(indent + A.color(C.A_SUBHEADER, k + ":") + " " + str(v))
340
341 def add_parser_options(self):
342 self.parser.add_argument(
343 "-p",
344 "--profile",
345 default=C.PROF_KEY_NONE,
346 help=_("return only invitations linked to this profile"),
347 )
348
349 async def start(self):
350 try:
351 data = await self.host.bridge.invitation_list(
352 self.args.profile,
353 )
354 except Exception as e:
355 self.disp(f"return only invitations linked to this profile: {e}", error=True)
356 self.host.quit(C.EXIT_BRIDGE_ERRBACK)
357 else:
358 await self.output(data)
359 self.host.quit()
360
361
362 class Invitation(base.CommandBase):
363 subcommands = (Create, Get, Delete, Modify, List)
364
365 def __init__(self, host):
366 super(Invitation, self).__init__(
367 host,
368 "invitation",
369 use_profile=False,
370 help=_("invitation of user(s) without XMPP account"),
371 )