2 import NavigationInstance
3 from time import localtime
4 from Components.NimManager import nimmanager
5 from ServiceReference import ServiceReference
6 from enigma import iServiceInformation, eServiceCenter
8 class TimerSanityCheck:
9 def __init__(self, timerlist, newtimer=None):
11 self.timerlist = timerlist
12 self.newtimer = newtimer
14 self.rep_eventlist = []
15 self.nrep_eventlist = []
19 def check(self, ext_timer=1):
22 self.newtimer = ext_timer
23 if self.newtimer is None:
26 self.simultimer = [ self.newtimer ]
27 return self.checkTimerlist()
29 def getSimulTimerList(self):
30 return self.simultimer
32 def doubleCheck(self):
33 if self.newtimer is not None and self.newtimer.service_ref.ref.valid():
34 self.simultimer = [ self.newtimer ]
35 for timer in self.timerlist:
36 if (timer == self.newtimer):
39 if timer.begin == self.newtimer.begin:
40 getUnsignedDataRef1 = timer.service_ref.ref.getUnsignedData
41 getUnsignedDataRef2 = self.newtimer.service_ref.ref.getUnsignedData
43 if getUnsignedDataRef1(x) != getUnsignedDataRef2(x):
49 def checkTimerlist(self, ext_timer=1):
50 #with special service for external plugins
51 # Entries in eventlist
53 # index -1 for the new Timer, 0..n index of the existing timers
54 # BeginEndFlag -1 for begin, +1 for end
55 # count of running timers
57 print "checkTimerlist"
58 # create a list with all start and end times
59 # split it into recurring and singleshot timers
61 ##################################################################################
62 # process the new timer
63 self.rep_eventlist = []
64 self.nrep_eventlist = []
66 self.newtimer = ext_timer
67 if (self.newtimer is not None) and (not self.newtimer.disabled):
68 if not self.newtimer.service_ref.ref.valid():
70 rflags = self.newtimer.repeated
71 rflags = ((rflags & 0x7F)>> 3)|((rflags & 0x07)<<4)
73 begin = self.newtimer.begin % 86400 # map to first day
74 while rflags: # then arrange on the week
76 self.rep_eventlist.append((begin, -1))
80 self.nrep_eventlist.extend([(self.newtimer.begin,-1,self.bflag),(self.newtimer.end,-1,self.eflag)])
82 ##################################################################################
83 # now process existing timers
85 for timer in self.timerlist:
86 if (timer != self.newtimer) and (not timer.disabled):
88 rflags = timer.repeated
89 rflags = ((rflags & 0x7F)>> 3)|((rflags & 0x07)<<4)
90 begin = timer.begin % 86400 # map all to first day
93 self.rep_eventlist.append((begin, idx))
97 self.nrep_eventlist.extend([(timer.begin,idx,self.bflag),(timer.end,idx,self.eflag)])
100 ################################################################################
101 # journalize timer repeations
102 if self.nrep_eventlist:
103 interval_begin = min(self.nrep_eventlist)[0]
104 interval_end = max(self.nrep_eventlist)[0]
105 offset_0 = interval_begin - (interval_begin % 604800)
106 weeks = (interval_end - offset_0) / 604800
107 if ((interval_end - offset_0) % 604800):
109 for cnt in range(weeks):
110 for event in self.rep_eventlist:
111 if event[1] == -1: # -1 is the identifier of the changed timer
112 event_begin = self.newtimer.begin
113 event_end = self.newtimer.end
115 event_begin = self.timerlist[event[1]].begin
116 event_end = self.timerlist[event[1]].end
117 new_event_begin = event[0] + offset_0 + (cnt * 604800)
118 # summertime correction
119 new_lth = localtime(new_event_begin).tm_hour
120 new_event_begin += 3600 * (localtime(event_begin).tm_hour - new_lth)
121 new_event_end = new_event_begin + (event_end - event_begin)
123 if new_event_begin >= self.newtimer.begin: # is the soap already running?
124 self.nrep_eventlist.extend([(new_event_begin, event[1], self.bflag),(new_event_end, event[1], self.eflag)])
126 if new_event_begin >= self.timerlist[event[1]].begin: # is the soap already running?
127 self.nrep_eventlist.extend([(new_event_begin, event[1], self.bflag),(new_event_end, event[1], self.eflag)])
129 offset_0 = 345600 # the Epoch begins on Thursday
130 weeks = 2 # test two weeks to take care of Sunday-Monday transitions
131 for cnt in range(weeks):
132 for event in self.rep_eventlist:
133 if event[1] == -1: # -1 is the identifier of the changed timer
134 event_begin = self.newtimer.begin
135 event_end = self.newtimer.end
137 event_begin = self.timerlist[event[1]].begin
138 event_end = self.timerlist[event[1]].end
139 new_event_begin = event[0] + offset_0 + (cnt * 604800)
140 new_event_end = new_event_begin + (event_end - event_begin)
141 self.nrep_eventlist.extend([(new_event_begin, event[1], self.bflag),(new_event_end, event[1], self.eflag)])
145 return cmp(y[2], x[2])
146 return cmp(x[0], y[0])
147 ################################################################################
148 # order list chronological
149 self.nrep_eventlist.sort(sort_func)
151 ##################################################################################
152 # detect overlapping timers and overlapping times
155 ConflictTunerType = None
157 newTimerTunerType = None
158 newTimerTunerSlot = None
162 for event in self.nrep_eventlist:
164 if event[1] == -1: # new timer
165 timer = self.newtimer
167 timer = self.timerlist[event[1]]
168 if event[2] == self.bflag:
169 fakeRecService = NavigationInstance.instance.recordService(timer.service_ref)
170 fakeRecResult = fakeRecService.start(True)
171 feinfo = fakeRecService.frontendInfo().getFrontendData()
172 tunerType = feinfo.get("tuner_type")
173 tunerSlot = feinfo.get("tuner_number")
174 if event[1] == -1: # new timer
175 newTimerTunerType = tunerType
176 newTimerTunerSlot = tunerSlot
177 overlaplist.append((fakeRecResult, timer, tunerType, tunerSlot))
178 fakeRecList.append((timer, fakeRecService))
180 if ConflictTimer is None: # just take care of the first conflict
181 ConflictTimer = timer
182 ConflictTunerType = tunerType
183 ConflictTunerSlot = tunerSlot
184 elif event[2] == self.eflag:
185 for fakeRec in fakeRecList:
186 if timer == fakeRec[0]:
187 NavigationInstance.instance.stopRecordService(fakeRec[1])
188 fakeRecList.remove(fakeRec)
190 if overlaplist.count(timer):
191 overlaplist.remove(timer)
193 print "Bug: unknown flag!"
194 self.nrep_eventlist[idx] = (event[0],event[1],event[2],cnt,overlaplist[:]) # insert a duplicate into current overlaplist
197 if ConflictTimer is None: # no conflict found :)
200 ##################################################################################
201 # we have detected a conflict, now we must figure out the involved timers
203 if self.newtimer is not None: # new timer?
204 if self.newtimer is not ConflictTimer: # the new timer is not the conflicting timer?
205 for event in self.nrep_eventlist:
206 if len(event[4]) > 1: # entry in overlaplist of this event??
209 for entry in event[4]:
210 if entry[1] is ConflictTimer:
212 if entry[1] is self.newtimer:
215 ConflictTimer = self.newtimer
216 ConflictTunerType = newTimerTunerType
217 ConflictSlot = newTimerTunerSlot
220 self.simultimer = [ ConflictTimer ]
221 for event in self.nrep_eventlist:
222 if len(event[4]) > 1: # entry in overlaplist of this event??
223 for entry in event[4]:
224 if entry[1] is ConflictTimer:
228 for entry in event[4]:
229 if not self.simultimer.count(entry[1]) and (entry[2] == ConflictTunerType or entry[3] == ConflictTunerSlot):
230 self.simultimer.append(entry[1])
232 if len(self.simultimer) < 2:
233 print "Bug: unknown Conflict!"
235 return False # conflict detected!