Mercurial > libervia-backend
comparison sat/core/sat_main.py @ 3120:0c29155ac68b
core: backend autoconnection:
A new Connection/autoconnect_backend param can be set for a profile or component to be
started automatically with backend. This is specially useful for components, but can be
useful for client profile too (e.g. on Android we need to start profile with backend to
get notifications, this part will come with following commits).
The new Sqlite.getIndParamValues method allows to retrieve the same parameters for all
profiles.
author | Goffi <goffi@goffi.org> |
---|---|
date | Sat, 25 Jan 2020 21:08:32 +0100 |
parents | 385fdd684f87 |
children | 130f9cb6e0ab |
comparison
equal
deleted
inserted
replaced
3119:790489521b15 | 3120:0c29155ac68b |
---|---|
1 #!/usr/bin/env python3 | 1 #!/usr/bin/env python3 |
2 # -*- coding: utf-8 -*- | |
3 | 2 |
4 # SAT: a jabber client | 3 # SAT: a jabber client |
5 # Copyright (C) 2009-2019 Jérôme Poisson (goffi@goffi.org) | 4 # Copyright (C) 2009-2019 Jérôme Poisson (goffi@goffi.org) |
6 | 5 |
7 # This program is free software: you can redistribute it and/or modify | 6 # This program is free software: you can redistribute it and/or modify |
20 from glob import glob | 19 from glob import glob |
21 import sys | 20 import sys |
22 import os.path | 21 import os.path |
23 import uuid | 22 import uuid |
24 import sat | 23 import sat |
25 from sat.core.i18n import _, languageSwitch | 24 from sat.core.i18n import _, D_, languageSwitch |
26 from sat.core import patches | 25 from sat.core import patches |
27 patches.apply() | 26 patches.apply() |
28 from twisted.application import service | 27 from twisted.application import service |
29 from twisted.internet import defer | 28 from twisted.internet import defer |
30 from twisted.words.protocols.jabber import jid | 29 from twisted.words.protocols.jabber import jid |
170 self.bridge.register_method("sessionInfosGet", self.getSessionInfos) | 169 self.bridge.register_method("sessionInfosGet", self.getSessionInfos) |
171 self.bridge.register_method("namespacesGet", self.getNamespaces) | 170 self.bridge.register_method("namespacesGet", self.getNamespaces) |
172 self.bridge.register_method("imageCheck", self._imageCheck) | 171 self.bridge.register_method("imageCheck", self._imageCheck) |
173 self.bridge.register_method("imageResize", self._imageResize) | 172 self.bridge.register_method("imageResize", self._imageResize) |
174 | 173 |
175 self.memory.initialized.addCallback(self._postMemoryInit) | 174 self.memory.initialized.addCallback(lambda __: defer.ensureDeferred(self._postMemoryInit())) |
176 | 175 |
177 @property | 176 @property |
178 def version(self): | 177 def version(self): |
179 """Return the short version of SàT""" | 178 """Return the short version of SàT""" |
180 return C.APP_VERSION | 179 return C.APP_VERSION |
200 | 199 |
201 @property | 200 @property |
202 def bridge_name(self): | 201 def bridge_name(self): |
203 return os.path.splitext(os.path.basename(self.bridge.__file__))[0] | 202 return os.path.splitext(os.path.basename(self.bridge.__file__))[0] |
204 | 203 |
205 def _postMemoryInit(self, ignore): | 204 async def _postMemoryInit(self): |
206 """Method called after memory initialization is done""" | 205 """Method called after memory initialization is done""" |
207 self.common_cache = cache.Cache(self, None) | 206 self.common_cache = cache.Cache(self, None) |
208 log.info(_("Memory initialised")) | 207 log.info(_("Memory initialised")) |
209 try: | 208 try: |
210 self._import_plugins() | 209 self._import_plugins() |
216 reason=str(e).decode("utf-8", "ignore") | 215 reason=str(e).decode("utf-8", "ignore") |
217 ) | 216 ) |
218 ) | 217 ) |
219 sys.exit(1) | 218 sys.exit(1) |
220 self._addBaseMenus() | 219 self._addBaseMenus() |
220 | |
221 self.initialised.callback(None) | 221 self.initialised.callback(None) |
222 log.info(_("Backend is ready")) | 222 log.info(_("Backend is ready")) |
223 | |
224 # profile autoconnection must be done after self.initialised is called because | |
225 # startSession waits for it. | |
226 autoconnect_dict = await self.memory.storage.getIndParamValues( | |
227 category='Connection', name='autoconnect_backend', | |
228 ) | |
229 profiles_autoconnect = [p for p, v in autoconnect_dict.items() if C.bool(v)] | |
230 if not self.trigger.point("profilesAutoconnect", profiles_autoconnect): | |
231 return | |
232 if profiles_autoconnect: | |
233 log.info(D_( | |
234 "Following profiles will be connected automatically: {profiles}" | |
235 ).format(profiles= ', '.join(profiles_autoconnect))) | |
236 connect_d_list = [] | |
237 for profile in profiles_autoconnect: | |
238 connect_d_list.append(defer.ensureDeferred(self.connect(profile))) | |
239 | |
240 if connect_d_list: | |
241 results = await defer.DeferredList(connect_d_list) | |
242 for idx, (success, result) in enumerate(results): | |
243 if not success: | |
244 profile = profiles_autoconnect[0] | |
245 log.warning( | |
246 _("Can't autoconnect profile {profile}: {reason}").format( | |
247 profile = profile, | |
248 reason = result) | |
249 ) | |
223 | 250 |
224 def _addBaseMenus(self): | 251 def _addBaseMenus(self): |
225 """Add base menus""" | 252 """Add base menus""" |
226 encryption.EncryptionHandler._importMenus(self) | 253 encryption.EncryptionHandler._importMenus(self) |
227 | 254 |
405 defers_list.append(defer.maybeDeferred(unload)) | 432 defers_list.append(defer.maybeDeferred(unload)) |
406 return defers_list | 433 return defers_list |
407 | 434 |
408 def _connect(self, profile_key, password="", options=None): | 435 def _connect(self, profile_key, password="", options=None): |
409 profile = self.memory.getProfileName(profile_key) | 436 profile = self.memory.getProfileName(profile_key) |
410 return self.connect(profile, password, options) | 437 return defer.ensureDeferred(self.connect(profile, password, options)) |
411 | 438 |
412 def connect(self, profile, password="", options=None, max_retries=C.XMPP_MAX_RETRIES): | 439 async def connect( |
440 self, profile, password="", options=None, max_retries=C.XMPP_MAX_RETRIES): | |
413 """Connect a profile (i.e. connect client.component to XMPP server) | 441 """Connect a profile (i.e. connect client.component to XMPP server) |
414 | 442 |
415 Retrieve the individual parameters, authenticate the profile | 443 Retrieve the individual parameters, authenticate the profile |
416 and initiate the connection to the associated XMPP server. | 444 and initiate the connection to the associated XMPP server. |
417 @param profile: %(doc_profile)s | 445 @param profile: %(doc_profile)s |
425 @raise exceptions.PasswordError: Profile password is wrong | 453 @raise exceptions.PasswordError: Profile password is wrong |
426 """ | 454 """ |
427 if options is None: | 455 if options is None: |
428 options = {} | 456 options = {} |
429 | 457 |
430 def connectProfile(__=None): | 458 await self.memory.startSession(password, profile) |
431 if self.isConnected(profile): | 459 |
432 log.info(_("already connected !")) | 460 if self.isConnected(profile): |
433 return True | 461 log.info(_("already connected !")) |
434 | 462 return True |
435 if self.memory.isComponent(profile): | 463 |
436 d = xmpp.SatXMPPComponent.startConnection(self, profile, max_retries) | 464 if self.memory.isComponent(profile): |
437 else: | 465 await xmpp.SatXMPPComponent.startConnection(self, profile, max_retries) |
438 d = xmpp.SatXMPPClient.startConnection(self, profile, max_retries) | 466 else: |
439 return d.addCallback(lambda __: False) | 467 await xmpp.SatXMPPClient.startConnection(self, profile, max_retries) |
440 | 468 |
441 d = self.memory.startSession(password, profile) | 469 return False |
442 d.addCallback(connectProfile) | |
443 return d | |
444 | 470 |
445 def disconnect(self, profile_key): | 471 def disconnect(self, profile_key): |
446 """disconnect from jabber server""" | 472 """disconnect from jabber server""" |
447 # FIXME: client should not be deleted if only disconnected | 473 # FIXME: client should not be deleted if only disconnected |
448 # it shoud be deleted only when session is finished | 474 # it shoud be deleted only when session is finished |