Exemple #1
0
 def difficulty(self, value):
     if value not in self.difficulties:
         logger.warning("Difficulty {} not in {}: skipping".format(
             value, ", ".join(self.difficulties)))
     else:
         logger.debug("Setting difficulty to {}".format(value))
         self._difficulty = value
Exemple #2
0
    def status(self, value):
        if value not in self.STATUSES:
            logger.warning("Status {} not in {}: skipping".format(
                value, ", ".join(self.STATUSES)))
            return

        if value == self.status:
            logger.debug("Status is already {}: skipping".format(value))
            return

        logger.debug("Setting status to {}".format(value))
        self._status = value

        if self._status == "inactive":
            self.skip_skippable_animations()

            if self.unskippable_animation_task and self.unskippable_animation_task.active(
            ):
                self.unskippable_animation_task.cancel()
            self.on_inactive()

        elif self._status == "playing":
            self.skip_skippable_animations()

            if self.unskippable_animation_task and self.unskippable_animation_task.active(
            ):
                self.unskippable_animation_task.cancel()
            self.on_playing()

        elif self._status == "success":
            self.on_success()
Exemple #3
0
 def cancel_looping_task(self):
     if self.looping_task is not None:
         logger.debug('Cancelling looping task')
         try:
             self.looping_task.cancel()
         except Exception as e:
             logger.warning("Could not cancel looping task (reason={})".format(e))
Exemple #4
0
    def status(self, value):
        if value not in self.STATUSES:
            logger.warning("Status {} not in {}: skipping".format(
                value, ", ".join(self.STATUSES)))
            return

        if value == self.status:
            logger.debug("Status is already {}: skipping".format(value))
            return

        logger.debug("Setting status to {}".format(value))
        self._status = value

        for task_name, task in self.tasks.items():
            if task.active():
                task.cancel()
        self.tasks = {}

        if self._status == "chaos":
            self.on_chaos()
        elif self._status == "mute":
            self.on_mute()
        elif self._status == "playing":
            self.on_playing()
        elif self._status == "success":
            self.on_success()
Exemple #5
0
    def onMessage(self, payload, isBinary):
        if isBinary:
            logger.warning(
                "Binary message received ({} bytes): ignoring".format(
                    len(payload)))
            return

        try:
            unicode_message = payload.decode('utf8')
        except UnicodeDecodeError:
            logger.exception("Cannot decode {}: ignoring".format(payload))
            return

        try:
            message = json.loads(unicode_message)
        except json.JSONDecodeError:
            logger.exception(
                "Cannot load {}: ignoring".format(unicode_message))
            return

        ok, warning = self.validate_message(message)
        if not ok:
            logger.info("Received {}".format(message))
            logger.warning(warning)
            logger.info("Ignoring")
        else:
            logger.debug("Received {}".format(message))
            self.log_message(message, to_server=False)
            self.factory.process_event(message[P.EVENT])
Exemple #6
0
 def cancel_release_task(self):
     logger.debug('Cancelling release task')
     try:
         self.release_task.cancel()
     except Exception as e:
         logger.warning(
             "Could not cancel release task (reason={})".format(e))
Exemple #7
0
    def action_set_variable(self, arguments, paragraphs, context):
        variable_name = arguments['variable']['variable']
        if type(self.variables[variable_name]) is Timer:
            logger.warning("set_variable action is not supported for timer variables")
            return
        computed_value = self.compute(arguments['value'], context)

        self.variables[variable_name] = computed_value
Exemple #8
0
    def fetch_and_init_rules(self):
        scenario_rules = requests.get(
            '{}/get_scenario/'.format(self.storage_url),
            params={'room_id': self.room_id},
        ).json()

        self.rule_definitions = scenario_rules['rules']

        for trigger_type in self.on_trigger_type_rules:
            self.on_trigger_type_rules[trigger_type] = []
        self.timers = set()

        self.variables = {}
        variable_definitions = scenario_rules['variables']
        for variable in variable_definitions:
            if variable['type'] == 'timer':
                context = {R.CONTEXT_EXPIRING_TIMER: variable['name']}
                init_value = Timer(
                    self,
                    0, False,
                    self.process_rules, [], context,
                )
            else:
                init_value = variable['init_value']
            self.variables[variable['name']] = init_value

        for rule in self.rule_definitions:
            for trigger in rule['content']['triggers']:
                if trigger['template'] in self.on_trigger_type_rules:
                    self.on_trigger_type_rules[trigger['template']].append(
                        {
                            "trigger": trigger,
                            "rule": rule,
                        }
                    )
                elif trigger['template'] == 'timed_trigger':
                    self.timers.add(
                        Timer(
                            self,
                            trigger['arguments']['session_time'], False,
                            self.process_rule, rule, {},
                        )
                    )
                elif trigger['template'] == 'periodic_trigger':
                    self.timers.add(
                        Timer(
                            self,
                            trigger['arguments']['period'], True,
                            self.process_rule, rule, {},
                        )
                    )
                elif trigger['template'] == 'timer_trigger':
                    variable_timer_name = trigger['arguments']['timer']['variable']
                    self.variables[variable_timer_name].callback_args[0].append(rule)
                else:
                    logger.warning("Unknown trigger type {}: skipping".format(trigger['template']))
Exemple #9
0
    def __init__(self, *args, **kwargs):
        super(SoundPlayer, self).__init__(*args, **kwargs)

        initial_master_volume = self.node_params.get('master_volume', None)
        master_volume_mixer = self.node_params.get('mixer', '')
        default_initial_volume = self.node_params.get('default_volume', 100)

        player = self.node_params.get('player', 'pyglet')
        if player == 'vlc':
            self.sound_player = self.vlc_play_sound
        elif player == 'pyglet':
            self.sound_player = self.pyglet_play_sound
            self.pyglet_players = []
            loop = LoopingCall(self.pyglet_loop)
            loop.start(1 / 30)
        else:
            raise ValueError(
                "Bad player value ({}). Possible values are vlc or "
                "pyglet.".format(player))

        try:
            self.master_volume = MasterVolume(
                initial_volume=initial_master_volume,
                mixer=master_volume_mixer,
            )
        except Exception:
            logger.exception()
            logger.warning(
                "Unable to initialize the master volume controller. Further "
                "actions on the master volume will be ignored.")
            self.master_volume = None

        self.sounds = {}
        for sound in self.node_params.get('sounds', []):
            id_ = sound['id']
            path = sound['path']
            volume = sound.get('volume', default_initial_volume)

            if player == 'vlc':
                media = vlc.Media(path)
                media.parse()
                # / 1000 because we will be interested by the value in seconds
                duration = media.get_duration() / 1000
                self.sounds[id_] = {
                    'media': media,
                    'duration': duration,
                    'volume': volume,
                }
            else:
                media = pyglet.media.load(path, streaming=False)
                self.sounds[id_] = {
                    'media': media,
                    'volume': volume,
                }
Exemple #10
0
    def __init__(self, *args, **kwargs):
        super(MusicPlayer, self).__init__(*args, **kwargs)

        initial_master_volume = self.node_params.get('master_volume', None)
        master_volume_mixer = self.node_params.get('mixer', '')
        default_initial_volume = self.node_params.get('default_volume', 100)

        player = self.node_params.get('player', 'vlc')
        if player == 'vlc':
            track_handler = VLCSelfReleasingTrackPlayer
            looping_track_handler = VLCLoopingTrackPlayer
        elif player == 'pyglet':
            track_handler = PygletTrackPlayer
            looping_track_handler = PygletLoopingTrackPlayer
            loop = LoopingCall(self.pyglet_loop)
            loop.start(1 / 30)
        else:
            raise ValueError(
                "Bad player value ({}). Possible values are vlc or "
                "pyglet.".format(player))

        try:
            self.master_volume = MasterVolume(
                initial_volume=initial_master_volume,
                mixer=master_volume_mixer,
            )
        except Exception:
            logger.exception()
            logger.warning(
                "Unable to initialize the master volume controller. Further "
                "actions on the master volume will be ignored.")
            self.master_volume = None

        self.tracks = {}
        for track in self.node_params.get('tracks', []):
            id_ = track['id']
            path = track['path']
            volume = track.get('volume', default_initial_volume)
            mode = track.get('mode', 'one_shot')
            if mode == 'loop':
                loop_a = track['loop_a']
                loop_b = track['loop_b']
                handler = looping_track_handler(
                    media_path=path,
                    loop_a=loop_a,
                    loop_b=loop_b,
                    initial_volume=volume,
                )
            else:
                handler = track_handler(
                    media_path=path,
                    initial_volume=volume,
                )
            self.tracks[id_] = handler
Exemple #11
0
 def send_to_node(self, name, channel, event):
     nodes = self.nodes.get((
         name,
         channel,
     ), [])
     if nodes:
         for node in nodes:
             node.send_event(event)
     else:
         logger.warning(
             "Node {}@{} is not registered: skipping event".format(
                 name, channel))
Exemple #12
0
 def pause(self):
     if self.task and self.task.active() and self.processor.state == STATE_TICKING:
         now = time.monotonic()
         delta_since_last_schedule = now - self.last_schedule_timestamp
         if delta_since_last_schedule > self.last_computed_delay:
             logger.warning(
                 "Timer precision issue (now={}, last_schedule_timestamp={}, delta={}, last_computed_delay={}): "
                 "rounding last_computed_delay to 0".format(
                     now, self.last_schedule_timestamp, delta_since_last_schedule, self.last_computed_delay
                 )
             )
             self.last_computed_delay = 0
         else:
             self.last_computed_delay -= delta_since_last_schedule
         self.task.cancel()
Exemple #13
0
    def fetch_and_init_rules(self):
        rule_sets = requests.get(
            '{}/get_rules_from_room_id/?room_id={}'.format(
                self.storage_url, self.room_id)).json()

        activated_rules = []
        activated_variables = []
        for rule_set in rule_sets:
            activated_rules.extend(rule_set['rules'])
            activated_variables.extend(rule_set['variables'])

        self.rule_definitions = activated_rules

        for trigger_type in self.on_trigger_type_rules:
            self.on_trigger_type_rules[trigger_type] = []
        self.timers = set()

        self.variables = {}
        for variable in activated_variables:
            if variable['type'] == 'timer':
                context = {R.CONTEXT_EXPIRING_TIMER: variable['name']}
                init_value = Timer(
                    self,
                    0,
                    False,
                    self.process_rules,
                    [],
                    context,
                )
            else:
                init_value = variable['init_value']
            self.variables[variable['name']] = init_value

        for rule in self.rule_definitions:
            for trigger in rule['content']['triggers']:
                if trigger['template'] in self.on_trigger_type_rules:
                    self.on_trigger_type_rules[trigger['template']].append({
                        "trigger":
                        trigger,
                        "rule":
                        rule,
                    })
                elif trigger['template'] == 'timed_trigger':
                    self.timers.add(
                        Timer(
                            self,
                            trigger['arguments']['session_time'],
                            False,
                            self.process_rule,
                            rule,
                            {},
                        ))
                elif trigger['template'] == 'periodic_trigger':
                    self.timers.add(
                        Timer(
                            self,
                            trigger['arguments']['period'],
                            True,
                            self.process_rule,
                            rule,
                            {},
                        ))
                elif trigger['template'] == 'timer_trigger':
                    variable_timer_name = trigger['arguments']['timer'][
                        'variable']
                    self.variables[variable_timer_name].callback_args[
                        0].append({
                            "trigger": {},
                            "rule": rule,
                        })
                else:
                    logger.warning("Unknown trigger type {}: skipping".format(
                        trigger['template']))

        self.buttons = {}

        cards = requests.get('{}/get_cards_from_room_id/?room_id={}'.format(
            self.storage_url, self.room_id)).json()
        for card in cards:
            card_rows = requests.get('{}/card_row/?card={}'.format(
                self.storage_url, card['id'])).json()
            for row in card_rows:
                if row['widget'] == 'buttons_group':
                    for button in row['widget_params']:
                        self.buttons[button['id']] = button
Exemple #14
0
    def onMessage(self, payload, isBinary):
        if isBinary:
            logger.warning(
                "Binary message received ({} bytes): ignoring".format(
                    len(payload)))
            return

        try:
            unicode_message = payload.decode('utf8')
        except UnicodeDecodeError:
            logger.exception("Cannot load {}: ignoring".format(payload))
            return

        try:
            message = json.loads(unicode_message)
        except json.JSONDecodeError:
            logger.exception(
                "Cannot load {}: ignoring".format(unicode_message))
            return

        ok, warning = self.validate_message(message)
        if not ok:
            logger.info("Received {}".format(message))
            logger.warning(warning)
            logger.info("Ignoring")
        else:
            logger.debug("Received {}".format(message))

            self.log_message(message, to_server=True)

            if self.client_type == P.CLIENT_NODE:
                if message[P.MESSAGE_TYPE] == P.MESSAGE_TYPE_EVENT:
                    event = message[P.EVENT]
                    self.factory.process_event(self.name, self.channel, event)
                elif message[P.MESSAGE_TYPE] == P.MESSAGE_TYPE_LOG:
                    level = message[P.LOG_LEVEL]
                    content = message[P.LOG_CONTENT]
                    if level == P.LOG_LEVEL_INFO:
                        self.factory.send_log_info(content)
                    elif level == P.LOG_LEVEL_ERROR:
                        self.factory.send_log_error(content)

            elif self.client_type == P.CLIENT_ADMIN:
                room_id = message[P.ROOM_ID]

                if message[P.MESSAGE_TYPE] == P.MESSAGE_TYPE_RUN:
                    self.factory.process_run_room(room_id)
                elif message[P.MESSAGE_TYPE] == P.MESSAGE_TYPE_HALT:
                    self.factory.process_halt_room(room_id)
                elif message[P.MESSAGE_TYPE] == P.MESSAGE_TYPE_RESET:
                    self.factory.process_reset_room(room_id)
                elif message[P.MESSAGE_TYPE] == P.MESSAGE_TYPE_SEND_EVENT_TO:
                    node = message[P.SEND_EVENT_NODE]
                    event_to_send = message[P.EVENT]
                    self.factory.process_send_event_to(room_id, node,
                                                       event_to_send)
                elif message[P.MESSAGE_TYPE] == P.MESSAGE_TYPE_SEND_EVENT_AS:
                    node = message[P.SEND_EVENT_NODE]
                    event_to_send = message[P.EVENT]
                    self.factory.process_send_event_as(room_id, node,
                                                       event_to_send)
                elif message[
                        P.MESSAGE_TYPE] == P.MESSAGE_TYPE_PRESSED_ADMIN_BUTTON:
                    button_id = message[P.PRESSED_BUTTON_ID]
                    self.factory.process_on_admin_button_pressed(
                        room_id, button_id)

            else:
                self.process_i_am_message(message)