lang/python/ PythonSchedule
python -m pip install schedule
see here at pypi and here at readthedocs. Summary
import schedule
import time
def job():
print("I'm working...")
schedule.every(10).seconds.do(job)
schedule.every(10).minutes.do(job)
schedule.every().hour.do(job)
schedule.every().day.at("10:30").do(job)
schedule.every(5).to(10).minutes.do(job)
schedule.every().monday.do(job)
schedule.every().wednesday.at("13:15").do(job)
schedule.every().minute.at(":17").do(job)
while True:
schedule.run_pending()
time.sleep(1)
aside
I wrote a very simple scheduling helper, named sleepuntil
where you'd run sleepuntil 03:45; cmd args...
.
It doesn't do any of the actual scheduling, rather it computes the number of seconds until the desired time
and sleeps that number of seconds. It is basically sleep
but with a calculator to work out the seconds.
It's very rough, since if I'm just writing for me, and the program is small, I don't care for
'software engineering best practices' — for me, the best way to manage code complexity is not to
have it in the first place: this is around 100 lines all in, and most of that is code for parsing and
printing times. At the time I wrote this, I wasn't aware of how f"{s:<50}"
, or f"{s^50}"
worked,
let alone f"{s:=^{w}}"
or x="*";f"{s:{x}^{w}"
. See AdvancedFormatStrings.
#!/usr/bin/python
import sys, os
from datetime import datetime
from time import sleep
args = sys.argv[1:]
if len(args) < 1 or len(args) > 2:
print("""sleepuntil time
where time has format 12:34""")
exit(1)
def parse_time(x):
a = x.split(":")
if len(a) < 2 or len(a) > 3:
raise ValueError("Time should be in the format hh:mm or hh:mm:ss")
if len(a) == 2:
h,m = map(int,a)
s = 0
else:
h,m,s = map(int,a)
return (h,m,s)
def format_secs(x):
s = x % 60
x //= 60
m = x % 60
x //= 60
if m > 0 or x > 0:
a = f"{s:02d}"
else:
return "{s}"
if x > 0:
a = f"{x}:{m:02d}:{a}"
else:
a = f"{m}:{a}"
return a
def compute_secs_until(x):
h,m,s = parse_time(x)
now = datetime.now()
h1 = now.hour
m1 = now.minute
s1 = now.second
secs = 3600*h+60*m+s
secs1 = 3600*h1+60*m1+s1
dt = secs - secs1
if dt < 0:
dt += 24*3600
return dt
def do_sleep():
try:
secs = compute_secs_until(args[0])
except Exception as e:
print(f"Exception {e}")
exit(1)
if len(args) > 1:
days = int(args[1])
secs += 24*3600*days
d = secs // (24*3600)
h = (secs % (24*3600)) // 3600
m = (secs % 3600) // 60
s = (secs % 60)
hms = []
if d > 0:
hms.append(f"{d} day")
if d != 1:
hms[-1] += "s"
if h > 0:
hms.append(f"{h} hour")
if h != 1:
hms[-1] += "s"
if m > 0:
hms.append(f"{m} minute")
if m != 1:
hms[-1] += "s"
if s > 0:
hms.append(f"{s} second")
if s != 1:
hms[-1] += "s"
if len(hms) == 0:
t = "0 seconds"
elif len(hms) == 1:
t = hms[0]
else:
hms1 = hms[:-1]
hms2 = hms[-1]
t = f"{', '.join(hms1)} and {hms2}"
try:
print(f"Sleeping {secs} seconds == {t}")
for s in range(secs):
cols = os.get_terminal_size().columns
tr = "Time remaining: "
a = f"{format_secs(secs-s)} == {secs-s} seconds"
if len(a) >= cols:
ostr = a
elif len(a) + len(tr) + 1 >= cols:
ostr = a + " " + "="*(cols - len(a) - 1)
else:
ostr = tr + a
ostr = ostr + " " + "="*(cols - len(ostr) - 1)
print(f"\r{ostr}",end="")
sleep(1)
except KeyboardInterrupt:
print("\nKeyboard Interrupt\n")
exit(1)
if __name__ == "__main__":
do_sleep()