From 01abec53c6856c24666967ee51d25d09fc6b8863 Mon Sep 17 00:00:00 2001 From: Stefan Pluecken Date: Tue, 10 Oct 2006 03:00:49 +0000 Subject: add parental control (still somehow buggy and some minor features missing... don't trust it yet to protect your children) --- lib/python/Components/Input.py | 3 + lib/python/Components/Makefile.am | 2 +- lib/python/Components/ParentalControl.py | 185 +++++++++++++++++++++++++++ lib/python/Components/ParentalControlList.py | 55 ++++++++ lib/python/Components/__init__.py | 3 +- 5 files changed, 246 insertions(+), 2 deletions(-) create mode 100644 lib/python/Components/ParentalControl.py create mode 100644 lib/python/Components/ParentalControlList.py (limited to 'lib/python/Components') diff --git a/lib/python/Components/Input.py b/lib/python/Components/Input.py index 710ad0bc..b30a74e4 100644 --- a/lib/python/Components/Input.py +++ b/lib/python/Components/Input.py @@ -20,6 +20,9 @@ class Input(VariableText, HTMLComponent, GUIComponent, NumericalTextInput): self.currPos = 0 self.overwrite = 0 self.setText(text) + + def __len__(self): + return len(self.text) def update(self): self.setMarkedPos(self.currPos) diff --git a/lib/python/Components/Makefile.am b/lib/python/Components/Makefile.am index 4aa6a297..05e15ad7 100644 --- a/lib/python/Components/Makefile.am +++ b/lib/python/Components/Makefile.am @@ -16,4 +16,4 @@ install_PYTHON = \ PluginList.py PluginComponent.py RecordingConfig.py About.py UsageConfig.py \ FIFOList.py ServiceEventTracker.py Input.py TimerSanityCheck.py FileList.py \ MultiContent.py MediaPlayer.py TunerInfo.py VideoWindow.py ChoiceList.py \ - Element.py Playlist.py + Element.py Playlist.py ParentalControl.py ParentalControlList.py diff --git a/lib/python/Components/ParentalControl.py b/lib/python/Components/ParentalControl.py new file mode 100644 index 00000000..86f188a4 --- /dev/null +++ b/lib/python/Components/ParentalControl.py @@ -0,0 +1,185 @@ +from Components.config import config, ConfigSubsection, ConfigSelection, ConfigPIN, ConfigYesNo, ConfigSubList +from Components.Input import Input +from Screens.InputBox import InputBox, PinInput +from Screens.MessageBox import MessageBox +from Tools.BoundFunction import boundFunction +from ServiceReference import ServiceReference +from Tools import Notifications +from Tools.Directories import resolveFilename, SCOPE_CONFIG + +def InitParentalControl(): + config.ParentalControl = ConfigSubsection() + config.ParentalControl.configured = ConfigYesNo(default = False) + config.ParentalControl.mode = ConfigSelection(default = "simple", choices = [("simple", _("simple")), ("complex", _("complex"))]) + config.ParentalControl.storeservicepin = ConfigSelection(default = "never", choices = [("never", _("never")), ("5_minutes", _("5 minutes")), ("30_minutes", _("30 minutes")), ("60_minutes", _("60 minutes")), ("restart", _("until restart"))]) + config.ParentalControl.servicepinactive = ConfigYesNo(default = False) + config.ParentalControl.setuppinactive = ConfigYesNo(default = False) + config.ParentalControl.type = ConfigSelection(default = "blacklist", choices = [("whitelist", _("whitelist")), ("blacklist", _("blacklist"))]) + config.ParentalControl.setuppin = ConfigPIN(default = -1) +# config.ParentalControl.configured = configElement("config.ParentalControl.configured", configSelection, 1, (("yes", _("yes")), ("no", _("no")))) + #config.ParentalControl.mode = configElement("config.ParentalControl.mode", configSelection, 0, (("simple", _("simple")), ("complex", _("complex")))) + #config.ParentalControl.storeservicepin = configElement("config.ParentalControl.storeservicepin", configSelection, 0, (("never", _("never")), ("5_minutes", _("5 minutes")), ("30_minutes", _("30 minutes")), ("60_minutes", _("60 minutes")), ("restart", _("until restart")))) + #config.ParentalControl.servicepinactive = configElement("config.ParentalControl.servicepinactive", configSelection, 1, (("yes", _("yes")), ("no", _("no")))) + #config.ParentalControl.setuppinactive = configElement("config.ParentalControl.setuppinactive", configSelection, 1, (("yes", _("yes")), ("no", _("no")))) + #config.ParentalControl.type = configElement("config.ParentalControl.type", configSelection, 0, (("whitelist", _("whitelist")), ("blacklist", _("blacklist")))) + #config.ParentalControl.setuppin = configElement("config.ParentalControl.setuppin", configSequence, "0000", configSequenceArg().get("PINCODE", (4, ""))) + + config.ParentalControl.servicepin = ConfigSubList() + + for i in range(3): + config.ParentalControl.servicepin.append(ConfigPIN(default = -1)) + #config.ParentalControl.servicepin.append(configElement("config.ParentalControl.servicepin.level" + str(i), configSequence, "0000", configSequenceArg().get("PINCODE", (4, "")))) + +class ParentalControl: + def __init__(self): + self.open() + self.serviceLevel = {} + self.tries = 3 + + def addWhitelistService(self, service): + self.whitelist.append(service.toString()) + + def addBlacklistService(self, service): + self.blacklist.append(service.toString()) + + def setServiceLevel(self, service, level): + self.serviceLevel[service.toString()] = level + + def deleteWhitelistService(self, service): + self.whitelist.remove(service.toString()) + if self.serviceLevel.has_key(service.toString()): + self.serviceLevel.remove(service.toString()) + + def deleteBlacklistService(self, service): + self.blacklist.remove(service.toString()) + if self.serviceLevel.has_key(service.toString()): + self.serviceLevel.remove(service.toString()) + + def isServicePlayable(self, serviceref, callback): + service = serviceref.toString() + if not config.ParentalControl.configured.value: + return True + print "whitelist:", self.whitelist + print "blacklist:", self.blacklist + print "config.ParentalControl.type.value:", config.ParentalControl.type.value + print "not in whitelist:", (service not in self.whitelist) + print "checking parental control for service:", service + if (config.ParentalControl.type.value == "whitelist" and service not in self.whitelist) or (config.ParentalControl.type.value == "blacklist" and service in self.blacklist): + self.callback = callback + print "service:", ServiceReference(service).getServiceName() + levelNeeded = 0 + if self.serviceLevel.has_key(service): + levelNeeded = self.serviceLevel[service] + pinList = self.getPinList()[:levelNeeded + 1] + Notifications.AddNotificationWithCallback(boundFunction(self.servicePinEntered, service), PinInput, tries = self.tries, pinList = pinList, service = ServiceReference(service).getServiceName(), title = _("this service is protected by a parental control pin"), windowTitle = _("Parental control")) + return False + else: + return True + + def protectService(self, service): + print "protect" + print "config.ParentalControl.type.value:", config.ParentalControl.type.value + if config.ParentalControl.type.value == "whitelist": + if service.toString() in self.whitelist: + self.deleteWhitelistService(service) + else: # blacklist + if service.toString() not in self.blacklist: + self.addBlacklistService(service) + print "whitelist:", self.whitelist + print "blacklist:", self.blacklist + + + def unProtectService(self, service): + print "unprotect" + print "config.ParentalControl.type.value:", config.ParentalControl.type.value + if config.ParentalControl.type.value == "whitelist": + if service.toString() not in self.whitelist: + self.addWhitelistService(service) + else: # blacklist + if service.toString() in self.blacklist: + self.deleteBlacklistService(service) + print "whitelist:", self.whitelist + print "blacklist:", self.blacklist + + + + def getProtectionLevel(self, serviceref): + service = serviceref.toString() + if (config.ParentalControl.type.value == "whitelist" and service not in self.whitelist) or (config.ParentalControl.type.value == "blacklist" and service in self.blacklist): + if self.serviceLevel.has_key(service): + return self.serviceLevel[service] + else: + return 0 + else: + return -1 + + def getPinList(self): + pinList = [] + for x in config.ParentalControl.servicepin: + pinList.append(x.value) + return pinList + + def servicePinEntered(self, service, result): +# levelNeeded = 0 + #if self.serviceLevel.has_key(service): + #levelNeeded = self.serviceLevel[service] +# + #print "getPinList():", self.getPinList() + #pinList = self.getPinList()[:levelNeeded + 1] + #print "pinList:", pinList +# +# print "pin entered for service", service, "and pin was", pin + #if pin is not None and int(pin) in pinList: + if result[0] is not None and result[0]: + print "pin ok, playing service" + self.tries = 3 + self.callback(ref = ServiceReference(service).ref) + else: + self.tries = result[1] + if result[0] is not None: + Notifications.AddNotification(MessageBox, _("The pin code you entered is wrong."), MessageBox.TYPE_ERROR) + print "wrong pin entered" + + def saveWhitelist(self): + file = open(resolveFilename(SCOPE_CONFIG, "whitelist"), 'w') + for x in self.whitelist: + file.write(x + "\n") + file.close + + def openWhitelist(self): + self.whitelist = [] + try: + file = open(resolveFilename(SCOPE_CONFIG, "whitelist"), 'r') + lines = file.readlines() + for x in lines: + self.whitelist.append(x.strip()) + file.close + except: + pass + + def saveBlacklist(self): + file = open(resolveFilename(SCOPE_CONFIG, "blacklist"), 'w') + for x in self.blacklist: + file.write(x + "\n") + file.close + + def openBlacklist(self): + self.blacklist = [] + try: + file = open(resolveFilename(SCOPE_CONFIG, "blacklist"), 'r') + lines = file.readlines() + for x in lines: + self.blacklist.append(x.strip()) + file.close + except: + pass + + def save(self): + self.saveBlacklist() + self.saveWhitelist() + + def open(self): + self.openBlacklist() + self.openWhitelist() + +parentalControl = ParentalControl() \ No newline at end of file diff --git a/lib/python/Components/ParentalControlList.py b/lib/python/Components/ParentalControlList.py new file mode 100644 index 00000000..6315963f --- /dev/null +++ b/lib/python/Components/ParentalControlList.py @@ -0,0 +1,55 @@ +from HTMLComponent import * +from GUIComponent import * + +from MenuList import MenuList +from Components.ParentalControl import parentalControl +from Tools.Directories import * + +from enigma import * + +RT_HALIGN_LEFT = 0 +RT_HALIGN_RIGHT = 1 +RT_HALIGN_CENTER = 2 +RT_HALIGN_BLOCK = 4 + +RT_VALIGN_TOP = 0 +RT_VALIGN_CENTER = 8 +RT_VALIGN_BOTTOM = 16 + +lockPicture = loadPNG(resolveFilename(SCOPE_SKIN_IMAGE, "lock-fs8.png")) + +def ParentalControlEntryComponent(service, name, locked = True): + res = [ (service, name, locked) ] + res.append((eListboxPythonMultiContent.TYPE_TEXT, 80, 5, 200, 50, 0, RT_HALIGN_LEFT, name)) + if locked: + res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, 0, 0, 32, 32, lockPicture)) + + return res + +class ParentalControlList(MenuList, HTMLComponent, GUIComponent): + def __init__(self, list): + GUIComponent.__init__(self) + self.l = eListboxPythonMultiContent() + self.list = list + self.l.setList(list) + self.l.setFont(0, gFont("Regular", 20)) + + GUI_WIDGET = eListbox + + def setList(self, list): + self.list = list + self.l.setList(list) + + def postWidgetCreate(self, instance): + instance.setContent(self.l) + instance.setItemHeight(32) + + def toggleSelectedLock(self): + print "self.l.getCurrentSelection():", self.l.getCurrentSelection() + print "self.l.getCurrentSelectionIndex():", self.l.getCurrentSelectionIndex() + self.list[self.l.getCurrentSelectionIndex()] = ParentalControlEntryComponent(self.l.getCurrentSelection()[0][0], self.l.getCurrentSelection()[0][1], not self.l.getCurrentSelection()[0][2]); + if self.l.getCurrentSelection()[0][2]: + parentalControl.protectService(self.l.getCurrentSelection()[0][0]) + else: + parentalControl.unProtectService(self.l.getCurrentSelection()[0][0]) + self.l.setList(self.list) diff --git a/lib/python/Components/__init__.py b/lib/python/Components/__init__.py index c303c5a5..f37827d6 100644 --- a/lib/python/Components/__init__.py +++ b/lib/python/Components/__init__.py @@ -7,4 +7,5 @@ __all__ = ["ActionMap", "Button", "Clock", "ConfigList", "EventInfo", "InputDevice", "ServicePosition", "IPAddress", "VariableIP", "IPGateway", "IPNameserver", "Network", "RFmon", "DiskInfo", "NimManager", "TimerEntry", "Lcd", "EpgList" "ScrollLabel", "Timezones", "HelpMenuList", "TimerSanityCheck", - "FileList", "MultiContent", "TunerInfo", "ChoiceList", "Playlist" ] + "FileList", "MultiContent", "TunerInfo", "ChoiceList", "Playlist", + "ParentalControl" ] -- cgit v1.2.3