def _addSecurityFlags(self, type, items): # Make sure we have some items to append the details to if len(items) < 1: return items # Make the call to the DB to get all the specific security settings pinDB = PinSentryDB() securityDetails = {} if type == MenuNavigator.TVSHOWS: securityDetails = pinDB.getAllTvShowsSecurity() elif type == MenuNavigator.MOVIES: securityDetails = pinDB.getAllMoviesSecurity() elif type == MenuNavigator.MOVIESETS: securityDetails = pinDB.getAllMovieSetsSecurity() elif type == MenuNavigator.PLUGINS: securityDetails = pinDB.getAllPluginsSecurity() for item in items: # Default security to 0 (Not Set) securityLevel = 0 if item['title'] in securityDetails: title = item['title'] securityLevel = securityDetails[title] log("%s has security level %d" % (title, securityLevel)) item['securityLevel'] = securityLevel del pinDB return items
def checkPlugins(self): navPath = xbmc.getInfoLabel("Container.FolderPath") if 'plugin://' not in navPath: # No Plugin currently set self.lastPluginChecked = "" return # Check if we are in a plugin location pluginName = xbmc.getInfoLabel("Container.FolderName") if pluginName in [None, "", self.lastPluginChecked]: # No Plugin currently set or this is a Plugin that has already been checked return # If we reach here we have aPlugin that we need to check log("NavigationRestrictions: Checking access to view Plugin: %s" % pluginName) self.lastPluginChecked = pluginName # Check for the case where the user does not want to check plugins # but the Pin Sentry plugin is selected, we always need to check this # as it is how permissions are set if (not Settings.isActivePlugins()) and ('PinSentry' not in pluginName): return securityLevel = 0 # Check to see if the user should have access to this plugin pinDB = PinSentryDB() securityLevel = pinDB.getPluginSecurityLevel(pluginName) if securityLevel < 1: # Check for the special case that we are accessing ourself # in which case we have a minimum security level if 'PinSentry' in pluginName: securityLevel = Settings.getSettingsSecurityLevel() else: log("NavigationRestrictions: No security enabled for plugin %s" % pluginName) return del pinDB # Check if we have already cached the pin number and at which level if PinSentry.getCachedPinLevel() >= securityLevel: log("NavigationRestrictions: Already cached pin at level %d, allowing access" % PinSentry.getCachedPinLevel()) return # Prompt the user for the pin, returns True if they knew it if PinSentry.promptUserForPin(securityLevel): log("NavigationRestrictions: Allowed access to plugin %s" % pluginName) else: log("NavigationRestrictions: Not allowed access to plugin %s which has security level %d" % (pluginName, securityLevel)) # Move back to the Video plugin Screen as they are not allowed where they are at the moment xbmc.executebuiltin("ActivateWindow(Video,addons://sources/video/)", True) # Clear the previous plugin as we will want to prompt for the pin again if the # user navigates there again self.lastPluginChecked = "" PinSentry.displayInvalidPinMessage(securityLevel)
def checkSystemSettings(self): # Check if the system restriction is enabled if not Settings.isActiveSystemSettings(): return # Check to see if the main system settings has been selected systemSettings = xbmc.getCondVisibility("Window.IsActive(10004)") addonBrowser = xbmc.getCondVisibility("Window.IsActive(10040)") profiles = xbmc.getCondVisibility("Window.IsActive(10034)") # Check if we are in any of the restricted sections if not systemSettings and not addonBrowser and not profiles: log("NavigationRestrictions: Not is restricted system settings") return # If we have already allowed the user to change settings, no need to check again # Check if we are still in the allowed time limit to edit if int(time.time()) < self.canChangeSettings: return # Need to make sure this user has access to change the settings pinDB = PinSentryDB() securityLevel = pinDB.getPluginSecurityLevel('PinSentry') del pinDB if securityLevel < 1: # If the user hasn't reset the permissions, then set it to the highest # security level available securityLevel = Settings.getSettingsSecurityLevel() log("NavigationRestrictions: Settings screen requires security level %d" % securityLevel) # Check if we have already cached the pin number and at which level if PinSentry.getCachedPinLevel() >= securityLevel: log("NavigationRestrictions: Already cached pin at level %d, allowing access" % PinSentry.getCachedPinLevel()) return # Before we prompt the user we need to close the dialog, otherwise the pin # dialog will appear behind it xbmc.executebuiltin("Dialog.Close(all, true)", True) # Prompt the user for the pin, returns True if they knew it if PinSentry.promptUserForPin(securityLevel): log("NavigationRestrictions: Allowed access to settings") # Allow the user 5 minutes to change the settings self.canChangeSettings = int(time.time()) + 300 xbmcgui.Dialog().notification(__addon__.getLocalizedString(32001).encode('utf-8'), __addon__.getLocalizedString(32110).encode('utf-8'), __icon__, 3000, False) else: log("NavigationRestrictions: Not allowed access to settings which has security level %d" % securityLevel) self.canChangeSettings = False PinSentry.displayInvalidPinMessage(securityLevel) # Return the user to the home page as they should not be here xbmc.executebuiltin("ActivateWindow(home)", True)
def checkFileSources(self): # Check if the user has navigated into a file source navPath = xbmc.getInfoLabel("Container.FolderPath") if navPath in [self.lastFileSource]: return if navPath in [None, ""]: self.lastFileSource = "" return # Skip over the internal items, quicker than doing a lookup if 'videodb://' in navPath: self.lastFileSource = "" return if 'special://' in navPath: self.lastFileSource = "" return if 'addons://' in navPath: self.lastFileSource = "" return if 'musicdb://' in navPath: self.lastFileSource = "" return # If we reach here we have a Movie Set that we need to check log("NavigationRestrictions: Checking access to view File Source: %s" % navPath) self.lastFileSource = navPath # Check to see if the user should have access to this file path pinDB = PinSentryDB() securityLevel = pinDB.getFileSourceSecurityLevelForPath(navPath) if securityLevel < 1: log("NavigationRestrictions: No security enabled for File Source %s" % navPath) return del pinDB # Check if we have already cached the pin number and at which level if PinSentry.getCachedPinLevel() >= securityLevel: log("NavigationRestrictions: Already cached pin at level %d, allowing access" % PinSentry.getCachedPinLevel()) return # Prompt the user for the pin, returns True if they knew it if PinSentry.promptUserForPin(securityLevel): log("NavigationRestrictions: Allowed access to File Source %s" % navPath) else: log("NavigationRestrictions: Not allowed access to File Source %s which has security level %d" % (navPath, securityLevel)) # Move back to the Movie Section as they are not allowed where they are at the moment xbmc.executebuiltin("ActivateWindow(Videos,sources://video/)", True) self.lastFileSource = "" PinSentry.displayInvalidPinMessage(securityLevel)
def checkSettings(self): # Check if we are in the Addon Information page (which can be used to disable the addon) # or the actual setting page addonSettings = xbmc.getCondVisibility("Window.IsActive(10140)") addonInformation = xbmc.getCondVisibility("Window.IsActive(10146)") if not addonSettings and not addonInformation: self.canChangeSettings = False return # If we have already allowed the user to change settings, no need to check again if self.canChangeSettings: return # Check if the addon is the PinSentry addon addonId = xbmc.getInfoLabel("ListItem.Property(Addon.ID)") if 'script.pinsentry' not in addonId: return # Need to make sure this user has access to change the settings pinDB = PinSentryDB() securityLevel = pinDB.getPluginSecurityLevel('PinSentry') del pinDB if securityLevel < 1: securityLevel = 1 # Check if we have already cached the pin number and at which level if PinSentry.getCachedPinLevel() >= securityLevel: log("NavigationRestrictions: Already cached pin at level %d, allowing access" % PinSentry.getCachedPinLevel()) return # Before we prompt the user we need to close the dialog, otherwise the pin # dialog will appear behind it xbmc.executebuiltin("Dialog.Close(all, true)", True) # Prompt the user for the pin, returns True if they knew it if PinSentry.promptUserForPin(): log("NavigationRestrictions: Allowed access to settings") self.canChangeSettings = True # Open the dialogs that should be shown if addonInformation: # Open the addon Information dialog xbmc.executebuiltin("ActivateWindow(10146)", True) elif addonSettings: # Open the addon settings dialog xbmc.executebuiltin("Addon.OpenSettings(script.pinsentry)", True) else: log("NavigationRestrictions: Not allowed access to settings which has security level %d" % securityLevel) self.canChangeSettings = False PinSentry.displayInvalidPinMessage()
def checkTvShows(self): # For TV Shows Users could either be in Seasons or Episodes if (not xbmc.getCondVisibility("Container.Content(seasons)")) and (not xbmc.getCondVisibility("Container.Content(episodes)")): # Not in a TV Show view, so nothing to do, Clear any previously # recorded TvShow if 'videodb://' in xbmc.getInfoLabel("Container.FolderPath"): self.lastTvShowChecked = "" return # Get the name of the TvShow tvshow = xbmc.getInfoLabel("ListItem.TVShowTitle") if tvshow in [None, "", self.lastTvShowChecked]: # No TvShow currently set - this can take a little time # So do nothing this time and wait until the next time # or this is a TvShow that has already been checked return # If we reach here we have a TvShow that we need to check log("NavigationRestrictions: Checking access to view TvShow: %s" % tvshow) self.lastTvShowChecked = tvshow # Check to see if the user should have access to this show pinDB = PinSentryDB() securityLevel = pinDB.getTvShowSecurityLevel(tvshow) if securityLevel < 1: log("NavigationRestrictions: No security enabled for %s" % tvshow) return del pinDB # Check if we have already cached the pin number and at which level if PinSentry.getCachedPinLevel() >= securityLevel: log("NavigationRestrictions: Already cached pin at level %d, allowing access" % PinSentry.getCachedPinLevel()) return # Prompt the user for the pin, returns True if they knew it if PinSentry.promptUserForPin(securityLevel): log("NavigationRestrictions: Allowed access to %s" % tvshow) else: log("NavigationRestrictions: Not allowed access to %s which has security level %d" % (tvshow, securityLevel)) # Move back to the TvShow Section as they are not allowed where they are at the moment # The following does seem strange, but you can't just call the TV Show list on it's own # In order to get there I had to first go via the home screen xbmc.executebuiltin("ActivateWindow(home)", True) xbmc.executebuiltin("ActivateWindow(Videos,videodb://tvshows/titles/)", True) # Clear the previous TV Show as we will want to prompt for the pin again if the # user navigates there again self.lastTvShowChecked = "" PinSentry.displayInvalidPinMessage(securityLevel)
def checkMovieSets(self): # Check if the user has navigated into a movie set navPath = xbmc.getInfoLabel("Container.FolderPath") if 'videodb://movies/sets/' not in navPath: # Not in a Movie Set view, so nothing to do if 'videodb://' in navPath: self.lastMovieSetChecked = "" return # Get the name of the movie set moveSetName = xbmc.getInfoLabel("Container.FolderName") if moveSetName in [None, "", self.lastMovieSetChecked]: # No Movie Set currently set - this can take a little time # So do nothing this time and wait until the next time # or this is a Movie set that has already been checked return # If we reach here we have a Movie Set that we need to check log("NavigationRestrictions: Checking access to view Movie Set: %s" % moveSetName) self.lastMovieSetChecked = moveSetName # Check to see if the user should have access to this set pinDB = PinSentryDB() securityLevel = pinDB.getMovieSetSecurityLevel(moveSetName) if securityLevel < 1: log("NavigationRestrictions: No security enabled for movie set %s" % moveSetName) return del pinDB # Check if we have already cached the pin number and at which level if PinSentry.getCachedPinLevel() >= securityLevel: log("NavigationRestrictions: Already cached pin at level %d, allowing access" % PinSentry.getCachedPinLevel()) return # Prompt the user for the pin, returns True if they knew it if PinSentry.promptUserForPin(securityLevel): log("NavigationRestrictions: Allowed access to movie set %s" % moveSetName) else: log("NavigationRestrictions: Not allowed access to movie set %s which has security level %d" % (moveSetName, securityLevel)) # Move back to the Movie Section as they are not allowed where they are at the moment xbmc.executebuiltin("ActivateWindow(Videos,videodb://movies/titles/)", True) # Clear the previous Movie Set as we will want to prompt for the pin again if the # user navigates there again self.lastMovieSetChecked = "" PinSentry.displayInvalidPinMessage(securityLevel)
def _cleanClassification(self, target, items): securityDetails = {} # Make the call to the DB to get all the specific security settings if target == MenuNavigator.MOVIES: pinDB = PinSentryDB() securityDetails = pinDB.getAllMovieClassificationSecurity(True) del pinDB elif target == MenuNavigator.TVSHOWS: pinDB = PinSentryDB() securityDetails = pinDB.getAllTvClassificationSecurity(True) del pinDB else: # No Classifications to deal with return items # Generate a list of certificates to check against certValues = securityDetails.keys() log("PinSentryPlugin: Allowing certificates for %s" % str(certValues)) # Check each of the items and add a flag if they are protected by a classification rule for item in items: if 'mpaa' in item: if item['mpaa'] not in [None, ""]: cert = item['mpaa'].strip().split(':')[-1] cert = cert.strip().split()[-1] try: cert = cert.encode("utf-8") except: log("PinSentryPlugin: Failed to encode certificate") # Need to decode the title as it doesn't link it for the logging that follows # if we don't title = item['title'] try: title = item['title'].decode("utf-8") except: log("PinSentryPlugin: Failed to decode title") if cert in certValues: item['mpaa'] = cert log("PinSentryPlugin: Setting mpaa for %s to %s" % (title, cert)) else: log("PinSentryPlugin: Clearing mpaa for %s (was %s)" % (title, item['mpaa'])) item['mpaa'] = "" return items
def setSecurity(self, type, title, id, level): log("Setting security for (id:%s) %s" % (id, title)) if title not in [None, ""]: pinDB = PinSentryDB() if type == MenuNavigator.TVSHOWS: # Set the security level for this title, setting it to zero # will result in the entry being removed from the database # as the default for an item is unset pinDB.setTvShowSecurityLevel(title, int(id), level) elif type == MenuNavigator.MOVIES: pinDB.setMovieSecurityLevel(title, int(id), level) elif type == MenuNavigator.MOVIESETS: pinDB.setMovieSetSecurityLevel(title, int(id), level) # As well as setting the security on the Movie set, we need # to also set it on each movie in the Movie Set self._setSecurityOnMoviesInMovieSets(int(id), level) elif type == MenuNavigator.PLUGINS: pinDB.setPluginSecurityLevel(title, id, level) del pinDB # Now reload the screen to reflect the change xbmc.executebuiltin("Container.Refresh")
__addon__ = xbmcaddon.Addon(id='script.pinsentry') __version__ = __addon__.getAddonInfo('version') __cwd__ = __addon__.getAddonInfo('path').decode("utf-8") __resource__ = xbmc.translatePath(os.path.join(__cwd__, 'resources').encode("utf-8")).decode("utf-8") __lib__ = xbmc.translatePath(os.path.join(__resource__, 'lib').encode("utf-8")).decode("utf-8") sys.path.append(__resource__) sys.path.append(__lib__) # Import the common settings from settings import log # Load the database interface from database import PinSentryDB ######################### # Main ######################### if __name__ == '__main__': log("PinSentryCleanup: Cleanup called (version %s)" % __version__) try: # Start by removing the database extrasDb = PinSentryDB() extrasDb.cleanDatabase() del extrasDb except: log("PinSentryCleanup: %s" % traceback.format_exc(), xbmc.LOGERROR)
def checkSettings(self): # Check if we are in the Addon Information page (which can be used to disable the addon) # or the actual setting page addonSettings = xbmc.getCondVisibility("Window.IsActive(10140)") addonInformation = xbmc.getCondVisibility("Window.IsActive(10146)") if not addonSettings and not addonInformation: # If not looking at an info or settings page, and the time for # allowed edits has ended, then reset it if self.canChangeSettings > 0: # If we have reached the home page, reset the timer if xbmc.getCondVisibility("Window.IsVisible(home)"): self.canChangeSettings = 0 elif time.time() > self.canChangeSettings: self.canChangeSettings = 0 return # Check if the addon is the PinSentry addon addonId = xbmc.getInfoLabel("ListItem.Property(Addon.ID)") if 'script.pinsentry' not in addonId: self.canChangeSettings = 0 return # If we have already allowed the user to change settings, no need to check again # Check if we are still in the allowed time limit to edit if int(time.time()) < self.canChangeSettings: return # Need to make sure this user has access to change the settings pinDB = PinSentryDB() securityLevel = pinDB.getPluginSecurityLevel('PinSentry') del pinDB if securityLevel < 1: # If the user hasn't reset the permissions, then set it to the highest # security level available securityLevel = Settings.getSettingsSecurityLevel() log("NavigationRestrictions: Settings screen requires security level %d" % securityLevel) # Check if we have already cached the pin number and at which level if PinSentry.getCachedPinLevel() >= securityLevel: log("NavigationRestrictions: Already cached pin at level %d, allowing access" % PinSentry.getCachedPinLevel()) return # Before we prompt the user we need to close the dialog, otherwise the pin # dialog will appear behind it xbmc.executebuiltin("Dialog.Close(all, true)", True) # Prompt the user for the pin, returns True if they knew it if PinSentry.promptUserForPin(securityLevel): log("NavigationRestrictions: Allowed access to settings") # Allow the user 5 minutes to change the settings self.canChangeSettings = int(time.time()) + 300 xbmcgui.Dialog().notification(__addon__.getLocalizedString(32001).encode('utf-8'), __addon__.getLocalizedString(32110).encode('utf-8'), __icon__, 3000, False) # Open the dialogs that should be shown, we don't reopen the Information dialog # as if we do the Close Dialog will not close it and the pin screen will not show correctly if addonSettings: # Open the addon settings dialog xbmc.executebuiltin("Addon.OpenSettings(script.pinsentry)", False) else: log("NavigationRestrictions: Not allowed access to settings which has security level %d" % securityLevel) self.canChangeSettings = False PinSentry.displayInvalidPinMessage(securityLevel)
def onPlayBackStarted(self): if not Settings.isActiveVideoPlaying(): return log("PinSentryPlayer: Notification that something started playing") # Only interested if it is not playing music if self.isPlayingAudio(): return # Ignore screen saver videos if xbmcgui.Window(10000).getProperty("VideoScreensaverRunning"): log("PinSentryPlayer: Detected VideoScreensaver playing") return # Check if the Pin is set, as no point prompting if it is not if not PinSentry.isPinSentryEnabled(): return isMusicVideo = False isTvShow = False # Get the information for what is currently playing # http://kodi.wiki/view/InfoLabels#Video_player title = xbmc.getInfoLabel("VideoPlayer.TVShowTitle") # If the TvShow Title is not set, then Check the ListItem as well if title in [None, ""]: title = xbmc.getInfoLabel("ListItem.TVShowTitle") securityLevel = 0 # If it is a TvShow, then check to see if it is enabled for this one if title not in [None, ""]: isTvShow = True log("PinSentryPlayer: TVShowTitle: %s" % title) pinDB = PinSentryDB() securityLevel = pinDB.getTvShowSecurityLevel(title) del pinDB else: # Check if the video is a music video isMusicVideo = self.isMusicVideoPlaying() # Not a TvShow, so check for the Movie Title title = xbmc.getInfoLabel("VideoPlayer.Title") # If no title is found, check the ListItem rather then the Player if title in [None, ""]: title = xbmc.getInfoLabel("ListItem.Title") if title not in [None, ""]: if not isMusicVideo: # Check for a Movie log("PinSentryPlayer: Title: %s" % title) pinDB = PinSentryDB() securityLevel = pinDB.getMovieSecurityLevel(title) del pinDB else: # Now check to see if this is music video log("PinSentryPlayer: Checking Music video for: %s" % title) pinDB = PinSentryDB() securityLevel = pinDB.getMusicVideoSecurityLevel(title) del pinDB # For video files it is possible to set them to always be allowed to play, in this case # the security value is -1 and we don't want to perform any new checking if securityLevel == -1: log("PinSentryPlayer: Security level is -1, so allowing access") return # Now perform the check that restricts if a file is in a file source # that should not be played if securityLevel < 1 and Settings.isActiveFileSource() and Settings.isActiveFileSourcePlaying(): # Get the path of the file being played filePath = xbmc.getInfoLabel("Player.Folderpath") if filePath in [None, ""]: filePath = xbmc.getInfoLabel("Player.Filenameandpath") if filePath in [None, ""]: filePath = xbmc.getInfoLabel("ListItem.FolderPath") if filePath in [None, ""]: filePath = xbmc.getInfoLabel("ListItem.FileNameAndPath") log("PinSentryPlayer: Checking file path: %s" % filePath) # Get all the sources that are protected pinDB = PinSentryDB() securityDetails = pinDB.getAllFileSourcesPathsSecurity() del pinDB # Each key is in path with security applied for key in securityDetails.keys(): if key in filePath: securityLevel = securityDetails[key] log("PinSentryPlayer: Setting path based security to %d" % securityLevel) # Now check to see if this item has a certificate restriction if securityLevel < 1: cert = xbmc.getInfoLabel("VideoPlayer.mpaa") if cert in [None, ""]: cert = xbmc.getInfoLabel("ListItem.Mpaa") if cert not in [None, ""]: log("PinSentryPlayer: Checking for certification restrictions: %s" % str(cert)) # Now split based on a colon and spaces, we only want the last bit of the # MPAA setting as the first bit can change based on scraper cert = cert.strip().split(':')[-1] cert = cert.strip().split()[-1] pinDB = PinSentryDB() if isTvShow: # Look up the TV Shows Certificate to see if it is restricted securityLevel = pinDB.getTvClassificationSecurityLevel(cert) else: # Look up the Movies Certificate to see if it is restricted securityLevel = pinDB.getMovieClassificationSecurityLevel(cert) del pinDB # If we have still not set security yet, check to make sure that the classification was actually # one of our supported types if securityLevel < 1: if isTvShow: if not Settings.isSupportedTvShowClassification(cert): securityLevel = Settings.getDefaultTvShowsWithoutClassification() log("PinSentryPlayer: Setting TV Show to level %d as there is no valid MPAA value" % securityLevel) elif not isMusicVideo: if not Settings.isSupportedMovieClassification(cert): securityLevel = Settings.getDefaultMoviesWithoutClassification() log("PinSentryPlayer: Setting Movie to level %d as there is no valid MPAA value" % securityLevel) # Check if we have set security based off of the classification if securityLevel > 0: # Before we check to make sure the user can access this video based on the # movie or TV Show classification, check for the case where there is background # media playing, this can be the case if TvTunes has started a Video while browsing # We do not want to prompt for the user to input the key for this isBackgroundMedia = True # Total wait for not playing background media is 1 second loopCount = 100 while isBackgroundMedia and (loopCount > 0): loopCount = loopCount - 1 if xbmcgui.Window(10025).getProperty("PlayingBackgroundMedia") in [None, ""]: isBackgroundMedia = False break xbmc.sleep(10) if isBackgroundMedia: securityLevel = 0 log("PinSentryPlayer: Playing background media") # Check if security has been set on this item if securityLevel < 1: if title in [None, ""]: # Not a TvShow or Movie - so allow the user to continue # without entering a pin code log("PinSentryPlayer: No security enabled, no title available") else: log("PinSentryPlayer: No security enabled for %s" % title) return # Check if we have already cached the pin number and at which level if PinSentry.getCachedPinLevel() >= securityLevel: log("PinSentryPlayer: Already cached pin at level %d, allowing access" % PinSentry.getCachedPinLevel()) return # Before we start prompting the user for the pin, check to see if we # have already been called and are prompting in another thread if xbmcgui.Window(10000).getProperty("PinSentryPrompting"): log("PinSentryPlayer: Already prompting for security code") return # Set the flag so other threads know we are processing this play request xbmcgui.Window(10000).setProperty("PinSentryPrompting", "true") # Pause the video so that we can prompt for the Pin to be entered # On some systems we could get notified that we have started playing a video # before it has actually been started, so keep trying to pause until we get # one that works while not xbmc.getCondVisibility("Player.Paused"): self.pause() log("PinSentryPlayer: Pausing video to check if OK to play") # Prompt the user for the pin, returns True if they knew it if PinSentry.promptUserForPin(securityLevel): log("PinSentryPlayer: Resuming video") # Pausing again will start the video playing again self.pause() else: log("PinSentryPlayer: Stopping video") self.stop() PinSentry.displayInvalidPinMessage(securityLevel) xbmcgui.Window(10000).clearProperty("PinSentryPrompting")
# Using ShutDown will perform the default behaviour that Kodi has in the system settings xbmc.executebuiltin("ShutDown") ################################## # Main of the PinSentry Service ################################## if __name__ == '__main__': log("Starting Pin Sentry Service %s" % __addon__.getAddonInfo('version')) # Tidy up any old pins and set any warnings when we first start Settings.checkPinSettings() # Make sure that the database exists if this is the first time pinDB = PinSentryDB() pinDB.createOrUpdateDB() del pinDB # Check to see if we need to restrict based on a given user to ensure they # are allowed to use the system userCtrl = UserPinControl() userCtrl.startupCheck() playerMonitor = PinSentryPlayer() systemMonitor = PinSentryMonitor() navRestrictions = NavigationRestrictions() loopsUntilUserControlCheck = 0 while (not xbmc.abortRequested): # No need to perform the user control check every fraction of a second
def setSecurity(self, type, title, id, oldLevel, classBlocked=False, forceLevel=None): log("Setting security for (id:%s) %s" % (id, title)) level = 1 # Check if we need to prompt the user or the new security level has been supplied if forceLevel is None: # Set the new security level to be used if oldLevel > 0: # Default is to disable it if it was enabled level = 0 numLevels = Settings.getNumberOfLevels() if numLevels > 1 or classBlocked: # Need to prompt the user to see which pin they are trying to set displayNameList = [] # Add the option to turn it off displayNameList.append("%s %s" % (__addon__.getLocalizedString(32211), __addon__.getLocalizedString(32013))) for i in range(1, numLevels + 1): secLevStr = str(i) if numLevels < 2: # If there is only one security level, use "On" rather than the number secLevStr = __addon__.getLocalizedString(32014) displayString = "%s %s" % (__addon__.getLocalizedString(32211), secLevStr) displayNameList.append(displayString) # Check if we need the option to disable a classification restriction if classBlocked: displayNameList.append(__addon__.getLocalizedString(32212)) select = xbmcgui.Dialog().select(__addon__.getLocalizedString(32001), displayNameList) if select != -1: level = select if classBlocked and (select >= (len(displayNameList) - 1)): level = -1 log("Setting security level to %d" % level) else: log("Exiting set security as no level selected") return else: level = forceLevel # This could take a little time to set the value so show the busy dialog xbmc.executebuiltin("ActivateWindow(busydialog)") if title not in [None, ""]: pinDB = PinSentryDB() if type == MenuNavigator.TVSHOWS: # Set the security level for this title, setting it to zero # will result in the entry being removed from the database # as the default for an item is unset pinDB.setTvShowSecurityLevel(title, int(id), level) elif type == MenuNavigator.MOVIES: pinDB.setMovieSecurityLevel(title, int(id), level) elif type == MenuNavigator.MOVIESETS: pinDB.setMovieSetSecurityLevel(title, int(id), level) # As well as setting the security on the Movie set, we need # to also set it on each movie in the Movie Set self._setSecurityOnMoviesInMovieSets(int(id), level) elif type == MenuNavigator.MUSICVIDEOS: pinDB.setMusicVideoSecurityLevel(title, int(id), level) elif type == MenuNavigator.PLUGINS: pinDB.setPluginSecurityLevel(title, id, level) elif type == MenuNavigator.FILESOURCE: pinDB.setFileSourceSecurityLevel(title, id, level) elif type == MenuNavigator.CLASSIFICATIONS_MOVIES: pinDB.setMovieClassificationSecurityLevel(id, title, level) elif type == MenuNavigator.CLASSIFICATIONS_TV: pinDB.setTvClassificationSecurityLevel(id, title, level) del pinDB else: # Handle the bulk operations like set All security for the movies self._setBulkSecurity(type, level) xbmc.executebuiltin("Dialog.Close(busydialog)") xbmc.executebuiltin("Container.Refresh")
def _setClassificationList(self, type="", subtype=""): classifications = () securityDetails = {} # Make the call to the DB to get all the specific security settings pinDB = PinSentryDB() if type == MenuNavigator.CLASSIFICATIONS_MOVIES: classifications = Settings.movieCassificationsNames securityDetails = pinDB.getAllMovieClassificationSecurity() elif type == MenuNavigator.CLASSIFICATIONS_TV: classifications = Settings.tvCassificationsNames securityDetails = pinDB.getAllTvClassificationSecurity() del pinDB # Get the root location of the icons iconLocation = os_path_join(__resource__, 'media') iconLocation = os_path_join(iconLocation, 'classifications') # Check if we are showing the root classification listing if type in [None, ""]: url = self._build_url({'mode': 'folder', 'foldername': MenuNavigator.CLASSIFICATIONS, 'type': MenuNavigator.CLASSIFICATIONS_MOVIES}) li = xbmcgui.ListItem(__addon__.getLocalizedString(32207), iconImage=__icon__) li.setProperty("Fanart_Image", __fanart__) li.addContextMenuItems([], replaceItems=True) xbmcplugin.addDirectoryItem(handle=self.addon_handle, url=url, listitem=li, isFolder=True) url = self._build_url({'mode': 'folder', 'foldername': MenuNavigator.CLASSIFICATIONS, 'type': MenuNavigator.CLASSIFICATIONS_TV}) li = xbmcgui.ListItem(__addon__.getLocalizedString(32208), iconImage=__icon__) li.setProperty("Fanart_Image", __fanart__) li.addContextMenuItems([], replaceItems=True) xbmcplugin.addDirectoryItem(handle=self.addon_handle, url=url, listitem=li, isFolder=True) elif subtype in [None, ""]: # Get all the different language that are supported languages = [] for classification in classifications: if classification['lang'] not in languages: languages.append(classification['lang']) # Check to see if we can sort all the entries alphabetically for the given language try: languages = sorted(languages, key=__addon__.getLocalizedString) except: # If it fails to sort, then we just list them unsorted log("PinSentryPlugin: Failed to sort language list") # Now print out the item for each language for lang in languages: url = self._build_url({'mode': 'folder', 'foldername': MenuNavigator.CLASSIFICATIONS, 'type': type, 'subtype': str(lang)}) iconImage = __icon__ for flag in Settings.flags: if flag['lang'] == lang: iconImage = os_path_join(iconLocation, flag['icon']) li = xbmcgui.ListItem(__addon__.getLocalizedString(lang), iconImage=iconImage) li.setProperty("Fanart_Image", __fanart__) li.addContextMenuItems([], replaceItems=True) xbmcplugin.addDirectoryItem(handle=self.addon_handle, url=url, listitem=li, isFolder=True) else: for classification in classifications: # Check if we are looking for a specific country if subtype != str(classification['lang']): continue fullName = classification['name'] % __addon__.getLocalizedString(classification['lang']) idStr = str(classification['id']) securityLevel = 0 if idStr in securityDetails: securityLevel = securityDetails[idStr] log("PinSentryPlugin: Classification %s has security level %d" % (fullName, securityLevel)) # Set the icon to the certificate one if available iconImage = __icon__ if classification['icon'] not in [None, ""]: iconImage = os_path_join(iconLocation, classification['icon']) li = xbmcgui.ListItem(fullName, iconImage=iconImage) # Add a tick if security is set if securityLevel > 0: li.setInfo('video', {'PlayCount': 1}) li.setProperty("Fanart_Image", __fanart__) li.addContextMenuItems([], replaceItems=True) url = self._build_url({'mode': 'setsecurity', 'type': type, 'id': classification['id'], 'title': classification['match'], 'level': securityLevel}) xbmcplugin.addDirectoryItem(handle=self.addon_handle, url=url, listitem=li, isFolder=False) xbmcplugin.endOfDirectory(self.addon_handle)
def onPlayBackStarted(self): if not Settings.isActiveVideoPlaying(): return log("PinSentryPlayer: Notification that something started playing") # Only interested if it is not playing music if self.isPlayingAudio(): return # Ignore screen saver videos if xbmcgui.Window(10000).getProperty("VideoScreensaverRunning"): log("PinSentryPlayer: Detected VideoScreensaver playing") return # Check if the Pin is set, as no point prompting if it is not if not PinSentry.isPinSentryEnabled(): return # Get the information for what is currently playing # http://kodi.wiki/view/InfoLabels#Video_player tvshowtitle = xbmc.getInfoLabel("VideoPlayer.TVShowTitle") # If the TvShow Title is not set, then Check the ListItem as well if tvshowtitle in [None, ""]: tvshowtitle = xbmc.getInfoLabel("ListItem.TVShowTitle") # cert = xbmc.getInfoLabel("VideoPlayer.mpaa") # listmpaa = xbmc.getInfoLabel("ListItem.Mpaa") # log("*** ROB ***: VideoPlayer.mpaa: %s" % str(cert)) # log("*** ROB ***: ListItem.Mpaa: %s" % str(listmpaa)) securityLevel = 0 # If it is a TvShow, then check to see if it is enabled for this one if tvshowtitle not in [None, ""]: log("PinSentryPlayer: TVShowTitle: %s" % tvshowtitle) pinDB = PinSentryDB() securityLevel = pinDB.getTvShowSecurityLevel(tvshowtitle) del pinDB if securityLevel < 1: log("PinSentryPlayer: No security enabled for %s" % tvshowtitle) return else: # Not a TvShow, so check for the Movie Title title = xbmc.getInfoLabel("VideoPlayer.Title") # If no title is found, check the ListItem rather then the Player if title in [None, ""]: title = xbmc.getInfoLabel("ListItem.Title") if title not in [None, ""]: log("PinSentryPlayer: Title: %s" % title) pinDB = PinSentryDB() securityLevel = pinDB.getMovieSecurityLevel(title) del pinDB if securityLevel < 1: log("PinSentryPlayer: No security enabled for %s" % title) return else: # Not a TvShow or Movie - so allow the user to continue # without entering a pin code log("PinSentryPlayer: No security enabled, no title available") return # Check if we have already cached the pin number and at which level if PinSentry.getCachedPinLevel() >= securityLevel: log("PinSentryPlayer: Already cached pin at level %d, allowing access" % PinSentry.getCachedPinLevel()) return # Before we start prompting the user for the pin, check to see if we # have already been called and are prompting in another thread if xbmcgui.Window(10000).getProperty("PinSentryPrompting"): log("PinSentryPlayer: Already prompting for security code") return # Set the flag so other threads know we are processing this play request xbmcgui.Window(10000).setProperty("PinSentryPrompting", "true") # Pause the video so that we can prompt for the Pin to be entered # On some systems we could get notified that we have started playing a video # before it has actually been started, so keep trying to pause until we get # one that works while not xbmc.getCondVisibility("Player.Paused"): self.pause() log("PinSentryPlayer: Pausing video to check if OK to play") # Prompt the user for the pin, returns True if they knew it if PinSentry.promptUserForPin(): log("PinSentryPlayer: Resuming video") # Pausing again will start the video playing again self.pause() else: log("PinSentryPlayer: Stopping video") self.stop() PinSentry.displayInvalidPinMessage() xbmcgui.Window(10000).clearProperty("PinSentryPrompting")