forked from agronholm/apscheduler
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added combining triggers (AndTrigger + OrTrigger)
Fixes agronholm#119.
- Loading branch information
Showing
7 changed files
with
205 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
from apscheduler.triggers.base import BaseTrigger | ||
from apscheduler.util import obj_to_ref, ref_to_obj | ||
|
||
|
||
class BaseMultiTrigger(BaseTrigger): | ||
__slots__ = 'triggers' | ||
|
||
def __init__(self, triggers): | ||
self.triggers = triggers | ||
|
||
def __getstate__(self): | ||
return { | ||
'version': 1, | ||
'triggers': [(obj_to_ref(trigger.__class__), trigger.__getstate__()) | ||
for trigger in self.triggers] | ||
} | ||
|
||
def __setstate__(self, state): | ||
if state.get('version', 1) > 1: | ||
raise ValueError( | ||
'Got serialized data for version %s of %s, but only versions up to 1 can be ' | ||
'handled' % (state['version'], self.__class__.__name__)) | ||
|
||
self.triggers = [] | ||
for clsref, state in state['triggers']: | ||
cls = ref_to_obj(clsref) | ||
trigger = cls.__new__(cls) | ||
trigger.__setstate__(state) | ||
self.triggers.append(trigger) | ||
|
||
def __repr__(self): | ||
return '<{}({})>'.format(self.__class__.__name__, self.triggers) | ||
|
||
|
||
class AndTrigger(BaseMultiTrigger): | ||
""" | ||
Always returns the earliest next fire time that all the given triggers can agree on. | ||
The trigger is considered to be finished when any of the given triggers has finished its | ||
schedule. | ||
Trigger alias: ``and`` | ||
:param list triggers: triggers to combine | ||
""" | ||
|
||
__slots__ = () | ||
|
||
def get_next_fire_time(self, previous_fire_time, now): | ||
while True: | ||
fire_times = [trigger.get_next_fire_time(previous_fire_time, now) | ||
for trigger in self.triggers] | ||
if None in fire_times: | ||
return None | ||
elif min(fire_times) == max(fire_times): | ||
return fire_times[0] | ||
else: | ||
now = max(fire_times) | ||
|
||
def __str__(self): | ||
return 'and[{}]'.format(', '.join(str(trigger) for trigger in self.triggers)) | ||
|
||
|
||
class OrTrigger(BaseMultiTrigger): | ||
""" | ||
Always returns the earliest next fire time produced by any of the given triggers. | ||
The trigger is considered finished when all the given triggers have finished their schedules. | ||
Trigger alias: ``or`` | ||
:param list triggers: triggers to combine | ||
.. note:: Triggers that depends on the previous fire time, such as the interval trigger, may | ||
seem to behave strangely since they are always passed the previous fire time produced by | ||
any of the given triggers. | ||
""" | ||
|
||
__slots__ = () | ||
|
||
def get_next_fire_time(self, previous_fire_time, now): | ||
fire_times = [trigger.get_next_fire_time(previous_fire_time, now) | ||
for trigger in self.triggers] | ||
fire_times = [fire_time for fire_time in fire_times if fire_time is not None] | ||
return min(fire_times) if fire_times else None | ||
|
||
def __str__(self): | ||
return 'or[{}]'.format(', '.join(str(trigger) for trigger in self.triggers)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
:mod:`apscheduler.triggers.combining` | ||
===================================== | ||
|
||
These triggers combine the behavior of other triggers in different ways to produce schedules more | ||
complex than would be possible with any single built-in trigger. | ||
|
||
.. automodule:: apscheduler.triggers.combining | ||
|
||
API | ||
--- | ||
|
||
.. autoclass:: AndTrigger | ||
|
||
.. autoclass:: OrTrigger | ||
|
||
|
||
Examples | ||
-------- | ||
|
||
Run ``job_function`` every 2 hours, but only on Saturdays and Sundays:: | ||
|
||
from apscheduler.triggers.combining import AndTrigger | ||
from apscheduler.triggers.interval import IntervalTrigger | ||
from apscheduler.triggers.cron import CronTrigger | ||
|
||
|
||
trigger = AndTrigger([IntervalTrigger(hours=2), | ||
CronTrigger(day_of_week='sat,sun')]) | ||
scheduler.add_job(job_function, trigger) | ||
|
||
Run ``job_function`` every Monday at 2pm and every Tuesday at 3pm:: | ||
|
||
trigger = OrTrigger([CronTrigger(day_of_week='mon', hour=2), | ||
CronTrigger(day_of_week='tue', hour=3)]) | ||
scheduler.add_job(job_function, trigger) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters