comparison libervia/frontends/quick_frontend/quick_app.py @ 4126:45e3bb8607d8

frontends (quick app): allow frontend to register an action handler: Some feature may need to handle directly some action, such as the incoming `A/V call` feature. rel 424
author Goffi <goffi@goffi.org>
date Tue, 03 Oct 2023 16:25:25 +0200
parents bb74f7dc3b10
children d01b8d002619
comparison
equal deleted inserted replaced
4125:bb74f7dc3b10 4126:45e3bb8607d8
14 # GNU Affero General Public License for more details. 14 # GNU Affero General Public License for more details.
15 15
16 # You should have received a copy of the GNU Affero General Public License 16 # You should have received a copy of the GNU Affero General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. 17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18 18
19 import sys
20 import time
21 from typing import Callable
22
23 from libervia.backend.core import exceptions
24 from libervia.backend.core.i18n import _
19 from libervia.backend.core.log import getLogger 25 from libervia.backend.core.log import getLogger
20 from libervia.backend.core.i18n import _
21 from libervia.backend.core import exceptions
22 from libervia.backend.tools import trigger 26 from libervia.backend.tools import trigger
23 from libervia.backend.tools.common import data_format 27 from libervia.backend.tools.common import data_format
24
25 from libervia.frontends.tools import jid
26 from libervia.frontends.quick_frontend import quick_widgets 28 from libervia.frontends.quick_frontend import quick_widgets
27 from libervia.frontends.quick_frontend import quick_menus 29 from libervia.frontends.quick_frontend import quick_menus
28 from libervia.frontends.quick_frontend import quick_blog 30 from libervia.frontends.quick_frontend import quick_blog
29 from libervia.frontends.quick_frontend import quick_chat, quick_games 31 from libervia.frontends.quick_frontend import quick_chat, quick_games
30 from libervia.frontends.quick_frontend import quick_contact_list 32 from libervia.frontends.quick_frontend import quick_contact_list
31 from libervia.frontends.quick_frontend.constants import Const as C 33 from libervia.frontends.quick_frontend.constants import Const as C
32 34 from libervia.frontends.tools import jid
33 import sys
34 import time
35 35
36 36
37 log = getLogger(__name__) 37 log = getLogger(__name__)
38 38
39 39
288 self._selected_widget = None 288 self._selected_widget = None
289 289
290 # listeners are callable watching events 290 # listeners are callable watching events
291 self._listeners = {} # key: listener type ("avatar", "selected", etc), 291 self._listeners = {} # key: listener type ("avatar", "selected", etc),
292 # value: list of callbacks 292 # value: list of callbacks
293
294 # cf. [register_action_handler]
295 self._action_handlers: dict[str, Callable[[dict, str, int, str], None]] = {}
293 296
294 # triggers 297 # triggers
295 self.trigger = ( 298 self.trigger = (
296 trigger.TriggerManager() 299 trigger.TriggerManager()
297 ) # trigger are used to change the default behaviour 300 ) # trigger are used to change the default behaviour
750 self.contact_lists[profile].disconnect() 753 self.contact_lists[profile].disconnect()
751 # FIXME: see note on connected_handler 754 # FIXME: see note on connected_handler
752 self.sync = False 755 self.sync = False
753 self.set_presence_status(C.PRESENCE_UNAVAILABLE, "", profile=profile) 756 self.set_presence_status(C.PRESENCE_UNAVAILABLE, "", profile=profile)
754 757
755 def action_new_handler(self, action_data_s, id_, security_limit, profile): 758 def action_new_handler(self, action_data_s, action_id, security_limit, profile):
756 self.action_manager( 759 action_data = data_format.deserialise(action_data_s)
757 data_format.deserialise(action_data_s), user_action=False, profile=profile 760 action_type = action_data.get("type")
758 ) 761 action_handler = self._action_handlers.get(action_type)
762 if action_handler is not None:
763 action_handler(action_data, action_id, security_limit, profile)
764 else:
765 self.action_manager(
766 action_data, user_action=False, profile=profile
767 )
759 768
760 def contact_new_handler(self, jid_s, attributes, groups, profile): 769 def contact_new_handler(self, jid_s, attributes, groups, profile):
761 entity = jid.JID(jid_s) 770 entity = jid.JID(jid_s)
762 groups = list(groups) 771 groups = list(groups)
763 self.contact_lists[profile].set_contact(entity, groups, attributes, in_roster=True) 772 self.contact_lists[profile].set_contact(entity, groups, attributes, in_roster=True)
1264 elif key == "avatar" and self.AVATARS_HANDLER: 1273 elif key == "avatar" and self.AVATARS_HANDLER:
1265 assert isinstance(value, dict) or value is None 1274 assert isinstance(value, dict) or value is None
1266 self.contact_lists[profile].set_cache(entity, "avatar", value) 1275 self.contact_lists[profile].set_cache(entity, "avatar", value)
1267 self.call_listeners("avatar", entity, value, profile=profile) 1276 self.call_listeners("avatar", entity, value, profile=profile)
1268 1277
1278 def register_action_handler(
1279 self,
1280 action_type: str,
1281 handler: Callable[[dict, str, int, str], None]
1282 ) -> None:
1283 """Register a handler for action type.
1284
1285 If an action of this type is received, the handler will be used, otherwise,
1286 generic ``action_manager`` is used
1287 @param action_type: type of action that the handler manage
1288 @param handler: method to call when an actipn of ``action_type`` is received.
1289 Will have following args:
1290 ``action_data``
1291 Data of the action.
1292 ``action_id``
1293 ID of the action.
1294 ``security_limit``
1295 Security limit, used to check if this action can be used in current security
1296 context.
1297 ``profile``
1298 Profile name.
1299 """
1300 if handler in self._action_handlers:
1301 raise exceptions.ConflictError(
1302 f"There is already a registered handler for {action_type} actions: "
1303 f"{handler}"
1304 )
1305 self._action_handlers[action_type] = handler
1306
1269 def action_manager(self, action_data, callback=None, ui_show_cb=None, user_action=True, 1307 def action_manager(self, action_data, callback=None, ui_show_cb=None, user_action=True,
1270 progress_cb=None, progress_eb=None, profile=C.PROF_KEY_NONE): 1308 progress_cb=None, progress_eb=None, profile=C.PROF_KEY_NONE):
1271 """Handle backend action 1309 """Handle backend action
1272 1310
1273 @param action_data(dict): action dict as sent by action_launch or returned by an 1311 @param action_data(dict): action dict as sent by action_launch or returned by an