Mercurial > libervia-backend
comparison sat_frontends/jp/cmd_invitation.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 |
comparison
equal
deleted
inserted
replaced
3039:a1bc34f90fa5 | 3040:fee60f17ebac |
---|---|
21 from . import base | 21 from . import base |
22 from sat.core.i18n import _ | 22 from sat.core.i18n import _ |
23 from sat_frontends.jp.constants import Const as C | 23 from sat_frontends.jp.constants import Const as C |
24 from sat.tools.common.ansi import ANSI as A | 24 from sat.tools.common.ansi import ANSI as A |
25 from sat.tools.common import data_format | 25 from sat.tools.common import data_format |
26 from functools import partial | |
27 | 26 |
28 __commands__ = ["Invitation"] | 27 __commands__ = ["Invitation"] |
29 | 28 |
30 | 29 |
31 class Create(base.CommandBase): | 30 class Create(base.CommandBase): |
36 "create", | 35 "create", |
37 use_profile=False, | 36 use_profile=False, |
38 use_output=C.OUTPUT_DICT, | 37 use_output=C.OUTPUT_DICT, |
39 help=_("create and send an invitation"), | 38 help=_("create and send an invitation"), |
40 ) | 39 ) |
41 self.need_loop = True | |
42 | 40 |
43 def add_parser_options(self): | 41 def add_parser_options(self): |
44 self.parser.add_argument( | 42 self.parser.add_argument( |
45 "-j", | 43 "-j", |
46 "--jid", | 44 "--jid", |
113 "--profile", | 111 "--profile", |
114 default="", | 112 default="", |
115 help="profile doing the invitation (default: don't associate profile)", | 113 help="profile doing the invitation (default: don't associate profile)", |
116 ) | 114 ) |
117 | 115 |
118 def invitationCreateCb(self, invitation_data): | 116 async def start(self): |
119 self.output(invitation_data) | |
120 self.host.quit(C.EXIT_OK) | |
121 | |
122 def invitationCreateEb(self, failure_): | |
123 self.disp( | |
124 "can't create invitation: {reason}".format(reason=failure_), error=True | |
125 ) | |
126 self.host.quit(C.EXIT_BRIDGE_ERRBACK) | |
127 | |
128 def start(self): | |
129 extra = dict(self.args.extra) | 117 extra = dict(self.args.extra) |
130 email = self.args.email[0] if self.args.email else None | 118 email = self.args.email[0] if self.args.email else None |
131 emails_extra = self.args.email[1:] | 119 emails_extra = self.args.email[1:] |
132 if self.args.no_email: | 120 if self.args.no_email: |
133 if email: | 121 if email: |
137 if not email: | 125 if not email: |
138 self.parser.error( | 126 self.parser.error( |
139 _("you need to specify an email address to send email invitation") | 127 _("you need to specify an email address to send email invitation") |
140 ) | 128 ) |
141 | 129 |
142 self.host.bridge.invitationCreate( | 130 try: |
143 email, | 131 invitation_data = await self.host.bridge.invitationCreate( |
144 emails_extra, | 132 email, |
145 self.args.jid, | 133 emails_extra, |
146 self.args.password, | 134 self.args.jid, |
147 self.args.name, | 135 self.args.password, |
148 self.args.host_name, | 136 self.args.name, |
149 self.args.lang, | 137 self.args.host_name, |
150 self.args.url, | 138 self.args.lang, |
151 self.args.subject, | 139 self.args.url, |
152 self.args.body, | 140 self.args.subject, |
153 extra, | 141 self.args.body, |
154 self.args.profile, | 142 extra, |
155 callback=self.invitationCreateCb, | 143 self.args.profile, |
156 errback=self.invitationCreateEb, | 144 ) |
157 ) | 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) | |
158 | 151 |
159 | 152 |
160 class Get(base.CommandBase): | 153 class Get(base.CommandBase): |
161 def __init__(self, host): | 154 def __init__(self, host): |
162 base.CommandBase.__init__( | 155 base.CommandBase.__init__( |
165 "get", | 158 "get", |
166 use_profile=False, | 159 use_profile=False, |
167 use_output=C.OUTPUT_DICT, | 160 use_output=C.OUTPUT_DICT, |
168 help=_("get invitation data"), | 161 help=_("get invitation data"), |
169 ) | 162 ) |
170 self.need_loop = True | |
171 | 163 |
172 def add_parser_options(self): | 164 def add_parser_options(self): |
173 self.parser.add_argument( | 165 self.parser.add_argument( |
174 "id", help=_("invitation UUID") | 166 "id", help=_("invitation UUID") |
175 ) | 167 ) |
178 "--with-jid", | 170 "--with-jid", |
179 action="store_true", | 171 action="store_true", |
180 help=_("start profile session and retrieve jid"), | 172 help=_("start profile session and retrieve jid"), |
181 ) | 173 ) |
182 | 174 |
183 def output_data(self, data, jid_=None): | 175 async def output_data(self, data, jid_=None): |
184 if jid_ is not None: | 176 if jid_ is not None: |
185 data["jid"] = jid_ | 177 data["jid"] = jid_ |
186 self.output(data) | 178 await self.output(data) |
187 self.host.quit() | 179 self.host.quit() |
188 | 180 |
189 def invitationGetCb(self, invitation_data): | 181 async def start(self): |
190 if self.args.with_jid: | 182 try: |
183 invitation_data = await self.host.bridge.invitationGet( | |
184 self.args.id, | |
185 ) | |
186 except Exception as e: | |
187 self.disp(msg=_(f"can't get invitation data: {e}"), error=True) | |
188 self.host.quit(C.EXIT_BRIDGE_ERRBACK) | |
189 | |
190 if not self.args.with_jid: | |
191 await self.output_data(invitation_data) | |
192 else: | |
191 profile = invitation_data["guest_profile"] | 193 profile = invitation_data["guest_profile"] |
192 | 194 try: |
193 def session_started(__): | 195 await self.host.bridge.profileStartSession( |
194 self.host.bridge.asyncGetParamA( | 196 invitation_data["password"], |
197 profile, | |
198 ) | |
199 except Exception as e: | |
200 self.disp(msg=_(f"can't start session: {e}"), error=True) | |
201 self.host.quit(C.EXIT_BRIDGE_ERRBACK) | |
202 | |
203 try: | |
204 jid_ = await self.host.bridge.asyncGetParamA( | |
195 "JabberID", | 205 "JabberID", |
196 "Connection", | 206 "Connection", |
197 profile_key=profile, | 207 profile_key=profile, |
198 callback=lambda jid_: self.output_data(invitation_data, jid_), | |
199 errback=partial( | |
200 self.errback, | |
201 msg=_("can't retrieve jid: {}"), | |
202 exit_code=C.EXIT_BRIDGE_ERRBACK, | |
203 ), | |
204 ) | 208 ) |
205 | 209 except Exception as e: |
206 self.host.bridge.profileStartSession( | 210 self.disp(msg=_(f"can't retrieve jid: {e}"), error=True) |
207 invitation_data["password"], | 211 self.host.quit(C.EXIT_BRIDGE_ERRBACK) |
208 profile, | 212 |
209 callback=session_started, | 213 await self.output_data(invitation_data, jid_) |
210 errback=partial( | |
211 self.errback, | |
212 msg=_("can't start session: {}"), | |
213 exit_code=C.EXIT_BRIDGE_ERRBACK, | |
214 ), | |
215 ) | |
216 else: | |
217 self.output_data(invitation_data) | |
218 | |
219 def start(self): | |
220 self.host.bridge.invitationGet( | |
221 self.args.id, | |
222 callback=self.invitationGetCb, | |
223 errback=partial( | |
224 self.errback, | |
225 msg=_("can't get invitation data: {}"), | |
226 exit_code=C.EXIT_BRIDGE_ERRBACK, | |
227 ), | |
228 ) | |
229 | 214 |
230 | 215 |
231 class Modify(base.CommandBase): | 216 class Modify(base.CommandBase): |
232 def __init__(self, host): | 217 def __init__(self, host): |
233 base.CommandBase.__init__( | 218 base.CommandBase.__init__( |
234 self, host, "modify", use_profile=False, help=_("modify existing invitation") | 219 self, host, "modify", use_profile=False, help=_("modify existing invitation") |
235 ) | 220 ) |
236 self.need_loop = True | |
237 | 221 |
238 def add_parser_options(self): | 222 def add_parser_options(self): |
239 self.parser.add_argument( | 223 self.parser.add_argument( |
240 "--replace", action="store_true", help="replace the whole data" | 224 "--replace", action="store_true", help="replace the whole data" |
241 ) | 225 ) |
281 ) | 265 ) |
282 self.parser.add_argument( | 266 self.parser.add_argument( |
283 "id", help=_("invitation UUID") | 267 "id", help=_("invitation UUID") |
284 ) | 268 ) |
285 | 269 |
286 def invitationModifyCb(self): | 270 async def start(self): |
287 self.disp(_("invitations have been modified correctly")) | |
288 self.host.quit(C.EXIT_OK) | |
289 | |
290 def invitationModifyEb(self, failure_): | |
291 self.disp( | |
292 "can't create invitation: {reason}".format(reason=failure_), error=True | |
293 ) | |
294 self.host.quit(C.EXIT_BRIDGE_ERRBACK) | |
295 | |
296 def start(self): | |
297 extra = dict(self.args.extra) | 271 extra = dict(self.args.extra) |
298 for arg_name in ("name", "host_name", "email", "language", "profile"): | 272 for arg_name in ("name", "host_name", "email", "language", "profile"): |
299 value = getattr(self.args, arg_name) | 273 value = getattr(self.args, arg_name) |
300 if not value: | 274 if not value: |
301 continue | 275 continue |
302 if arg_name in extra: | 276 if arg_name in extra: |
303 self.parser.error( | 277 self.parser.error( |
304 _( | 278 _(f"you can't set {arg_name} in both optional argument and extra") |
305 "you can't set {arg_name} in both optional argument and extra" | |
306 ).format(arg_name=arg_name) | |
307 ) | 279 ) |
308 extra[arg_name] = value | 280 extra[arg_name] = value |
309 self.host.bridge.invitationModify( | 281 try: |
310 self.args.id, | 282 await self.host.bridge.invitationModify( |
311 extra, | 283 self.args.id, |
312 self.args.replace, | 284 extra, |
313 callback=self.invitationModifyCb, | 285 self.args.replace, |
314 errback=self.invitationModifyEb, | 286 ) |
315 ) | 287 except Exception as e: |
288 self.disp( | |
289 f"can't modify invitation: {e}", error=True | |
290 ) | |
291 self.host.quit(C.EXIT_BRIDGE_ERRBACK) | |
292 else: | |
293 self.disp(_("invitations have been modified successfuly")) | |
294 self.host.quit(C.EXIT_OK) | |
316 | 295 |
317 | 296 |
318 class List(base.CommandBase): | 297 class List(base.CommandBase): |
319 def __init__(self, host): | 298 def __init__(self, host): |
320 extra_outputs = {"default": self.default_output} | 299 extra_outputs = {"default": self.default_output} |
325 use_profile=False, | 304 use_profile=False, |
326 use_output=C.OUTPUT_COMPLEX, | 305 use_output=C.OUTPUT_COMPLEX, |
327 extra_outputs=extra_outputs, | 306 extra_outputs=extra_outputs, |
328 help=_("list invitations data"), | 307 help=_("list invitations data"), |
329 ) | 308 ) |
330 self.need_loop = True | |
331 | 309 |
332 def default_output(self, data): | 310 def default_output(self, data): |
333 for idx, datum in enumerate(data.items()): | 311 for idx, datum in enumerate(data.items()): |
334 if idx: | 312 if idx: |
335 self.disp("\n") | 313 self.disp("\n") |
345 "--profile", | 323 "--profile", |
346 default=C.PROF_KEY_NONE, | 324 default=C.PROF_KEY_NONE, |
347 help=_("return only invitations linked to this profile"), | 325 help=_("return only invitations linked to this profile"), |
348 ) | 326 ) |
349 | 327 |
350 def invitationListCb(self, data): | 328 async def start(self): |
351 self.output(data) | 329 try: |
352 self.host.quit() | 330 data = await self.host.bridge.invitationList( |
353 | 331 self.args.profile, |
354 def start(self): | 332 ) |
355 self.host.bridge.invitationList( | 333 except Exception as e: |
356 self.args.profile, | 334 self.disp(f"return only invitations linked to this profile: {e}", error=True) |
357 callback=self.invitationListCb, | 335 self.host.quit(C.EXIT_BRIDGE_ERRBACK) |
358 errback=partial( | 336 else: |
359 self.errback, | 337 await self.output(data) |
360 msg=_("can't list invitations: {}"), | 338 self.host.quit() |
361 exit_code=C.EXIT_BRIDGE_ERRBACK, | |
362 ), | |
363 ) | |
364 | 339 |
365 | 340 |
366 class Invitation(base.CommandBase): | 341 class Invitation(base.CommandBase): |
367 subcommands = (Create, Get, Modify, List) | 342 subcommands = (Create, Get, Modify, List) |
368 | 343 |