1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 """C{timer [-t] INTERVAL}
19
20 Generates a sequence of timestamps, separated in time by the specified C{INTERVAL}
21 (approximately). The C{INTERVAL} format is::
22
23 HH:MM:SS
24
25 where C{HH} is hours, C{MM} is minutes, C{SS} is seconds. C{HH:} and
26 C{HH:MM:} may be omitted.
27
28 B{Examples}::
29
30 INTERVAL meaning
31 -----------------------------
32 5 5 seconds
33 1:30 1 minute, 30 seconds
34 1:00:00 1 hour
35
36 The output timestamp is time in seconds since 1/1/1970. If C{-t} is specified,
37 then the output timestamp is a tuple, matching what is returned by
38 C{time.gmtime()} and C{time.localtime()}: (year, month, day of month,
39 hour, minute, second, day of week, day of year, dst).
40
41 Notes:
42 - month is 1-based (January = 1, February = 2, ...)
43 - day of month is 1-based.
44 - second can go as high as 61 due to leap-seconds.
45 - day of week is 0-based, Monday = 0.
46 - day of year is 1-based.
47 - dst is 1 if Daylight Savings Time is in effect, 0 otherwise.
48 """
49
50 import threading
51 import time
52
53 import osh.core
54
55 Option = osh.args.Option
56
57
60
61
62 -def timer(interval, tupleoutput = False):
63 """Generates a sequence of timestamps, separated in time by the
64 specified C{interval} (approximately). The C{interval} format is
65 C{HH:MM:SS}, where C{HH} is hours, C{MM} is minutes, C{SS} is
66 seconds. C{HH:} and C{HH:MM:} may be omitted. Output items are
67 numbers representing seconds since 1/1/1970, if tupleoutput is False,
68 a tuple of (year, month, day of month,
69 hour, minute, second, day of week, day of year, dst) otherwise.
70 """
71 args = []
72 if tupleoutput:
73 args.append(Option('-t'))
74 return _Timer().process_args(interval)
75
76 -class _Timer(osh.core.Generator):
77
78 _tupleoutput = None
79 _metronome = None
80 _lock = None
81 _now = None
82 _done = False
83
84
85
88
89
90
91
94
96 args = self.args()
97 self._tupleoutput = args.flag('-t')
98 if args.has_next():
99 interval = self.parse_interval(args.next_string())
100 if args.has_next():
101 self.usage()
102 self._metronome = _Metronome(interval, self)
103 self._lock = threading.Condition()
104 else:
105 self.usage()
106
107
108
109
111
112
113
114
115
116 self._metronome.start()
117 while not self._done:
118 self._lock.acquire()
119 while self._now is None:
120
121
122
123 self._lock.wait(1.0)
124 now = self._now
125 if (not self._tupleoutput):
126 now = time.mktime(now)
127 self._now = None
128 self._lock.release()
129 self.send(now)
130
131
132
134 colon1 = interval.find(':')
135 colon2 = -1
136 if colon1 > 0:
137 colon2 = interval.find(':', colon1 + 1)
138
139 if colon1 < 0:
140
141 interval = '0:0:' + interval
142 elif colon2 < 0:
143
144 interval = '0:' + interval
145 colon1 = interval.find(':')
146 colon2 = interval.find(':', colon1 + 1)
147 HH = int(interval[:colon1])
148 MM = int(interval[colon1 + 1 : colon2])
149 SS = int(interval[colon2 + 1 :])
150 return HH * 3600 + MM * 60 + SS
151
153 self._lock.acquire()
154 self._now = time.localtime()
155 self._lock.notifyAll()
156 self._lock.release()
157
159
160 _interval = None
161 _timer = None
162
164 threading.Thread.__init__(self)
165 self._interval = interval
166 self._timer = timer
167 self.setDaemon(True)
168
170 while True:
171 self._timer.register_tick()
172 time.sleep(self._interval)
173