# basictimerapp - a really simple timer application. # This should be run using the command line: # pythonwin /app demos\basictimerapp.py import win32ui import win32api import win32con import sys from pywin.framework import app, cmdline, dlgappcore, cmdline import timer import time import string class TimerAppDialog(dlgappcore.AppDialog): softspace=1 def __init__(self, appName = ""): dlgappcore.AppDialog.__init__(self, win32ui.IDD_GENERAL_STATUS) self.timerAppName = appName self.argOff = 0 if len(self.timerAppName)==0: if len(sys.argv)>1 and sys.argv[1][0]!='/': self.timerAppName = sys.argv[1] self.argOff = 1 def PreDoModal(self): # sys.stderr = sys.stdout pass def ProcessArgs(self, args): for arg in args: if arg=="/now": self.OnOK() def OnInitDialog(self): win32ui.SetProfileFileName('pytimer.ini') self.title = win32ui.GetProfileVal(self.timerAppName, "Title", "Remote System Timer") self.buildTimer = win32ui.GetProfileVal(self.timerAppName, "Timer", "EachMinuteIntervaler()") self.doWork = win32ui.GetProfileVal(self.timerAppName, "Work", "DoDemoWork()") # replace "\n" with real \n. self.doWork = self.doWork.replace('\\n','\n') dlgappcore.AppDialog.OnInitDialog(self) self.SetWindowText(self.title) self.prompt1 = self.GetDlgItem(win32ui.IDC_PROMPT1) self.prompt2 = self.GetDlgItem(win32ui.IDC_PROMPT2) self.prompt3 = self.GetDlgItem(win32ui.IDC_PROMPT3) self.butOK = self.GetDlgItem(win32con.IDOK) self.butCancel = self.GetDlgItem(win32con.IDCANCEL) self.prompt1.SetWindowText("Python Timer App") self.prompt2.SetWindowText("") self.prompt3.SetWindowText("") self.butOK.SetWindowText("Do it now") self.butCancel.SetWindowText("Close") self.timerManager = TimerManager(self) self.ProcessArgs(sys.argv[self.argOff:]) self.timerManager.go() return 1 def OnDestroy(self,msg): dlgappcore.AppDialog.OnDestroy(self, msg) self.timerManager.stop() def OnOK(self): # stop the timer, then restart after setting special boolean self.timerManager.stop() self.timerManager.bConnectNow = 1 self.timerManager.go() return # def OnCancel(self): default behaviour - cancel == close. # return class TimerManager: def __init__(self, dlg): self.dlg = dlg self.timerId = None self.intervaler = eval(self.dlg.buildTimer) self.bConnectNow = 0 self.bHaveSetPrompt1 = 0 def CaptureOutput(self): self.oldOut = sys.stdout self.oldErr = sys.stderr sys.stdout = sys.stderr = self self.bHaveSetPrompt1 = 0 def ReleaseOutput(self): sys.stdout = self.oldOut sys.stderr = self.oldErr def write(self, str): s = str.strip() if len(s): if self.bHaveSetPrompt1: dest = self.dlg.prompt3 else: dest = self.dlg.prompt1 self.bHaveSetPrompt1 = 1 dest.SetWindowText(s) def go(self): self.OnTimer(None,None) def stop(self): if self.timerId: timer.kill_timer (self.timerId) self.timerId = None def OnTimer(self, id, timeVal): if id: timer.kill_timer (id) if self.intervaler.IsTime() or self.bConnectNow : # do the work. try: self.dlg.SetWindowText(self.dlg.title + " - Working...") self.dlg.butOK.EnableWindow(0) self.dlg.butCancel.EnableWindow(0) self.CaptureOutput() try: exec(self.dlg.doWork) print("The last operation completed successfully.") except: t, v, tb = sys.exc_info() str = "Failed: %s: %s" % (t, repr(v)) print(str) self.oldErr.write(str) tb = None # Prevent cycle finally: self.ReleaseOutput() self.dlg.butOK.EnableWindow() self.dlg.butCancel.EnableWindow() self.dlg.SetWindowText(self.dlg.title) else: now = time.time() nextTime = self.intervaler.GetNextTime() if nextTime: timeDiffSeconds = nextTime - now timeDiffMinutes = int(timeDiffSeconds / 60) timeDiffSeconds = timeDiffSeconds % 60 timeDiffHours = int(timeDiffMinutes / 60) timeDiffMinutes = timeDiffMinutes % 60 self.dlg.prompt1.SetWindowText("Next connection due in %02d:%02d:%02d" % (timeDiffHours,timeDiffMinutes,timeDiffSeconds)) self.timerId = timer.set_timer (self.intervaler.GetWakeupInterval(), self.OnTimer) self.bConnectNow = 0 class TimerIntervaler: def __init__(self): self.nextTime = None self.wakeUpInterval = 2000 def GetWakeupInterval(self): return self.wakeUpInterval def GetNextTime(self): return self.nextTime def IsTime(self): now = time.time() if self.nextTime is None: self.nextTime = self.SetFirstTime(now) ret = 0 if now >= self.nextTime: ret = 1 self.nextTime = self.SetNextTime(self.nextTime, now) # do the work. return ret class EachAnyIntervaler(TimerIntervaler): def __init__(self, timeAt, timePos, timeAdd, wakeUpInterval = None): TimerIntervaler.__init__(self) self.timeAt = timeAt self.timePos = timePos self.timeAdd = timeAdd if wakeUpInterval: self.wakeUpInterval = wakeUpInterval def SetFirstTime(self, now): timeTup = time.localtime(now) lst = [] for item in timeTup: lst.append(item) bAdd = timeTup[self.timePos] > self.timeAt lst[self.timePos] = self.timeAt for pos in range(self.timePos+1, 6): lst[pos]=0 ret = time.mktime(tuple(lst)) if (bAdd): ret = ret + self.timeAdd return ret; def SetNextTime(self, lastTime, now): return lastTime + self.timeAdd class EachMinuteIntervaler(EachAnyIntervaler): def __init__(self, at=0): EachAnyIntervaler.__init__(self, at, 5, 60, 2000) class EachHourIntervaler(EachAnyIntervaler): def __init__(self, at=0): EachAnyIntervaler.__init__(self, at, 4, 3600, 10000) class EachDayIntervaler(EachAnyIntervaler): def __init__(self,at=0): EachAnyIntervaler.__init__(self, at, 3, 86400, 10000) class TimerDialogApp(dlgappcore.DialogApp): def CreateDialog(self): return TimerAppDialog() def DoDemoWork(): print("Doing the work...") print("About to connect") win32api.MessageBeep(win32con.MB_ICONASTERISK) win32api.Sleep(2000) print("Doing something else...") win32api.MessageBeep(win32con.MB_ICONEXCLAMATION) win32api.Sleep(2000) print("More work.") win32api.MessageBeep(win32con.MB_ICONHAND) win32api.Sleep(2000) print("The last bit.") win32api.MessageBeep(win32con.MB_OK) win32api.Sleep(2000) app = TimerDialogApp() def t(): t = TimerAppDialog("Test Dialog") t.DoModal() return t if __name__=='__main__': import demoutils demoutils.NeedApp()