Example #1
0
    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
Example #2
0
    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)
Example #3
0
    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)
Example #4
0
    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)
Example #5
0
    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()
Example #6
0
    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)
Example #7
0
    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)
Example #8
0
    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
Example #9
0
    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")
Example #10
0
__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)
Example #11
0
    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)
Example #12
0
    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")
Example #13
0
        # 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
Example #14
0
    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")
Example #15
0
    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)
Example #16
0
    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")