Coding a scheduled journal application

K

kpierce8

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?
 
G

Gabriel Genellina

En Thu, 08 Mar 2007 20:42:45 -0300, (e-mail address removed)
I guess the
question is how to get it to run in the background and pop-up at the
appropriate times?

Use cron on linux or the task scheduler on windows
 
D

Dennis Lee Bieber

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/
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top