Version 1.0b: Fix bug with plugin- start after poweroff: Plugin started to early...
[vuplus_dvbapp-plugin] / kiddytimer / src / KTmain.py
index 31cba8e..8139366 100644 (file)
@@ -1,18 +1,34 @@
 from Components.Label import Label
 from Components.ProgressBar import ProgressBar
 from KTMultiPixmap import KTmultiPixmap
-from Components.config import config
+from Components.config import config, configfile
+from Screens.ChoiceBox import ChoiceBox
 from Screens.InputBox import PinInput
 from Screens.MessageBox import MessageBox
+from Screens.MinuteInput import MinuteInput
 from Screens.Screen import Screen
 from Screens import Standby
 from Tools.BoundFunction import boundFunction
 from Tools import Notifications
-from enigma import ePoint, eTimer
+from Tools.Directories import resolveFilename, SCOPE_CONFIG
+from enigma import ePoint, eTimer, eDVBLocalTimeHandler
+
+from __init__ import _
 import KTglob
 import NavigationInstance
 import time
 
+PARAM_NONE = -1
+PARAM_STOPTIMER = 1
+PARAM_STARTTIMER = 2
+PARAM_DISABLETIMER = 3
+PARAM_ENABLETIMER = 4
+PARAM_INCREASETIMER = 5
+PARAM_DECREASETIMER = 6
+PARAM_SETTIMER = 7
+PARAM_ENABLETIMERONCE = 8
+PARAM_RESETTIMER = 9
+
 class KiddyTimerScreen(Screen):    
 
     def __init__(self, session):
@@ -21,16 +37,16 @@ class KiddyTimerScreen(Screen):
         self.onShow.append(self.movePosition)
         
         self.skin_path = KTglob.plugin_path
-
+        
         self["TimerGraph"] = KTmultiPixmap()
         self["TimerText"] = Label(_("??:??"))
         self["TimerSlider"] = ProgressBar()
         self["TimerSliderText"] = Label(_("??:??"))
         
     def renderScreen(self):
-        self["TimerSlider"].setValue(int(KTglob.oKiddyTimer.remainingPercentage*100)) 
-        self["TimerGraph"].setPixmapNum(KTglob.oKiddyTimer.curImg)
-        self.sTimeLeft = KTglob.getTimeFromSeconds( (KTglob.oKiddyTimer.remainingTime + 59) , False ) # Add 59 Seconds to show one minute if less than 1 minute left...
+        self["TimerSlider"].setValue(int(kiddyTimer.remainingPercentage*100)) 
+        self["TimerGraph"].setPixmapNum(kiddyTimer.curImg)
+        self.sTimeLeft = KTglob.getTimeFromSeconds( (kiddyTimer.remainingTime + 59) , False ) # Add 59 Seconds to show one minute if less than 1 minute left...
         self["TimerText"].setText(self.sTimeLeft)
         self["TimerSliderText"].setText(self.sTimeLeft)
 
@@ -63,139 +79,240 @@ class KiddyTimer():
     def __init__(self):
         self.session = None 
         self.dialog = None
-        self.dialogEnabled = False
+        self.active = False
 
         self.iServiceReference = None
         self.curImg = 0
-                    
+
+        self.sessionStartTime = None
+
         self.loopTimerStep = 1000
         self.loopTimer = eTimer()
-        self.loopTimer.callback.append(self.calculateTimer)
-    
+        self.loopTimer.callback.append(self.calculateTimes)
+
+        config.misc.standbyCounter.addNotifier(self.enterStandby, initial_call = False)
+
     def gotSession(self, session):
         self.session = session
-        self.enabled = config.plugins.KiddyTimer.enabled.value
-        # Start- Time of the plugin, used for calculating the remaining time
-        self.pluginStartTime = time.localtime()            
-        # Number of the current day
-        self.dayNr = int(time.strftime("%w" , self.pluginStartTime ))
-        # Current Day to compare with the last saved day. If different -> Reset counter
-        # Number of seconds for the current day
-        iDayTime = KTglob.getSecondsFromClock( config.plugins.KiddyTimer.dayTimes[self.dayNr].timeValue.getValue() )
-        self.currentDayTime = iDayTime
-        self.currentDay = time.strftime("%d.%m.%Y" , self.pluginStartTime)
-        self.lastSavedRemainingTime = config.plugins.KiddyTimer.remainingTime.getValue()
-        self.remainingTime = self.lastSavedRemainingTime
-        if self.enabled == True:            
-            if self.currentDay != config.plugins.KiddyTimer.lastStartDay.getValue():
-                #Reset all Timers
-                self.resetTimer()
-            
-            if self.dialog == None:
-                self.dialog = self.session.instantiateDialog(KiddyTimerScreen)
-                self.dialog.hide()
-                
-            self.setDialogStatus(self.timerHasToRun())
-            if self.dialogEnabled == True:
-                self.askForActivation()
+        self.startTimer()   
+         
+    def enterStandby(self,configElement):
+        Standby.inStandby.onClose.append(self.endStandby)
+        self.stopTimer()    
+      
+    def endStandby(self):
+        self.sessionStartTime = None
+        self.startTimer()
+        
+    def startTimer(self,bForceStart=False,iRemainingSeconds=0):
+        curStartYear = time.localtime().tm_year 
+        if curStartYear < 2010: 
+            # Time has not yet been set from transponder, wait until it has been set
+            eDVBLocalTimeHandler.getInstance().m_timeUpdated.get().append(self.gotTime)
+        else:
+            bDoStandardInit = True
+            if bForceStart:
+                self.enabled = True
             else:
-                self.calculateTimer()
+                self.enabled = config.plugins.KiddyTimer.enabled.value
+            if (self.enabled == True and self.timerHasToRun()) or bForceStart:   
+                # Date of the current day
+                self.currentDay = time.strftime("%d.%m.%Y" , time.localtime())
+                # First check for Cheat- attempts by kids
+                if self.detectCheatAttempt():
+                    config.plugins.KiddyTimer.remainingTime.value = 0
+                    configfile.save()
+                    bForceStart = True
+                elif iRemainingSeconds > 0:
+                    self.resetTimer(setTime=iRemainingSeconds)
+                    bDoStandardInit = False
+                elif self.currentDay != config.plugins.KiddyTimer.lastStartDay.getValue():
+                    self.resetTimer()
+                    bDoStandardInit = False
+                if bDoStandardInit:             
+                    self.setCurrentDayTime()
+                    self.setSessionTime(config.plugins.KiddyTimer.remainingTime.getValue())
+                    self.setRemainingTime(self.sessionTime)
+                    self.setSessionStartTime()
     
-    def askForActivation(self):
-        Notifications.AddNotificationWithCallback(self.activationCallback, MessageBox, _("Do you want to start the kiddytimer- plugin now."), MessageBox.TYPE_YESNO, 5)
+                self.setPluginStatus("RUNNING")
+                self.toggleActiveState(True)
+                if not bForceStart:
+                    self.askForActivation()
+                else:
+                    self.startLoop()
+
+    def gotTime(self):
+        eDVBLocalTimeHandler.getInstance().m_timeUpdated.get().remove(self.gotTime)
+        self.startTimer()
+    
+    def stopTimer(self):
+        if self.active:
+            self.saveValues()
+        self.toggleActiveState(False)
+        self.stopLoop()
+        self.setPluginStatus("SHUTDOWN")
+        self.iServiceReference = None
+        self.dialog = None
+                
+    def resetTimer(self,**kwargs):
+        if "setTime" in kwargs.keys():
+            self.setCurrentDayTime(kwargs["setTime"])
+        else:            
+            self.setCurrentDayTime()
+        
+        self.setSessionTime(self.currentDayTime)
+        self.setRemainingTime(self.currentDayTime)
+        self.setSessionStartTime()
 
-    def activationCallback(self, value):
-        self.setDialogStatus(self.timerHasToRun())
+    def timerHasToRun(self):
+        curStartTime = time.localtime()
+        iPluginStart = KTglob.getSecondsFromClock( [curStartTime[3],curStartTime[4]] )
+        iMonitorEnd = KTglob.getSecondsFromClock(config.plugins.KiddyTimer.monitorEndTime.getValue())  
+        iMonitorStart = KTglob.getSecondsFromClock(config.plugins.KiddyTimer.monitorStartTime.getValue())  
+        return (iPluginStart < iMonitorEnd) & (iPluginStart > iMonitorStart)
 
-        if value:
-            self.setDialogStatus( True )
-            if self.dialog == None:
-                self.dialog = self.session.instantiateDialog(KiddyTimerScreen)
-                self.dialog.hide()
+    def startLoop(self):
+        self.loopTimer.start(self.loopTimerStep,1)
+    
+    def stopLoop(self):
+        self.loopTimer.stop()
+                           
+    def detectCheatAttempt(self):
+        sLastStatus = config.plugins.KiddyTimer.lastStatus.value
+        if (sLastStatus == "RUNNING"):
+            # cheat detected: RUNNING is NEVER a valid entry when checking.
+            Notifications.AddNotification(MessageBox, _("Cheat attempt detected. \nBox has not been shudown correctly. \nRemaining time was set to 0."), MessageBox.TYPE_WARNING, 0)
+            return True
         else:
-            self.askForPassword()
-                                       
-        self.calculateTimer()
+            return False
+
+    def setPluginStatus(self,sStatus):
+        # Set values for detection of cheat attempts
+        config.plugins.KiddyTimer.lastStatus.value = sStatus
+        config.plugins.KiddyTimer.lastStatus.save()
+        configfile.save()
+
+    def askForActivation(self):
+        iTimeOut = config.plugins.KiddyTimer.activationDialogTimeout.getValue()
+        Notifications.AddNotificationWithCallback(self.callbackAskForActivation, MessageBox, _("Do you want to start the kiddytimer- plugin now."), MessageBox.TYPE_YESNO, iTimeOut)
+
+    def callbackAskForActivation(self, value):
+        if not value:
+            self.callbackParameter = PARAM_STOPTIMER
+            self.askForPIN()
+
+        self.startLoop()
 
-    def askForPassword(self):
+    def askForPIN(self):
         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"))
     
     def getTriesEntry(self):
         return config.ParentalControl.retries.setuppin
-        
+
     def pinEntered(self, result):
-        if result is None:
-            pass
-        elif not result:
+        if not result:
             pass
         else:
-            self.setDialogStatus( False )        
-    
-    def startLoop(self):
-        self.loopTimer.start(self.loopTimerStep,1)
-    
-    def stopLoop(self):
-        self.loopTimer.stop()
-    
-    def resetTimer(self):
-        iDayTime = KTglob.getSecondsFromClock( config.plugins.KiddyTimer.dayTimes[self.dayNr].timeValue.getValue() )
+            if self.callbackParameter == PARAM_STOPTIMER:
+                self.stopTimer()      
+            elif self.callbackParameter == PARAM_DISABLETIMER:
+                self.toggleEnabledState(False)
+            elif self.callbackParameter == PARAM_INCREASETIMER:
+                self.session.openWithCallback(self.modifySessionTime, MinuteInput)
+            elif self.callbackParameter == PARAM_SETTIMER:
+                self.session.openWithCallback(self.callbackSetTimer, MinuteInput)
+            elif self.callbackParameter == PARAM_RESETTIMER:
+                self.resetTimer()
+            elif self.callbackParameter == PARAM_ENABLETIMERONCE:
+                self.session.openWithCallback(self.callbackEnableTimerOnce, MinuteInput)
+
+    def setCurrentDayTime(self,iDayTime=PARAM_NONE):
+        if iDayTime == PARAM_NONE:
+            iDayTime = KTglob.getTodaysTimeInSeconds()
         self.currentDayTime = iDayTime
-        
-        self.lastSavedRemainingTime = self.currentDayTime
-        self.remainingTime = self.currentDayTime
+
+    def setSessionStartTime(self):
+        self.sessionStartTime = time.localtime()
                 
-        config.plugins.KiddyTimer.lastStartDay.setValue(self.currentDay)
-        self.remainingPercentage = self.remainingTime / self.currentDayTime
-        self.pluginStartTime = time.localtime()
+    def modifySessionTime(self, iMinutes):
+        iSeconds = iMinutes * 60
+        if self.callbackParameter == PARAM_INCREASETIMER:
+            iSeconds += self.sessionTime
+        else:
+            iSeconds = self.sessionTime - iSeconds 
+        self.setSessionTime(iSeconds)
         
-        self.saveValues()
-    
-    def timerHasToRun(self):
-        iPluginStart = KTglob.getSecondsFromClock( [self.pluginStartTime[3],self.pluginStartTime[4]] )
-        iMonitorEnd = KTglob.getSecondsFromClock(config.plugins.KiddyTimer.monitorEndTime.getValue())  
-        return iPluginStart < iMonitorEnd 
+
+    def setSessionTime(self, iSeconds):
+        self.sessionTime = iSeconds
+        if self.sessionTime > self.currentDayTime:
+            self.setCurrentDayTime(self.sessionTime)
+        if self.sessionTime < 0:
+            self.sessionTime = 0
+
+    def setRemainingTime(self,iRemaining):
+        if iRemaining < 0:
+            iRemaining = 0
+        self.remainingTime = iRemaining
+        self.remainingPercentage = iRemaining / self.currentDayTime
+
+    def callbackSetTimer(self, iMinutes):
+        iSeconds = iMinutes * 60
+        self.resetTimer(setTime=iSeconds)
+                
+    def callbackEnableTimerOnce(self, iMinutes):
+        iSeconds = iMinutes * 60
+        if iSeconds > 0:
+            #If timer is active: stop it first to prohibit conflicts
+            if self.active:
+                self.stopTimer()
+            self.startTimer(True, iSeconds)
     
-    def setDialogStatus(self , bStatus):
+    def toggleActiveState(self , bStatus):
+        # Initialize dialog
+        if self.dialog == None and bStatus:
+            self.dialog = self.session.instantiateDialog(KiddyTimerScreen)
+        self.active = bStatus
         if bStatus == True:
-            self.dialogEnabled = True
-            if self.dialog != None:
-                self.dialog.show()
+            self.dialog.show()
         else:
-            self.dialogEnabled = False
             if self.dialog != None:
                 self.dialog.hide()
 
-    def calculateTimer(self):
-        if Standby.inStandby != None:
-            Standby.inStandby.onClose.append(self.endStandby)
-            self.stopMe()            
+    def toggleEnabledState(self, bStatus):
+        config.plugins.KiddyTimer.enabled.value = bStatus
+        self.enabled = bStatus
+        config.plugins.KiddyTimer.enabled.save()
+        configfile.save()
+        if self.enabled:
+            self.startTimer()
         else:
-            if self.dialogEnabled == True:
-                odtEnd = time.mktime(time.localtime())
-                iDiff = odtEnd - time.mktime(self.pluginStartTime)
-                iRemaining = self.lastSavedRemainingTime - iDiff
-                if iRemaining < 0:
-                    iRemaining = 0
-                self.remainingTime = iRemaining
-                self.remainingPercentage = iRemaining / KTglob.oKiddyTimer.currentDayTime
-                self.saveValues()
-                
-                self.setImageNumber()
-                
-                if self.remainingTime == 0:
-                    self.iServiceReference = NavigationInstance.instance.getCurrentlyPlayingServiceReference()
-                    NavigationInstance.instance.stopService()
-                self.dialog.renderScreen()
-            self.startLoop()
+            self.stopTimer()
+
+    def calculateTimes(self):
+        self.stopLoop()
+        if self.active == True:
+            odtEnd = time.mktime(time.localtime())
+            iDiff = odtEnd - time.mktime(self.sessionStartTime)
+            iRemaining = self.sessionTime - iDiff
+            if iRemaining < 0:
+                iRemaining = 0
+            self.remainingTime = iRemaining
+            if self.currentDayTime > 0:
+                self.remainingPercentage = iRemaining / self.currentDayTime
+            else:
+                self.remainingPercentage = 0
 
-    def showHide(self):
-        if config.plugins.KiddyTimer.enabled.value and self.timerHasToRun():
-            self.setDialogStatus(True)
+            self.setImageNumber()
+            
+            if self.remainingTime == 0:
+                self.iServiceReference = NavigationInstance.instance.getCurrentlyPlayingServiceReference()
+                NavigationInstance.instance.stopService()
+            self.dialog.renderScreen()
+            self.startLoop()
         else:
-            self.setDialogStatus(False)
-        
-    def endStandby(self):
-        self.gotSession(self.session)
+            self.stopTimer()
 
     def setImageNumber(self):
         iCurPercent = int( self.remainingPercentage * 1000 )
@@ -207,17 +324,48 @@ class KiddyTimer():
         if iCount < 0:
             iCount = 0
         self.curImg = iCount
-
-    def stopMe(self):
-        self.saveValues()
-        if self.dialog != None:
-            self.stopLoop()
-            self.dialog.hide()
-        self.iServiceReference = None
-        self.dialog = None
         
     def saveValues(self):
-        config.plugins.KiddyTimer.lastStartDay.save()
-        config.plugins.KiddyTimer.remainingTime.setValue(int(self.remainingTime))
-        config.plugins.KiddyTimer.remainingTime.save()
-        
\ No newline at end of file
+        if hasattr(self,"currentDay"):
+            config.plugins.KiddyTimer.lastStartDay.value = self.currentDay
+            config.plugins.KiddyTimer.lastStartDay.save()
+        if hasattr(self,"remainingTime"):
+            config.plugins.KiddyTimer.remainingTime.value = int(self.remainingTime)
+            config.plugins.KiddyTimer.remainingTime.save()
+
+    def showExtensionsMenu(self):
+        keyList = []
+        if self.enabled:
+            if self.active:
+                keyList.append((_("Stop KiddyTimer (this session only)"),PARAM_STOPTIMER))
+                keyList.append((_("Increase remaining time"),PARAM_INCREASETIMER))
+                keyList.append((_("Decrease remaining time"),PARAM_DECREASETIMER))
+                keyList.append((_("Set remaining time"),PARAM_SETTIMER))
+                keyList.append((_("Reset todays remaining time"),PARAM_RESETTIMER))
+            else:
+                keyList.append((_("Start KiddyTimer"),PARAM_STARTTIMER))
+            keyList.append((_("Enable KiddyTimer for x minutes"),PARAM_ENABLETIMERONCE))
+            keyList.append((_("Disable KiddyTimer"),PARAM_DISABLETIMER))
+        else:
+            keyList.append((_("Enable KiddyTimer"),PARAM_ENABLETIMER))
+            keyList.append((_("Enable KiddyTimer for x minutes"),PARAM_ENABLETIMERONCE))
+        self.session.openWithCallback(self.DoSelectionExtensionsMenu,ChoiceBox,_("Please select your KiddyTimer- option"),keyList)
+        
+    def DoSelectionExtensionsMenu(self,answer):
+        self.callbackParameter = PARAM_NONE
+        if answer is None:
+            pass
+        elif answer[1] in [PARAM_DISABLETIMER,PARAM_STOPTIMER,PARAM_INCREASETIMER,PARAM_SETTIMER,PARAM_ENABLETIMERONCE,PARAM_RESETTIMER]:
+            self.callbackParameter = answer[1]
+            self.askForPIN()
+        elif  answer[1] == PARAM_STARTTIMER:
+            self.startTimer()
+        elif  answer[1] == PARAM_ENABLETIMER: 
+            self.toggleEnabledState(True)
+        elif answer[1] == PARAM_DECREASETIMER:
+            self.session.openWithCallback(self.modifySessionTime, MinuteInput)
+        else:
+            self.session.open(MessageBox,_("Invalid selection"), MessageBox.TYPE_ERROR, 5)
+
+# Assign global variable kiddyTimer
+kiddyTimer = KiddyTimer()
\ No newline at end of file