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