diff --git a/platypush/backend/alarm.py b/platypush/backend/alarm.py index 7b0863512..c3e8635a2 100644 --- a/platypush/backend/alarm.py +++ b/platypush/backend/alarm.py @@ -57,8 +57,12 @@ class Alarm: try: cron = croniter.croniter(self.when, now) return cron.get_next() - except croniter.CroniterBadCronError: - timestamp = datetime.datetime.fromisoformat(self.when).timestamp() + except (AttributeError, croniter.CroniterBadCronError): + try: + timestamp = datetime.datetime.fromisoformat(self.when).timestamp() + except (TypeError, ValueError): + timestamp = (datetime.datetime.now() + datetime.timedelta(seconds=int(self.when))).timestamp() + return timestamp if timestamp >= now else None def is_enabled(self): @@ -223,8 +227,13 @@ class AlarmBackend(Backend): def add_alarm(self, when: str, actions: list, name: Optional[str] = None, audio_file: Optional[str] = None, enabled: bool = True) -> Alarm: - alarm = Alarm(when=when, actions=actions, name=name, enabled=enabled, audio_file=audio_file) - assert alarm.name not in self.alarms, 'Alarm {} already exists'.format(alarm.name) + alarm = Alarm(when=when, actions=actions, name=name, enabled=enabled, audio_file=audio_file, + audio_plugin=self.audio_plugin) + + if alarm.name in self.alarms: + self.logger.info('Overwriting existing alarm {}'.format(alarm.name)) + self.alarms[alarm.name].stop() + self.alarms[alarm.name] = alarm self.alarms[alarm.name].start() return self.alarms[alarm.name] diff --git a/platypush/plugins/alarm.py b/platypush/plugins/alarm.py index df16000fd..896c82b6b 100644 --- a/platypush/plugins/alarm.py +++ b/platypush/plugins/alarm.py @@ -20,22 +20,23 @@ class AlarmPlugin(Plugin): return get_backend('alarm') @action - def add(self, when: str, actions: list, name: Optional[str] = None, audio_file: Optional[str] = None, - enabled: bool = True) -> str: + def add(self, when: str, actions: Optional[list] = None, name: Optional[str] = None, + audio_file: Optional[str] = None, enabled: bool = True) -> str: """ Add a new alarm. NOTE: alarms that aren't configured in the :class:`platypush.backend.alarm.AlarmBackend` will only run in the current session. If you want an alarm to be permanently stored, you should configure it in the alarm backend configuration. You may want to add an alarm dynamically if it's a one-time alarm instead :param when: When the alarm should be executed. It can be either a cron expression (for recurrent alarms), or - a datetime string in ISO format (for one-shot alarms/timers). + a datetime string in ISO format (for one-shot alarms/timers), or an integer representing the number of + seconds before the alarm goes on (e.g. 300 for 5 minutes). :param actions: List of actions to be executed. :param name: Alarm name. :param audio_file: Path of the audio file to be played. :param enabled: Whether the new alarm should be enabled (default: True). :return: The alarm name. """ - alarm = self._get_backend().add_alarm(when=when, audio_file=audio_file, actions=actions, + alarm = self._get_backend().add_alarm(when=when, audio_file=audio_file, actions=actions or [], name=name, enabled=enabled) return alarm.name