basictimerapp.py 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. # basictimerapp - a really simple timer application.
  2. # This should be run using the command line:
  3. # pythonwin /app demos\basictimerapp.py
  4. import win32ui
  5. import win32api
  6. import win32con
  7. import sys
  8. from pywin.framework import app, cmdline, dlgappcore, cmdline
  9. import timer
  10. import time
  11. import string
  12. class TimerAppDialog(dlgappcore.AppDialog):
  13. softspace=1
  14. def __init__(self, appName = ""):
  15. dlgappcore.AppDialog.__init__(self, win32ui.IDD_GENERAL_STATUS)
  16. self.timerAppName = appName
  17. self.argOff = 0
  18. if len(self.timerAppName)==0:
  19. if len(sys.argv)>1 and sys.argv[1][0]!='/':
  20. self.timerAppName = sys.argv[1]
  21. self.argOff = 1
  22. def PreDoModal(self):
  23. # sys.stderr = sys.stdout
  24. pass
  25. def ProcessArgs(self, args):
  26. for arg in args:
  27. if arg=="/now":
  28. self.OnOK()
  29. def OnInitDialog(self):
  30. win32ui.SetProfileFileName('pytimer.ini')
  31. self.title = win32ui.GetProfileVal(self.timerAppName, "Title", "Remote System Timer")
  32. self.buildTimer = win32ui.GetProfileVal(self.timerAppName, "Timer", "EachMinuteIntervaler()")
  33. self.doWork = win32ui.GetProfileVal(self.timerAppName, "Work", "DoDemoWork()")
  34. # replace "\n" with real \n.
  35. self.doWork = self.doWork.replace('\\n','\n')
  36. dlgappcore.AppDialog.OnInitDialog(self)
  37. self.SetWindowText(self.title)
  38. self.prompt1 = self.GetDlgItem(win32ui.IDC_PROMPT1)
  39. self.prompt2 = self.GetDlgItem(win32ui.IDC_PROMPT2)
  40. self.prompt3 = self.GetDlgItem(win32ui.IDC_PROMPT3)
  41. self.butOK = self.GetDlgItem(win32con.IDOK)
  42. self.butCancel = self.GetDlgItem(win32con.IDCANCEL)
  43. self.prompt1.SetWindowText("Python Timer App")
  44. self.prompt2.SetWindowText("")
  45. self.prompt3.SetWindowText("")
  46. self.butOK.SetWindowText("Do it now")
  47. self.butCancel.SetWindowText("Close")
  48. self.timerManager = TimerManager(self)
  49. self.ProcessArgs(sys.argv[self.argOff:])
  50. self.timerManager.go()
  51. return 1
  52. def OnDestroy(self,msg):
  53. dlgappcore.AppDialog.OnDestroy(self, msg)
  54. self.timerManager.stop()
  55. def OnOK(self):
  56. # stop the timer, then restart after setting special boolean
  57. self.timerManager.stop()
  58. self.timerManager.bConnectNow = 1
  59. self.timerManager.go()
  60. return
  61. # def OnCancel(self): default behaviour - cancel == close.
  62. # return
  63. class TimerManager:
  64. def __init__(self, dlg):
  65. self.dlg = dlg
  66. self.timerId = None
  67. self.intervaler = eval(self.dlg.buildTimer)
  68. self.bConnectNow = 0
  69. self.bHaveSetPrompt1 = 0
  70. def CaptureOutput(self):
  71. self.oldOut = sys.stdout
  72. self.oldErr = sys.stderr
  73. sys.stdout = sys.stderr = self
  74. self.bHaveSetPrompt1 = 0
  75. def ReleaseOutput(self):
  76. sys.stdout = self.oldOut
  77. sys.stderr = self.oldErr
  78. def write(self, str):
  79. s = str.strip()
  80. if len(s):
  81. if self.bHaveSetPrompt1:
  82. dest = self.dlg.prompt3
  83. else:
  84. dest = self.dlg.prompt1
  85. self.bHaveSetPrompt1 = 1
  86. dest.SetWindowText(s)
  87. def go(self):
  88. self.OnTimer(None,None)
  89. def stop(self):
  90. if self.timerId: timer.kill_timer (self.timerId)
  91. self.timerId = None
  92. def OnTimer(self, id, timeVal):
  93. if id: timer.kill_timer (id)
  94. if self.intervaler.IsTime() or self.bConnectNow :
  95. # do the work.
  96. try:
  97. self.dlg.SetWindowText(self.dlg.title + " - Working...")
  98. self.dlg.butOK.EnableWindow(0)
  99. self.dlg.butCancel.EnableWindow(0)
  100. self.CaptureOutput()
  101. try:
  102. exec(self.dlg.doWork)
  103. print("The last operation completed successfully.")
  104. except:
  105. t, v, tb = sys.exc_info()
  106. str = "Failed: %s: %s" % (t, repr(v))
  107. print(str)
  108. self.oldErr.write(str)
  109. tb = None # Prevent cycle
  110. finally:
  111. self.ReleaseOutput()
  112. self.dlg.butOK.EnableWindow()
  113. self.dlg.butCancel.EnableWindow()
  114. self.dlg.SetWindowText(self.dlg.title)
  115. else:
  116. now = time.time()
  117. nextTime = self.intervaler.GetNextTime()
  118. if nextTime:
  119. timeDiffSeconds = nextTime - now
  120. timeDiffMinutes = int(timeDiffSeconds / 60)
  121. timeDiffSeconds = timeDiffSeconds % 60
  122. timeDiffHours = int(timeDiffMinutes / 60)
  123. timeDiffMinutes = timeDiffMinutes % 60
  124. self.dlg.prompt1.SetWindowText("Next connection due in %02d:%02d:%02d" % (timeDiffHours,timeDiffMinutes,timeDiffSeconds))
  125. self.timerId = timer.set_timer (self.intervaler.GetWakeupInterval(), self.OnTimer)
  126. self.bConnectNow = 0
  127. class TimerIntervaler:
  128. def __init__(self):
  129. self.nextTime = None
  130. self.wakeUpInterval = 2000
  131. def GetWakeupInterval(self):
  132. return self.wakeUpInterval
  133. def GetNextTime(self):
  134. return self.nextTime
  135. def IsTime(self):
  136. now = time.time()
  137. if self.nextTime is None:
  138. self.nextTime = self.SetFirstTime(now)
  139. ret = 0
  140. if now >= self.nextTime:
  141. ret = 1
  142. self.nextTime = self.SetNextTime(self.nextTime, now)
  143. # do the work.
  144. return ret
  145. class EachAnyIntervaler(TimerIntervaler):
  146. def __init__(self, timeAt, timePos, timeAdd, wakeUpInterval = None):
  147. TimerIntervaler.__init__(self)
  148. self.timeAt = timeAt
  149. self.timePos = timePos
  150. self.timeAdd = timeAdd
  151. if wakeUpInterval:
  152. self.wakeUpInterval = wakeUpInterval
  153. def SetFirstTime(self, now):
  154. timeTup = time.localtime(now)
  155. lst = []
  156. for item in timeTup:
  157. lst.append(item)
  158. bAdd = timeTup[self.timePos] > self.timeAt
  159. lst[self.timePos] = self.timeAt
  160. for pos in range(self.timePos+1, 6):
  161. lst[pos]=0
  162. ret = time.mktime(tuple(lst))
  163. if (bAdd):
  164. ret = ret + self.timeAdd
  165. return ret;
  166. def SetNextTime(self, lastTime, now):
  167. return lastTime + self.timeAdd
  168. class EachMinuteIntervaler(EachAnyIntervaler):
  169. def __init__(self, at=0):
  170. EachAnyIntervaler.__init__(self, at, 5, 60, 2000)
  171. class EachHourIntervaler(EachAnyIntervaler):
  172. def __init__(self, at=0):
  173. EachAnyIntervaler.__init__(self, at, 4, 3600, 10000)
  174. class EachDayIntervaler(EachAnyIntervaler):
  175. def __init__(self,at=0):
  176. EachAnyIntervaler.__init__(self, at, 3, 86400, 10000)
  177. class TimerDialogApp(dlgappcore.DialogApp):
  178. def CreateDialog(self):
  179. return TimerAppDialog()
  180. def DoDemoWork():
  181. print("Doing the work...")
  182. print("About to connect")
  183. win32api.MessageBeep(win32con.MB_ICONASTERISK)
  184. win32api.Sleep(2000)
  185. print("Doing something else...")
  186. win32api.MessageBeep(win32con.MB_ICONEXCLAMATION)
  187. win32api.Sleep(2000)
  188. print("More work.")
  189. win32api.MessageBeep(win32con.MB_ICONHAND)
  190. win32api.Sleep(2000)
  191. print("The last bit.")
  192. win32api.MessageBeep(win32con.MB_OK)
  193. win32api.Sleep(2000)
  194. app = TimerDialogApp()
  195. def t():
  196. t = TimerAppDialog("Test Dialog")
  197. t.DoModal()
  198. return t
  199. if __name__=='__main__':
  200. import demoutils
  201. demoutils.NeedApp()