1 import NavigationInstance
2 from time import localtime
3 from ServiceReference import ServiceReference
4 from enigma import iServiceInformation, eServiceCenter, eServiceReference
6 class TimerSanityCheck:
7 def __init__(self, timerlist, newtimer=None):
9 self.timerlist = timerlist
10 self.newtimer = newtimer
12 self.rep_eventlist = []
13 self.nrep_eventlist = []
17 def check(self, ext_timer=1):
20 self.newtimer = ext_timer
21 if self.newtimer is None:
24 self.simultimer = [ self.newtimer ]
25 return self.checkTimerlist()
27 def getSimulTimerList(self):
28 return self.simultimer
30 def doubleCheck(self):
31 if self.newtimer is not None and self.newtimer.service_ref.ref.valid():
32 self.simultimer = [ self.newtimer ]
33 for timer in self.timerlist:
34 if (timer == self.newtimer):
37 if timer.begin == self.newtimer.begin:
38 getUnsignedDataRef1 = timer.service_ref.ref.getUnsignedData
39 getUnsignedDataRef2 = self.newtimer.service_ref.ref.getUnsignedData
40 for x in (1, 2, 3, 4):
41 if getUnsignedDataRef1(x) != getUnsignedDataRef2(x):
47 def checkTimerlist(self, ext_timer=1):
48 #with special service for external plugins
49 # Entries in eventlist
51 # BeginEndFlag 1 for begin, -1 for end
52 # index -1 for the new Timer, 0..n index of the existing timers
53 # count of running timers
55 serviceHandler = eServiceCenter.getInstance()
56 print "checkTimerlist"
57 # create a list with all start and end times
58 # split it into recurring and singleshot timers
60 ##################################################################################
61 # process the new timer
62 self.rep_eventlist = []
63 self.nrep_eventlist = []
65 self.newtimer = ext_timer
66 if (self.newtimer is not None) and (not self.newtimer.disabled):
67 if not self.newtimer.service_ref.ref.valid():
69 rflags = self.newtimer.repeated
70 rflags = ((rflags & 0x7F)>> 3)|((rflags & 0x07)<<4)
72 begin = self.newtimer.begin % 86400 # map to first day
73 while rflags: # then arrange on the week
75 self.rep_eventlist.append((begin, -1))
79 self.nrep_eventlist.extend([(self.newtimer.begin,self.bflag,-1),(self.newtimer.end,self.eflag,-1)])
81 ##################################################################################
82 # now process existing timers
84 for timer in self.timerlist:
85 if (timer != self.newtimer) and (not timer.disabled):
87 rflags = timer.repeated
88 rflags = ((rflags & 0x7F)>> 3)|((rflags & 0x07)<<4)
89 begin = timer.begin % 86400 # map all to first day
92 self.rep_eventlist.append((begin, idx))
96 self.nrep_eventlist.extend([(timer.begin,self.bflag,idx),(timer.end,self.eflag,idx)])
99 ################################################################################
100 # journalize timer repeations
101 if self.nrep_eventlist:
102 interval_begin = min(self.nrep_eventlist)[0]
103 interval_end = max(self.nrep_eventlist)[0]
104 offset_0 = interval_begin - (interval_begin % 604800)
105 weeks = (interval_end - offset_0) / 604800
106 if ((interval_end - offset_0) % 604800):
108 for cnt in range(weeks):
109 for event in self.rep_eventlist:
110 if event[1] == -1: # -1 is the identifier of the changed timer
111 event_begin = self.newtimer.begin
112 event_end = self.newtimer.end
114 event_begin = self.timerlist[event[1]].begin
115 event_end = self.timerlist[event[1]].end
116 new_event_begin = event[0] + offset_0 + (cnt * 604800)
117 # summertime correction
118 new_lth = localtime(new_event_begin).tm_hour
119 new_event_begin += 3600 * (localtime(event_begin).tm_hour - new_lth)
120 new_event_end = new_event_begin + (event_end - event_begin)
122 if new_event_begin >= self.newtimer.begin: # is the soap already running?
123 self.nrep_eventlist.extend([(new_event_begin, self.bflag, event[1]),(new_event_end, self.eflag, event[1])])
125 if new_event_begin >= self.timerlist[event[1]].begin: # is the soap already running?
126 self.nrep_eventlist.extend([(new_event_begin, self.bflag, event[1]),(new_event_end, self.eflag, event[1])])
128 offset_0 = 345600 # the Epoch begins on Thursday
129 weeks = 2 # test two weeks to take care of Sunday-Monday transitions
130 for cnt in range(weeks):
131 for event in self.rep_eventlist:
132 if event[1] == -1: # -1 is the identifier of the changed timer
133 event_begin = self.newtimer.begin
134 event_end = self.newtimer.end
136 event_begin = self.timerlist[event[1]].begin
137 event_end = self.timerlist[event[1]].end
138 new_event_begin = event[0] + offset_0 + (cnt * 604800)
139 new_event_end = new_event_begin + (event_end - event_begin)
140 self.nrep_eventlist.extend([(new_event_begin, self.bflag, event[1]),(new_event_end, self.eflag, event[1])])
142 ################################################################################
143 # order list chronological
144 self.nrep_eventlist.sort()
146 ##################################################################################
147 # detect overlapping timers and overlapping times
150 ConflictTunerType = None
151 newTimerTunerType = None
155 for event in self.nrep_eventlist:
157 if event[2] == -1: # new timer
158 timer = self.newtimer
160 timer = self.timerlist[event[2]]
161 if event[1] == self.bflag:
163 fakeRecService = NavigationInstance.instance.recordService(timer.service_ref, True)
165 fakeRecResult = fakeRecService.start(True)
168 if not fakeRecResult: # tune okay
169 feinfo = fakeRecService.frontendInfo().getFrontendData()
170 tunerType.append(feinfo.get("tuner_type"))
171 else: # tune failed.. so we must go another way to get service type (DVB-S, DVB-T, DVB-C)
173 def getServiceType(ref): # helper function to get a service type of a service reference
174 serviceInfo = serviceHandler.info(ref)
175 serviceInfo = serviceInfo and serviceInfo.getInfoObject(ref, iServiceInformation.sTransponderData)
176 return serviceInfo and serviceInfo["tuner_type"] or ""
178 ref = timer.service_ref.ref
179 if ref.flags & eServiceReference.isGroup: # service group ?
180 serviceList = serviceHandler.list(ref) # get all alternative services
182 for ref in serviceList.getContent("R"): # iterate over all group service references
183 type = getServiceType(ref)
184 if not type in tunerType: # just add single time
185 tunerType.append(type)
187 tunerType.append(getServiceType(ref))
189 if event[2] == -1: # new timer
190 newTimerTunerType = tunerType
191 overlaplist.append((fakeRecResult, timer, tunerType))
192 fakeRecList.append((timer, fakeRecService))
194 if ConflictTimer is None: # just take care of the first conflict
195 ConflictTimer = timer
196 ConflictTunerType = tunerType
197 elif event[1] == self.eflag:
198 for fakeRec in fakeRecList:
199 if timer == fakeRec[0] and fakeRec[1]:
200 NavigationInstance.instance.stopRecordService(fakeRec[1])
201 fakeRecList.remove(fakeRec)
203 for entry in overlaplist:
204 if entry[1] == timer:
205 overlaplist.remove(entry)
207 print "Bug: unknown flag!"
208 self.nrep_eventlist[idx] = (event[0],event[1],event[2],cnt,overlaplist[:]) # insert a duplicate into current overlaplist
211 if ConflictTimer is None: # no conflict found :)
214 ##################################################################################
215 # we have detected a conflict, now we must figure out the involved timers
217 if self.newtimer is not None: # new timer?
218 if self.newtimer is not ConflictTimer: # the new timer is not the conflicting timer?
219 for event in self.nrep_eventlist:
220 if len(event[4]) > 1: # entry in overlaplist of this event??
223 for entry in event[4]:
224 if entry[1] is ConflictTimer:
226 if entry[1] is self.newtimer:
229 ConflictTimer = self.newtimer
230 ConflictTunerType = newTimerTunerType
233 self.simultimer = [ ConflictTimer ]
234 for event in self.nrep_eventlist:
235 if len(event[4]) > 1: # entry in overlaplist of this event??
236 for entry in event[4]:
237 if entry[1] is ConflictTimer:
241 for entry in event[4]:
242 if not entry[1] in self.simultimer:
244 if x in ConflictTunerType:
245 self.simultimer.append(entry[1])
248 if len(self.simultimer) < 2:
249 print "Bug: unknown Conflict!"
251 return False # conflict detected!