'Schedule a task to run every friday, but avoid to run it twice if it's done and computer rebooted on friday + do it next day if computer off on friday
I've tried to schedule a specific task with Python with various methods:
- rolling my own scheduling (with
time.sleep(3600)
and check every hour), see below - trying libraries like schedule
but it seems it's not easy to have this: I'd like a task to run once every friday with these 2 conditions:
- if it's done and I reboot the computer (or restart the Python script) on friday, I don't want the task to run a second time the same day
- if the computer is off on friday, and I start it on saturday, the task should run (because then, it has not already been run this week).
How to do this in a nice way with Python?
NB: I'd like to avoid to use the Windows Task Scheduler or a wrapper around it
NB2: The Python script that schedules the task starts automatically on Windows startup.
Here is what I've tried, but it's not very elegant, and does not meet requirement 2. Moreover rolling my own scheduling is probably not optimal, I'm looking for something "higher-level".
try:
with open('last.run', 'r') as f:
lastrun = int(f.read())
except:
lastrun = -1
while True:
t = datetime.datetime.now()
if t.weekday() == 4 and t.day != lastrun:
result = doit() # do the task
if result:
with open('last.run', 'w') as f:
f.write(str(t.day))
print('sleeping...')
time.sleep(3600)
Solution 1:[1]
Since requirement 2 can be rephrased as "if the computer is off on a Friday, the task should run the next time the computer is on"
, then what you need to implement is simply:
- Figure out the date when the task should run next time.
- Inside an endless loop:
- if today is equal or greater than when the task should run next time:
- run task and then (if successful) update when task should run to next Friday after today.
Note that since it can happen that the task was supposed to run on a Friday that was the last day of it's month, then the whole date needs to be stored, not just the day of the month.
To calculate the date of next Friday, see currently highest rated answer of how-to-calculate-next-friday
try:
with open('next.run', 'r') as f:
nextrun = datetime.date.fromordinal(int(f.read()))
except:
# Calculate date of next Friday (including today if today is indeed a Friday)
today = datetime.date.today()
nextrun = today + datetime.timedelta( (4 - today.weekday()) % 7 )
while True:
today = datetime.date.today()
if today >= nextrun:
result = doit() # do the task
if result:
# Calculate date of next Friday after today (the day after next Thursday)
daysuntilnext = (3 - today.weekday()) % 7) + 1
nextrun = today + datetime.timedelta(daysuntilnext)
with open('next.run', 'w') as f:
f.write(str(nextrun.toordinal()))
# Optional: sleep for (daysuntilnext - 1) days
print('sleeping...')
time.sleep(3600)
Solution 2:[2]
Just save the date when you run the script in a date-time object - with pickle or in a txtfile, or in a database-, make a function that runs in a deamon thread if you want to it parrallel ( or/and use celery or "Python | Schedule Library" to run a tasks on friday. When it is friday your function checks the difference (called delta in date.time) between the date now and the date you saved earlyer, and if the diffence > 6 you run the script and save the date again.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | SiggiSv |
Solution 2 | Leo Hanhart |