Cleanup and improve the RSS stuff.
[kiosk.git] / renderer.py
1 import time
2 from datetime import datetime
3
4 class renderer(object):
5     """Base class for something that can render."""
6     def render(self):
7         pass
8
9     def get_name(self):
10         return self.__class__.__name__
11
12 class abstaining_renderer(renderer):
13     """A renderer that doesn't do it all the time."""
14     def __init__(self, name_to_timeout_dict):
15         self.name_to_timeout_dict = name_to_timeout_dict;
16         self.last_runs = {}
17         for key in name_to_timeout_dict:
18             self.last_runs[key] = 0
19
20     def should_render(self, keys_to_skip):
21         now = time.time()
22         for key in self.name_to_timeout_dict:
23             if (((now - self.last_runs[key]) > self.name_to_timeout_dict[key]) and
24                 key not in keys_to_skip):
25                 return key
26         return None
27
28     def render(self):
29         tries_per_key = {}
30         keys_to_skip = set()
31         while True:
32             key = self.should_render(keys_to_skip)
33             if key == None:
34                 break
35
36             if key in tries_per_key:
37                 tries_per_key[key] += 1
38             else:
39                 tries_per_key[key] = 0
40
41             if tries_per_key[key] >= 3:
42                 print('renderer: Too many failures/retries for "%s.%s", ' +
43                       ', giving up for now' % (self.get_name(), key))
44                 keys_to_skip.add(key)
45             else:
46                 msg = 'renderer: executing "%s.%s"' % (self.get_name(), key)
47                 if (tries_per_key[key] > 1):
48                     msg = msg + " (retry #%d)" % tries_per_key[key]
49                 print(msg)
50                 if (self.periodic_render(key)):
51                     self.last_runs[key] = time.time()
52
53     def periodic_render(self, key):
54         pass
55
56 class debuggable_abstaining_renderer(abstaining_renderer):
57     def __init__(self, name_to_timeout_dict, debug):
58         super(debuggable_abstaining_renderer, self).__init__(name_to_timeout_dict);
59         self.debug = debug
60
61     def debug_prefix(self):
62         return self.get_name()
63
64     def being_debugged(self):
65         return self.debug
66
67     def debug_print(self, template, *args):
68         try:
69             if self.being_debugged():
70                 if args:
71                     msg = template.format(args)
72                 else:
73                     msg = template
74
75                 # current date and time
76                 now = datetime.now()
77                 timestamp = now.strftime("%d-%b-%Y (%H:%M:%S.%f)")
78                 print("%s(%s): %s" % (self.debug_prefix(), timestamp, msg))
79         except Exception as e:
80             print("Exception in debug_print!")
81             print(e)