0c74e02674968be08973f2655b6be104dd32b5b4
[vuplus_dvbapp-plugin] / kiddytimer / src / KTmain.py
1 from Components.Label import Label
2 from Components.ProgressBar import ProgressBar
3 from KTMultiPixmap import KTmultiPixmap
4 from Components.config import config, configfile
5 from Screens.ChoiceBox import ChoiceBox
6 from Screens.InputBox import PinInput
7 from Screens.MessageBox import MessageBox
8 from Screens.MinuteInput import MinuteInput
9 from Screens.Screen import Screen
10 from Screens import Standby
11 from Tools.BoundFunction import boundFunction
12 from Tools import Notifications
13 from Tools.Directories import resolveFilename, SCOPE_CONFIG
14 from enigma import ePoint, eTimer, eDVBLocalTimeHandler
15
16 from __init__ import _
17 import KTglob
18 import NavigationInstance
19 import time
20
21 PARAM_NONE = -1
22 PARAM_STOPTIMER = 1
23 PARAM_STARTTIMER = 2
24 PARAM_DISABLETIMER = 3
25 PARAM_ENABLETIMER = 4
26 PARAM_INCREASETIMER = 5
27 PARAM_DECREASETIMER = 6
28 PARAM_SETTIMER = 7
29 PARAM_ENABLETIMERONCE = 8
30 PARAM_RESETTIMER = 9
31
32 class KiddyTimerScreen(Screen):    
33
34     def __init__(self, session):
35         Screen.__init__(self, session)
36         self.skin = KTglob.SKIN
37         self.onShow.append(self.movePosition)
38         
39         self.skin_path = KTglob.plugin_path
40         
41         self["TimerGraph"] = KTmultiPixmap()
42         self["TimerText"] = Label(_("??:??"))
43         self["TimerSlider"] = ProgressBar()
44         self["TimerSliderText"] = Label(_("??:??"))
45         
46     def renderScreen(self):
47         self["TimerSlider"].setValue(int(kiddyTimer.remainingPercentage*100)) 
48         self["TimerGraph"].setPixmapNum(kiddyTimer.curImg)
49         self.sTimeLeft = KTglob.getTimeFromSeconds( (kiddyTimer.remainingTime + 59) , False ) # Add 59 Seconds to show one minute if less than 1 minute left...
50         self["TimerText"].setText(self.sTimeLeft)
51         self["TimerSliderText"].setText(self.sTimeLeft)
52
53         if config.plugins.KiddyTimer.timerStyle.value == "clock":
54             self["TimerGraph"].show()
55             self["TimerText"].show()
56             self["TimerSlider"].hide()    
57             self["TimerSliderText"].hide()
58         else:
59             self["TimerGraph"].hide()
60             self["TimerText"].hide()
61             self["TimerSlider"].show()
62             self["TimerSliderText"].show()
63
64     def movePosition(self):
65         if self.instance:
66             self.getPixmapList()
67             self.instance.move(ePoint(config.plugins.KiddyTimer.position_x.value, config.plugins.KiddyTimer.position_y.value))
68
69     def getPixmapList(self):
70         self.percentageList = []
71         for sPixmap in self["TimerGraph"].pixmapFiles:
72             i = int(sPixmap[-8:-4])
73             self.percentageList.append(i)
74       
75 ##############################################################################
76
77 class KiddyTimer():
78
79     def __init__(self):
80         self.session = None 
81         self.dialog = None
82         self.active = False
83
84         self.iServiceReference = None
85         self.curImg = 0
86
87         self.sessionStartTime = None
88
89         self.loopTimerStep = 1000
90         self.loopTimer = eTimer()
91         self.loopTimer.callback.append(self.calculateTimes)
92
93         config.misc.standbyCounter.addNotifier(self.enterStandby, initial_call = False)
94
95     def gotSession(self, session):
96         self.session = session
97         self.startTimer()   
98          
99     def enterStandby(self,configElement):
100         Standby.inStandby.onClose.append(self.endStandby)
101         self.stopTimer()    
102       
103     def endStandby(self):
104         self.sessionStartTime = None
105         self.startTimer()
106         
107     def startTimer(self,bForceStart=False,iRemainingSeconds=0):
108         curStartYear = time.localtime().tm_year 
109         if curStartYear < 2010: 
110             # Time has not yet been set from transponder, wait until it has been set
111             eDVBLocalTimeHandler.getInstance().m_timeUpdated.get().append(self.gotTime)
112         else:
113             bDoStandardInit = True
114             if bForceStart:
115                 self.enabled = True
116             else:
117                 self.enabled = config.plugins.KiddyTimer.enabled.value
118             if (self.enabled == True and self.timerHasToRun()) or bForceStart:   
119                 # Date of the current day
120                 self.currentDay = time.strftime("%d.%m.%Y" , time.localtime())
121                 # First check for Cheat- attempts by kids
122                 if self.detectCheatAttempt():
123                     config.plugins.KiddyTimer.remainingTime.value = 0
124                     configfile.save()
125                     bForceStart = True
126                 elif iRemainingSeconds > 0:
127                     self.resetTimer(setTime=iRemainingSeconds)
128                     bDoStandardInit = False
129                 elif self.currentDay != config.plugins.KiddyTimer.lastStartDay.getValue():
130                     self.resetTimer()
131                     bDoStandardInit = False
132                 if bDoStandardInit:             
133                     self.setCurrentDayTime()
134                     self.setSessionTime(config.plugins.KiddyTimer.remainingTime.getValue())
135                     self.setRemainingTime(self.sessionTime)
136                     self.setSessionStartTime()
137     
138                 self.setPluginStatus("RUNNING")
139                 self.toggleActiveState(True)
140                 if not bForceStart:
141                     self.askForActivation()
142                 else:
143                     self.startLoop()
144
145     def gotTime(self):
146         eDVBLocalTimeHandler.getInstance().m_timeUpdated.get().remove(self.gotTime)
147         self.startTimer()
148     
149     def stopTimer(self):
150         if self.active:
151             self.saveValues()
152         self.toggleActiveState(False)
153         self.stopLoop()
154         self.setPluginStatus("SHUTDOWN")
155         self.iServiceReference = None
156         self.dialog = None
157                 
158     def resetTimer(self,**kwargs):
159         if "setTime" in kwargs.keys():
160             self.setCurrentDayTime(kwargs["setTime"])
161         else:            
162             self.setCurrentDayTime()
163         
164         self.setSessionTime(self.currentDayTime)
165         self.setRemainingTime(self.currentDayTime)
166         self.setSessionStartTime()
167
168     def timerHasToRun(self):
169         curStartTime = time.localtime()
170         iPluginStart = KTglob.getSecondsFromClock( [curStartTime[3],curStartTime[4]] )
171         iMonitorEnd = KTglob.getSecondsFromClock(config.plugins.KiddyTimer.monitorEndTime.getValue())  
172         iMonitorStart = KTglob.getSecondsFromClock(config.plugins.KiddyTimer.monitorStartTime.getValue())  
173         return (iPluginStart < iMonitorEnd) & (iPluginStart > iMonitorStart)
174
175     def startLoop(self):
176         self.loopTimer.start(self.loopTimerStep,1)
177     
178     def stopLoop(self):
179         self.loopTimer.stop()
180                            
181     def detectCheatAttempt(self):
182         sLastStatus = config.plugins.KiddyTimer.lastStatus.value
183         if (sLastStatus == "RUNNING"):
184             # cheat detected: RUNNING is NEVER a valid entry when checking.
185             Notifications.AddNotification(MessageBox, _("Cheat attempt detected. \nBox has not been shudown correctly. \nRemaining time was set to 0."), MessageBox.TYPE_WARNING, 0)
186             return True
187         else:
188             return False
189
190     def setPluginStatus(self,sStatus):
191         # Set values for detection of cheat attempts
192         config.plugins.KiddyTimer.lastStatus.value = sStatus
193         config.plugins.KiddyTimer.lastStatus.save()
194         configfile.save()
195
196     def askForActivation(self):
197         iTimeOut = config.plugins.KiddyTimer.activationDialogTimeout.getValue()
198         Notifications.AddNotificationWithCallback(self.callbackAskForActivation, MessageBox, _("Do you want to start the kiddytimer- plugin now."), MessageBox.TYPE_YESNO, iTimeOut)
199
200     def callbackAskForActivation(self, value):
201         if not value:
202             self.callbackParameter = PARAM_STOPTIMER
203             self.askForPIN()
204
205         self.startLoop()
206
207     def askForPIN(self):
208         self.session.openWithCallback( self.pinEntered, PinInput, pinList = [config.plugins.KiddyTimer.pin.getValue()], triesEntry = self.getTriesEntry(), title = _("Please enter the correct pin code"), windowTitle = _("Enter pin code"))
209     
210     def getTriesEntry(self):
211         return config.ParentalControl.retries.setuppin
212
213     def pinEntered(self, result):
214         if not result:
215             pass
216         else:
217             if self.callbackParameter == PARAM_STOPTIMER:
218                 self.stopTimer()      
219             elif self.callbackParameter == PARAM_DISABLETIMER:
220                 self.toggleEnabledState(False)
221             elif self.callbackParameter == PARAM_INCREASETIMER:
222                 self.session.openWithCallback(self.modifySessionTime, MinuteInput)
223             elif self.callbackParameter == PARAM_SETTIMER:
224                 self.session.openWithCallback(self.callbackSetTimer, MinuteInput)
225             elif self.callbackParameter == PARAM_RESETTIMER:
226                 self.resetTimer()
227             elif self.callbackParameter == PARAM_ENABLETIMERONCE:
228                 self.session.openWithCallback(self.callbackEnableTimerOnce, MinuteInput)
229
230     def setCurrentDayTime(self,iDayTime=PARAM_NONE):
231         if iDayTime == PARAM_NONE:
232             iDayTime = KTglob.getTodaysTimeInSeconds()
233         self.currentDayTime = iDayTime
234
235     def setSessionStartTime(self):
236         self.sessionStartTime = time.localtime()
237                 
238     def modifySessionTime(self, iMinutes):
239         iSeconds = iMinutes * 60
240         if self.callbackParameter == PARAM_INCREASETIMER:
241             iSeconds += self.sessionTime
242         else:
243             iSeconds = self.sessionTime - iSeconds 
244         self.setSessionTime(iSeconds)
245         
246
247     def setSessionTime(self, iSeconds):
248         self.sessionTime = iSeconds
249         if self.sessionTime > self.currentDayTime:
250             self.setCurrentDayTime(self.sessionTime)
251         if self.sessionTime < 0:
252             self.sessionTime = 0
253
254     def setRemainingTime(self,iRemaining):
255         if iRemaining < 0:
256             iRemaining = 0
257         self.remainingTime = iRemaining
258         if self.currentDayTime > 0:
259             self.remainingPercentage = iRemaining / self.currentDayTime
260         else:
261             self.remainingPercentage = 0
262
263     def callbackSetTimer(self, iMinutes):
264         iSeconds = iMinutes * 60
265         self.resetTimer(setTime=iSeconds)
266                 
267     def callbackEnableTimerOnce(self, iMinutes):
268         iSeconds = iMinutes * 60
269         if iSeconds > 0:
270             #If timer is active: stop it first to prohibit conflicts
271             if self.active:
272                 self.stopTimer()
273             self.startTimer(True, iSeconds)
274     
275     def toggleActiveState(self , bStatus):
276         # Initialize dialog
277         if self.dialog == None and bStatus:
278             self.dialog = self.session.instantiateDialog(KiddyTimerScreen)
279         self.active = bStatus
280         if bStatus == True:
281             self.dialog.show()
282         else:
283             if self.dialog != None:
284                 self.dialog.hide()
285
286     def toggleEnabledState(self, bStatus):
287         config.plugins.KiddyTimer.enabled.value = bStatus
288         self.enabled = bStatus
289         config.plugins.KiddyTimer.enabled.save()
290         configfile.save()
291         if self.enabled:
292             self.startTimer()
293         else:
294             self.stopTimer()
295
296     def calculateTimes(self):
297         self.stopLoop()
298         if self.active == True:
299             odtEnd = time.mktime(time.localtime())
300             iDiff = odtEnd - time.mktime(self.sessionStartTime)
301             iRemaining = self.sessionTime - iDiff
302             if iRemaining < 0:
303                 iRemaining = 0
304             self.remainingTime = iRemaining
305             if self.currentDayTime > 0:
306                 self.remainingPercentage = iRemaining / self.currentDayTime
307             else:
308                 self.remainingPercentage = 0
309
310             self.setImageNumber()
311             
312             if self.remainingTime == 0:
313                 self.iServiceReference = NavigationInstance.instance.getCurrentlyPlayingServiceReference()
314                 NavigationInstance.instance.stopService()
315             self.dialog.renderScreen()
316             self.startLoop()
317         else:
318             self.stopTimer()
319
320     def setImageNumber(self):
321         iCurPercent = int( self.remainingPercentage * 1000 )
322         iCount = 0
323         for iPercent in self.dialog.percentageList:
324            if iCurPercent <= iPercent:
325                iCount = iCount + 1
326         iCount = iCount - 1
327         if iCount < 0:
328             iCount = 0
329         self.curImg = iCount
330         
331     def saveValues(self):
332         if hasattr(self,"currentDay"):
333             config.plugins.KiddyTimer.lastStartDay.value = self.currentDay
334             config.plugins.KiddyTimer.lastStartDay.save()
335         if hasattr(self,"remainingTime"):
336             config.plugins.KiddyTimer.remainingTime.value = int(self.remainingTime)
337             config.plugins.KiddyTimer.remainingTime.save()
338
339     def showExtensionsMenu(self):
340         keyList = []
341         if self.enabled:
342             if self.active:
343                 keyList.append((_("Stop KiddyTimer (this session only)"),PARAM_STOPTIMER))
344                 keyList.append((_("Increase remaining time"),PARAM_INCREASETIMER))
345                 keyList.append((_("Decrease remaining time"),PARAM_DECREASETIMER))
346                 keyList.append((_("Set remaining time"),PARAM_SETTIMER))
347                 keyList.append((_("Reset todays remaining time"),PARAM_RESETTIMER))
348             else:
349                 keyList.append((_("Start KiddyTimer"),PARAM_STARTTIMER))
350             keyList.append((_("Enable KiddyTimer for x minutes"),PARAM_ENABLETIMERONCE))
351             keyList.append((_("Disable KiddyTimer"),PARAM_DISABLETIMER))
352         else:
353             keyList.append((_("Enable KiddyTimer"),PARAM_ENABLETIMER))
354             keyList.append((_("Enable KiddyTimer for x minutes"),PARAM_ENABLETIMERONCE))
355         self.session.openWithCallback(self.DoSelectionExtensionsMenu,ChoiceBox,_("Please select your KiddyTimer- option"),keyList)
356         
357     def DoSelectionExtensionsMenu(self,answer):
358         self.callbackParameter = PARAM_NONE
359         if answer is None:
360             pass
361         elif answer[1] in [PARAM_DISABLETIMER,PARAM_STOPTIMER,PARAM_INCREASETIMER,PARAM_SETTIMER,PARAM_ENABLETIMERONCE,PARAM_RESETTIMER]:
362             self.callbackParameter = answer[1]
363             self.askForPIN()
364         elif  answer[1] == PARAM_STARTTIMER:
365             self.startTimer()
366         elif  answer[1] == PARAM_ENABLETIMER: 
367             self.toggleEnabledState(True)
368         elif answer[1] == PARAM_DECREASETIMER:
369             self.session.openWithCallback(self.modifySessionTime, MinuteInput)
370         else:
371             self.session.open(MessageBox,_("Invalid selection"), MessageBox.TYPE_ERROR, 5)
372
373 # Assign global variable kiddyTimer
374 kiddyTimer = KiddyTimer()