I'm a python newbie and would like to develop a tiny application to
schedule a document to open in a text processor and ask a question.
I'd like to be able to give it multiple time:question pairs such as
(monday 1:00pm : "Please enter your completed tasks for the morning?).
It could just open a dialog box with a big text entry area and the
question, then append a text file after a submit command. I guess the
question is how to get it to run in the background and pop-up at the
appropriate times?
<cynical>If on a Windows box with Outlook, just create a whole bunch
of appointments in the calendar and, as long as Outlook is loaded, it
will pop up reminders</cynical>
The neophyte approach would probably be a long-running process of
the form:
-=-=-=-=-=- pseudocode, don't try to run
import time
import datetime #I can't recall if parsing routines are in time
taskFID = "task.dat"
# datafile containing time-ordered (pre-sorted) records of
# yyyymmdd hhmm | task description
resultFID = "the.log"
tf = open(taskFID, "r")
rf = open(resultFID, "a")
def doEvent(tm, des):
#pop-up dialog with "des", get "res"
#format "tm" into readable time
rf.write("%s\t%s\n\n%s" %
(rtm, des, res) )
rf.flush()
for t in tf:
(dttim, task) = t.split("|")
#parse dttim to get internal taskTime format (seconds?)
now = time.clock()
if taskTime > now:
time.sleep(taskTime - now)
doEvent(taskTime, description)
rf.close()
tf.close()
-=-=-=-=-=-=-
BUT, this has many drawbacks. ONE: the task list must be in
ascending time order. TWO: to modify the task list requires shutting
down this scheduler, editing the file (removing any "in the past"
expired events), restarting the scheduler. THREE: if the program stops
for any reason (if running as part of a user-specific start-up, and that
user logs off) you have to go back to step two to clean up and restart.
Much better would be, first, to replace the task list file with a
simple database (SQLite, say)... A simple table of:
table tasklist=
ID integer primary key
eTime datetime
description char
response char
expired boolean default False
Then, a simple program may be used to add/edit task records. Another
program could be used to produce a report later.
The scheduler /could/ be a monolithic loop as shown above, suitably
modified:
-=-=-=-=-=- pseudocode, don't try to run
import time
import datetime #I can't recall if parsing routines are in time
import db_adapter as db
con = db.connect("suitable parameters to access database table")
cur = con.cursor()
def doEvent(id, tm, des):
#pop-up dialog with "des", get "res" or CANCEL
if not CANCEL:
cur.execute("""update tasklist set
response = ?,
expired = True
where ID = ? """,
(res, id) )
con.commit()
while True:
now = time.clock() #or whatever is needed to create DB compatible
cur.execute("""select ID, eTime, description from tasklist
where not expired
and eTime <= ?
order by eTime""",
(now,) )
tasks = cur.fetchall() #fetch all to free cursor for updates
for t in tasks:
(id, taskTime, description) = t
doEvent(id, taskTime, description)
time.sleep(60) #one minute timer
-=-=-=-=-=-=-
Now... This has taken care of having to pre-order the task list
file; the database will sort the relevant events by time. It also
handles two things -- responded to items are flagged expired and won't
show up in the future; and cancelled (skipped) items will be raised one
minute after all "current" events have been processed. (What resolution
do you need -- would five minutes work?)
Still has the drawback that if it shuts down for any reason, someone
has to restart it.
Third approach, building on the above... remove the
while True:
and left shift the following lines; replace the
time.sleep(60)
with
cur.close()
con.close()
and on Linux/UNIX make it a cron job -- set to run every n-minutes. On
Windows, try using the Windows task scheduler (control panel/scheduled
tasks on WinXP)
You may (I'm not fully up on either cron or Windows task scheduler
-- the latter does have something about stopping a scheduled job that
takes too long) need to implement some sort of PID/lock in case the
scheduler starts a second (or more) copy of the program while the user
is still responding to the first (another reason to use a larger
granularity).
Using the system scheduling programs resolve the manual restart
problem. The program gets started each time the system says it should
run.
--
Wulfraed Dennis Lee Bieber KD6MOG
(e-mail address removed) (e-mail address removed)
HTTP://wlfraed.home.netcom.com/
(Bestiaria Support Staff: (e-mail address removed))
HTTP://www.bestiaria.com/