fix executable modules, more documentation
[imago.git] / imago_pack / timer.py
1 #!/usr/bin/env python
2
3 """Go timer"""
4
5 import os
6 import sys
7 import time
8 import argparse
9 import subprocess
10
11 import pygame
12
13 class Timer:
14     def __init__(self, main_time, byop, byot):
15         self._last = 0
16         self._elapsed = 0.
17         self._main_t = main_time
18         self.byost = "main time"
19         self._byop = byop + 1
20         self._byot = byot
21         self._byo = False
22
23     def get_time(self):
24         if self._last > 0: # when running:
25             r_time = self._main_t - (time.time() - self._last + self._elapsed)
26             if (r_time - int(r_time)) < 0.75:
27                 sep = ":"
28             else:
29                sep = " "
30         else: # not running:
31             if self._byo and self._byop > 0:
32                 self._elapsed = 0
33             r_time = self._main_t - self._elapsed
34             sep = ":"
35         if r_time < 0:
36             self._byo = True
37             self._main_t = self._byot
38             self._byop -= 1
39             if self._byop > 0:
40                 self._elapsed = 0
41                 self._last = time.time()
42                 self.byost = "(" + str(self._byop) + ")"
43                 return self.get_time()
44             else:
45                 r_time = 0
46                 self.byost = "lost on time"
47         return "{0:0>2}".format(int(r_time / 60)) + sep + "{0:0>2}".format(int(r_time % 60))
48
49     def start(self):
50         self._last = time.time()
51
52     def stop(self):
53         self._elapsed += time.time() - self._last
54         self._last = 0
55
56     def is_running(self):
57         if self._last > 0:
58             return True
59         else:
60             return False
61
62 def main():
63     parser = argparse.ArgumentParser(description=__doc__)
64     parser.add_argument('-m', type=int, default=10,
65                         help="main time in minutes (default is 10)")
66     parser.add_argument('-b', type=int, nargs=2, default=[5, 20],
67                         help="japanese byoyomi: number of periods, period length in"
68                             " seconds (default is 5 periods, 20 seconds)")
69     parser.add_argument('-c', '--camera', dest='cam', action='store_true',
70                         help="camera on")
71     parser.add_argument('-d', type=int, default=0,
72                         help="video device id")
73     parser.add_argument('-r', type=int, nargs=2, default=[640, 480],
74                         help="set camera resolution")
75     args = parser.parse_args()
76
77
78     pygame.init()
79     pygame.display.set_mode((600, 130))
80     pygame.display.set_caption("Go timer")
81     screen = pygame.display.get_surface()
82
83     clock = pygame.time.Clock()
84
85     font = pygame.font.Font(pygame.font.match_font('monospace'), 80)
86     font2 = pygame.font.Font(None, 25)
87
88     done = False
89     first = True
90
91     main_time = args.m * 60
92
93     timers = (Timer(main_time, args.b[0], args.b[1]), Timer(main_time, args.b[0], args.b[1]))
94
95     if args.cam:
96         capture = subprocess.Popen(['python', 'capture.py', '-c', '-d', str(args.d), '-r',
97                           str(args.r[0]),
98                           str(args.r[1])], stdin=subprocess.PIPE)
99     last = 0
100
101     while not done:
102         for event in pygame.event.get():
103             if event.type == pygame.QUIT:
104                 done = True
105             elif event.type == pygame.KEYDOWN:
106                 if time.time() - last < 0.7:
107                     continue
108                 last = time.time()
109                 if first:
110                     timers[0].start()
111                     first = False
112                     if args.cam:
113                         print >> capture.stdin, "stop"
114                         print >> capture.stdin, "take"
115                     continue
116                 if args.cam:
117                     print >> capture.stdin, "take"
118                 for timer in timers:
119                     if timer.is_running():
120                         timer.stop()
121                     else:
122                         timer.start()
123
124         screen.fill([0, 0, 0])
125         text1 = font.render(timers[0].get_time(), True, [128, 255, 128])
126         screen.blit(text1, [10, 10])
127         text2 = font.render(timers[1].get_time(), True, [128, 255, 128])
128         screen.blit(text2, [300, 10])
129         text3 = font2.render(timers[0].byost, True, [128, 255, 128])
130         screen.blit(text3, [10, 90])
131         text4 = font2.render(timers[1].byost, True, [128, 255, 128])
132         screen.blit(text4, [300, 90])
133         pygame.display.flip()
134         clock.tick(15)
135
136     if args.cam:
137         print >> capture.stdin, "exit"
138
139 if __name__ == '__main__':
140     try:
141         main()
142     finally:
143         pygame.quit()