/circuits/core/timers.py

https://bitbucket.org/prologic/circuits/ · Python · 89 lines · 41 code · 19 blank · 29 comment · 9 complexity · 67c00da65a35cc1fb2b056aa702d6c46 MD5 · raw file

  1. # Module: timers
  2. # Date: 04th August 2004
  3. # Author: James Mills <prologic@shortcircuit.net.au>
  4. """Timer component to facilitate timed events."""
  5. from circuits.core.handlers import handler
  6. from time import time, mktime
  7. from datetime import datetime
  8. from .components import BaseComponent
  9. class Timer(BaseComponent):
  10. """Timer Component
  11. A timer is a component that fires an event once after a certain
  12. delay or periodically at a regular interval.
  13. """
  14. def __init__(self, interval, event, *channels, **kwargs):
  15. """
  16. :param interval: the delay or interval to wait for until
  17. the event is fired. If interval is specified as
  18. datetime, the interval is recalculated as the
  19. time span from now to the given datetime.
  20. :type interval: ``datetime`` or number of seconds as a ``float``
  21. :param event: the event to fire.
  22. :type event: :class:`~.events.Event`
  23. :param persist: An optional keyword argument which if ``True``
  24. will cause the event to be fired repeatedly
  25. once per configured interval until the timer
  26. is unregistered. **Default:** ``False``
  27. :type persist: ``bool``
  28. """
  29. super(Timer, self).__init__()
  30. self.expiry = None
  31. self.interval = None
  32. self.event = event
  33. self.channels = channels
  34. self.persist = kwargs.get("persist", False)
  35. self.reset(interval)
  36. @handler("generate_events")
  37. def _on_generate_events(self, event):
  38. if self.expiry is None:
  39. return
  40. now = time()
  41. if now >= self.expiry:
  42. if self.unregister_pending:
  43. return
  44. self.fire(self.event, *self.channels)
  45. if self.persist:
  46. self.reset()
  47. else:
  48. self.unregister()
  49. event.reduce_time_left(0)
  50. else:
  51. event.reduce_time_left(self.expiry - now)
  52. def reset(self, interval=None):
  53. """
  54. Reset the timer, i.e. clear the amount of time already waited
  55. for.
  56. """
  57. if interval is not None and isinstance(interval, datetime):
  58. self.interval = mktime(interval.timetuple()) - time()
  59. elif interval is not None:
  60. self.interval = interval
  61. self.expiry = time() + self.interval
  62. @property
  63. def expiry(self):
  64. return getattr(self, "_expiry", None)
  65. @expiry.setter
  66. def expiry(self, seconds):
  67. self._expiry = seconds