def build(cls, name, hook): """ Builds a rule given either another EventRule, a dictionary or a JSON UTF-8 encoded string/bytearray """ if isinstance(hook, cls): return hook else: hook = parse(hook) if is_functional_hook(hook): actions = Procedure(name=name, requests=[hook], _async=False) return cls(name=name, condition=hook.condition, actions=actions) assert isinstance(hook, dict) condition = EventCondition.build(hook['if']) if 'if' in hook else None actions = [] priority = hook['priority'] if 'priority' in hook else None condition.priority = priority if 'then' in hook: if isinstance(hook['then'], list): actions = hook['then'] else: actions = [hook['then']] actions = Procedure.build(name=name + '__Hook', requests=actions, _async=False) return cls(name=name, condition=condition, actions=actions, priority=priority)
def __init__(self, when: str, actions: Optional[list] = None, name: Optional[str] = None, audio_file: Optional[str] = None, audio_plugin: Optional[str] = None, audio_volume: Optional[Union[int, float]] = None, snooze_interval: float = 300.0, enabled: bool = True): with self._id_lock: self._alarms_count += 1 self.id = self._alarms_count self.when = when self.name = name or 'Alarm_{}'.format(self.id) self.audio_file = None if audio_file: self.audio_file = os.path.abspath(os.path.expanduser(audio_file)) assert os.path.isfile( self.audio_file), 'No such audio file: {}'.format( self.audio_file) self.audio_plugin = audio_plugin self.audio_volume = audio_volume self.snooze_interval = snooze_interval self.state: Optional[AlarmState] = None self.timer: Optional[threading.Timer] = None self.actions = Procedure.build(name=name, _async=False, requests=actions or [], id=self.id) self._enabled = enabled self._runtime_snooze_interval = snooze_interval
def _execute_procedure(self, *args, **kwargs): from platypush.config import Config from platypush.procedure import Procedure logger.info('Executing procedure request: {}'.format(self.action)) procedures = Config.get_procedures() proc_name = '.'.join(self.action.split('.')[1:]) if proc_name not in procedures: proc_name = self.action.split('.')[-1] proc_config = procedures[proc_name] if is_functional_procedure(proc_config): kwargs.update(**self.args) if 'n_tries' in kwargs: del kwargs['n_tries'] return proc_config(*args, **kwargs) proc = Procedure.build(name=proc_name, requests=proc_config['actions'], _async=proc_config['_async'], args=self.args, backend=self.backend, id=self.id) return proc.execute(*args, **kwargs)
def __init__(self, name, cron_expression, actions): super().__init__() self.cron_expression = cron_expression self.name = name self.state = CronjobState.IDLE self.actions = Procedure.build(name=name + '__Cron', _async=False, requests=actions)
def __init__(self, name, cron_expression, actions): super().__init__() self.cron_expression = cron_expression self.name = name self.state = CronjobState.IDLE self._should_stop = threading.Event() if isinstance(actions, dict) or isinstance(actions, list): self.actions = Procedure.build(name=name + '__Cron', _async=False, requests=actions) else: self.actions = actions
def _execute_procedure(self, *args, **kwargs): from platypush.config import Config from platypush.procedure import Procedure logger.info('Executing procedure request: {}'.format(self.action)) proc_name = self.action.split('.')[-1] proc_config = Config.get_procedures()[proc_name] proc = Procedure.build(name=proc_name, requests=proc_config['actions'], _async=proc_config['_async'], args=self.args, backend=self.backend, id=self.id) return proc.execute(*args, **kwargs)
def set_interval(self, seconds, actions, name=None, **args): """ Define a set of actions to run each specified amount of `seconds`. :param seconds: Number of seconds between two runs of the interval procedure :type seconds: float :param actions: List of actions to be executed at each interval :type actions: list[dict] :param name: Set an optional name for this interval. It is advised to set a name if you are planning to programmatically cancel the interval in your business logic. :type name: str :param args: Optional arguments/context to pass to the interval function """ with self._interval_hndl_idx_lock: self._interval_hndl_idx += 1 if not name: name = self._DEFAULT_INTERVAL_PREFIX + \ str(self._interval_hndl_idx) if name in self._pending_intervals: return ( None, "An interval named '{}' is already running".format(name)) procedure = Procedure.build(name=name, requests=actions, _async=False) self._pending_intervals[name] = procedure def _proc_wrapper(procedure, seconds, **kwargs): while True: with self._pending_intervals_lock: if name not in self._pending_intervals: return procedure.execute(**kwargs) time.sleep(seconds) with self._pending_intervals_lock: self._pending_intervals[name] = threading.Thread( target=_proc_wrapper, args=[procedure, seconds], kwargs=args) self._pending_intervals[name].start()
def set_timeout(self, seconds, actions, name=None, **args): """ Define a set of actions to run after the specified amount of `seconds`. :param seconds: Number of seconds before running the timeout procedure :type seconds: float :param actions: List of actions to be executed after the timeout expires :type actions: list[dict] :param name: Set an optional name for this timeout. It is advised to set a name if you are planning to programmatically cancel the timeout in your business logic. :type name: str :param args: Optional arguments/context to pass to the timeout function """ with self._timeout_hndl_idx_lock: self._timeout_hndl_idx += 1 if not name: name = self._DEFAULT_TIMEOUT_PREFIX + str( self._timeout_hndl_idx) if name in self._pending_timeouts: return ( None, "A timeout named '{}' is already awaiting".format(name)) procedure = Procedure.build(name=name, requests=actions, _async=False) self._pending_timeouts[name] = procedure def _proc_wrapper(procedure, **kwargs): try: procedure.execute(**kwargs) finally: with self._pending_timeouts_lock: if name in self._pending_timeouts: del self._pending_timeouts[name] with self._pending_timeouts_lock: self._pending_timeouts[name] = threading.Timer(seconds, _proc_wrapper, args=[procedure], kwargs=args) self._pending_timeouts[name].start()