# Copyright (C) 2018 Avatao.com Innovative Learning Kft. # All Rights Reserved. See LICENSE file for details. from tfw import EventHandlerBase from tfw.crypto import KeyManager, sign_message from tfw.config.logs import logging LOG = logging.getLogger(__name__) class FSMManagingEventHandler(EventHandlerBase): def __init__(self, key, fsm_type): super().__init__(key) self.fsm = fsm_type() self._fsm_updater = FSMUpdater(self.fsm) self.auth_key = KeyManager().auth_key self.command_handlers = { 'trigger': self.handle_trigger, 'update': self.handle_update } def handle_event(self, message): try: data = message['data'] message['data'] = self.command_handlers[data['command']](data) fsm_update_message = self._fsm_updater.generate_fsm_update() sign_message(self.auth_key, message) sign_message(self.auth_key, fsm_update_message) self.server_connector.broadcast(fsm_update_message) return message except KeyError: LOG.error('IGNORING MESSAGE: Invalid message received: %s', message) def handle_trigger(self, data): trigger = data['value'] self.fsm.step(trigger) return data def handle_update(self, data): # pylint: disable=no-self-use return data class FSMUpdater: def __init__(self, fsm): self.fsm = fsm def generate_fsm_update(self): return { 'key': 'fsm_update', 'data': self.get_fsm_state_and_transitions() } def get_fsm_state_and_transitions(self): state = self.fsm.state valid_transitions = [ {'trigger': trigger} for trigger in self.fsm.get_triggers(self.fsm.state) ] last_trigger = self.fsm.trigger_history[-1] if self.fsm.trigger_history else None in_accepted_state = state in self.fsm.accepted_states return { 'current_state': state, 'valid_transitions': valid_transitions, 'last_trigger': last_trigger, 'in_accepted_state': in_accepted_state }