Fix multiple activations of repeating timer, improve readability a bit
[enigma2-plugins.git] / epgrefresh / src / EPGRefreshTimer.py
1 # To check if in Standby
2 import Screens.Standby
3
4 # Base Class
5 import timer
6
7 # To see if in Timespan and to determine begin of timespan
8 from time import localtime, mktime, time, strftime
9
10 # Config
11 from Components.config import config
12
13 def checkTimespan(begin, end):
14         # Get current time
15         time = localtime()
16
17         # Check if we span a day
18         if begin[0] > end[0] or (begin[0] == end[0] and begin[1] >= end[1]):
19                 # Check if begin of event is later than our timespan starts
20                 if time.tm_hour > begin[0] or (time.tm_hour == begin[0] and time.tm_min >= begin[1]):
21                         # If so, event is in our timespan
22                         return True
23                 # Check if begin of event is earlier than our timespan end
24                 if time.tm_hour < end[0] or (time.tm_hour == end[0] and time.tm_min <= end[1]):
25                         # If so, event is in our timespan
26                         return True
27                 return False
28         else:
29                 # Check if event begins earlier than our timespan starts 
30                 if time.tm_hour < begin[0] or (time.tm_hour == begin[0] and time.tm_min < begin[1]):
31                         # Its out of our timespan then
32                         return False
33                 # Check if event begins later than our timespan ends
34                 if time.tm_hour > end[0] or (time.tm_hour == end[0] and time.tm_min > end[1]):
35                         # Its out of our timespan then
36                         return False
37                 return True
38
39 class EPGRefreshTimerEntry(timer.TimerEntry):
40         """TimerEntry ..."""
41         def __init__(self, begin, tocall, nocheck = False):
42                 timer.TimerEntry.__init__(self, int(begin), int(begin))
43
44                 self.function = tocall
45                 self.nocheck = nocheck
46                 if nocheck:
47                         self.state = self.StatePrepared
48
49         def getNextActivation(self):
50                 # We delay our activation so we won't rush into reprocessing a repeating one
51                 return self.begin+1
52
53         def activate(self):
54                 if self.state == self.StateWaiting:
55                         # Check if in timespan
56                         if checkTimespan(config.plugins.epgrefresh.begin.value, config.plugins.epgrefresh.end.value):
57                                 print "[EPGRefresh] In Timespan, will check if we're in Standby and have no Recordings running next"
58                                 # Do we realy want to check nav?
59                                 from NavigationInstance import instance
60                                 if config.plugins.epgrefresh.force.value or (Screens.Standby.inStandby and instance is not None and not instance.RecordTimer.isRecording()):
61                                         return True
62                                 else:
63                                         print "[EPGRefresh] Box still in use, rescheduling"     
64
65                                         # Recheck later
66                                         self.begin = time() + config.plugins.epgrefresh.delay_standby.value*60
67                                         return False
68                         else:
69                                 print "[EPGRefresh] Not in timespan, ending timer"
70                                 self.state = self.StateEnded
71                                 return False
72                 elif self.state == self.StateRunning:
73                         self.function()
74
75                 return True
76
77         def timeChanged(self):
78                 if self.nocheck and self.state < self.StateRunning:
79                         self.state = self.StatePrepared
80
81         def shouldSkip(self):
82                 return False
83
84         def __repr__(self):
85                 return ''.join([
86                                 "<EPGRefreshTimerEntry (",
87                                 ', '.join([
88                                         strftime("%c", localtime(self.begin)),
89                                         str(self.repeated),
90                                         str(self.function)
91                                 ]),
92                                 ")>"
93                         ])
94
95 class EPGRefreshTimer(timer.Timer):
96         def __init__(self):
97                 timer.Timer.__init__(self)
98
99         def remove(self, entry):
100                 print "[EPGRefresh] Timer removed " + str(entry)
101
102                 # avoid re-enqueuing
103                 entry.repeated = False
104
105                 # abort timer.
106                 # this sets the end time to current time, so timer will be stopped.
107                 entry.abort()
108
109                 if entry.state != entry.StateEnded:
110                         self.timeChanged(entry)
111
112                 print "state: ", entry.state
113                 print "in processed: ", entry in self.processed_timers
114                 print "in running: ", entry in self.timer_list
115                 # now the timer should be in the processed_timers list. remove it from there.
116                 self.processed_timers.remove(entry)
117
118         def setRefreshTimer(self, tocall):
119                 # Add refresh Timer
120                 now = localtime()
121                 begin = mktime(
122                         (now.tm_year, now.tm_mon, now.tm_mday,
123                         config.plugins.epgrefresh.begin.value[0],
124                         config.plugins.epgrefresh.begin.value[1],
125                         0, now.tm_wday, now.tm_yday, now.tm_isdst)
126                 )
127
128                 # If the last scan was finished before our timespan begins/began and
129                 # timespan began in the past fire the timer once (timer wouldn't do so
130                 # by itself)
131                 if config.plugins.epgrefresh.lastscan.value < begin and begin < time():
132                         tocall()
133
134                 refreshTimer = EPGRefreshTimerEntry(begin, tocall, nocheck = True)
135
136                 for x in range(0,7):
137                         refreshTimer.setRepeated(x)
138
139                 # We can be sure that whenever this function is called the timer list
140                 # was wiped, so just add a new timer
141                 self.addTimerEntry(refreshTimer)
142
143         def add(self, entry):
144                 entry.timeChanged()
145                 print "[EPGRefresh] Timer added " + str(entry)
146                 self.addTimerEntry(entry)
147
148         def clear(self):
149                 self.timer_list = []
150
151         def isActive(self):
152                 return len(self.timer_list) > 0
153
154 epgrefreshtimer = EPGRefreshTimer()