Exemplo n.º 1
0
def SetDefaultLocale(loc="en-us"):
    global defaultLangDict
    global defaultCountryDict
    global __defaultLocale
    global CurrentLocale
    if loc == __defaultLocale: return

    __defaultLocale = loc

    pos = __defaultLocale.find("-")

    if pos > -1:
        lang = __defaultLocale[:pos]
        langPath = os.path.join(Plugin.__bundlePath,
                                "Contents/Strings/%s.json" % lang)
        if os.path.exists(langPath):
            f = open(langPath, "r")
            defaultLangDict = JSON.ObjectFromString(f.read())
            f.close()
            PMS.Log("(Framework) Loaded %s strings" % lang)
        else:
            PMS.Log("(Framework) Couldn't find %s strings" % lang)

        locPath = os.path.join(Plugin.__bundlePath,
                               "Contents/Strings/%s.json" % __defaultLocale)
        if os.path.exists(locPath):
            f = open(locPath, "r")
            defaultCountryDict = JSON.ObjectFromString(f.read())
            f.close()
            PMS.Log("(Framework) Loaded %s strings" % __defaultLocale)
        else:
            PMS.Log("(Framework) Couldn't find %s strings" % __defaultLocale)

    else:
        langPath = os.path.join(Plugin.__bundlePath,
                                "Contents/Strings/%s.json" % __defaultLocale)
        if os.path.exists(langPath):
            f = open(langPath, "r")
            defaultLangDict = JSON.ObjectFromString(f.read())
            f.close()
            PMS.Log("(Framework) Loaded %s strings" % __defaultLocale)
        else:
            PMS.Log("(Framework) Couldn't find %s strings" % __defaultLocale)

    if CurrentLocale == None: CurrentLocale = loc
Exemplo n.º 2
0
def __loadLocale(loc):
    global CurrentLocale
    if loc == CurrentLocale:
        return None

    global langDict
    global countryDict
    pos = loc.find("-")

    if pos > -1:

        lang = loc[:pos]
        langPath = os.path.join(Plugin.__bundlePath,
                                "Contents/Strings/%s.json" % lang)
        if os.path.exists(langPath):
            f = open(langPath, "r")
            langDict = JSON.ObjectFromString(f.read())
            f.close()
            PMS.Log("(Framework) Loaded %s strings" % lang)
        else:
            PMS.Log("(Framework) Couldn't find %s strings" % lang)

        locPath = os.path.join(Plugin.__bundlePath,
                               "Contents/Strings/%s.json" % loc)
        if os.path.exists(locPath):
            f = open(locPath, "r")
            countryDict = JSON.ObjectFromString(f.read())
            f.close()
            PMS.Log("(Framework) Loaded %s strings" % loc)
        else:
            PMS.Log("(Framework) Couldn't find %s strings" % loc)

    else:
        langPath = os.path.join(Plugin.__bundlePath,
                                "Contents/Strings/%s.json" % loc)
        if os.path.exists(langPath):
            f = open(langPath, "r")
            langDict = JSON.ObjectFromString(f.read())
            f.close()
            PMS.Log("(Framework) Loaded %s strings" % loc)
        else:
            PMS.Log("(Framework) Couldn't find %s strings" % loc)

    CurrentLocale = loc
Exemplo n.º 3
0
def __loadDefaults():
    global __dict
    __dict = {}
    path = "%s/Contents/DefaultDict.json" % Plugin.__bundlePath
    if os.path.exists(path):
        f = open(path, "r")
        string = f.read()
        f.close()
        __dict = JSON.ObjectFromString(string)
        PMS.Log("(Framework) Loaded the default dictionary file")
    Plugin.__callNamed("CreateDict", addToLog=False)
    Set("Framework.LastCompatibilityVersion",
        PMS.FrameworkCompatibilityVersion,
        addToLog=False)
Exemplo n.º 4
0
def __load():
    global __prefs
    global __prefsPath

    path = "%s/Contents/DefaultPrefs.json" % Plugin.__bundlePath
    if os.path.exists(path):
        f = open(path, "r")
        string = f.read()
        f.close()
        __prefs = JSON.ObjectFromString(string)
        PMS.Log("(Framework) Loaded the default preferences file")
    Plugin.__callNamed("CreatePrefs", addToLog=False)
    if os.path.exists(__prefsPath):
        try:
            f = open(__prefsPath, "r")
            userPrefs = XML.ElementFromString(f.read())
            f.close()
            for userPref in userPrefs:
                for pref in __prefs:
                    if pref["id"] == userPref.tag:
                        pref["value"] = userPref.text
            PMS.Log("(Framework) Loaded the user preferences file")
        except:
            PMS.Log("(Framework) Exception when reading preferences")
Exemplo n.º 5
0
def __run(_bundlePath):
    #
    # Initializes the framework, verifies the plug-in & extracts information, then enters a
    # run loop for handling requests.
    #
    global Identifier
    global Debug
    global __bundlePath
    global __pluginModule
    global __logFilePath
    global __requestHandlers
    global LastPrefix

    FirstRun = False
    random.seed()

    # Set up the support file paths
    pmsPath = "%s/Library/Application Support/Plex Media Server" % os.environ[
        "HOME"]
    supportFilesPath = "%s/Plug-in Support" % pmsPath
    frameworkSupportFilesPath = "%s/Framework Support" % pmsPath
    logFilesPath = "%s/Library/Logs/PMS Plugin Logs" % os.environ["HOME"]

    # Make sure framework directories exist
    def checkpath(path):
        try:
            if not os.path.exists(path): os.makedirs(path)
        except:
            pass

    checkpath("%s/Preferences" % supportFilesPath)
    checkpath("%s/Databases" % supportFilesPath)
    checkpath(logFilesPath)
    checkpath(frameworkSupportFilesPath)

    # Set the bundle path
    __bundlePath = _bundlePath.rstrip('/')

    # Add the bundle path to the system path, including any libraries
    if os.path.isdir("%s/Contents" % __bundlePath):
        sys.path.append("%s/Contents" % __bundlePath)
        if os.path.isdir("%s/Contents/Libraries" % __bundlePath):
            sys.path.append("%s/Contents/Libraries" % __bundlePath)
    else:
        print "Couldn't find bundle directory"
        return None

    # Open the Info.plist file
    f = open("%s/Contents/Info.plist" % __bundlePath, "r")
    infoplist = XML.ElementFromString(f.read())
    f.close()
    if infoplist is None:
        print "Couldn't load Info.plist file from plug-in"
        return

    # Get the plug-in identifier
    Identifier = infoplist.xpath(
        '//key[text()="CFBundleIdentifier"]//following-sibling::string/text()'
    )[0]
    if Identifier is None:
        print "Invalid Info.plist file in plug-in"
        return None

    # Set up the log file
    __logFilePath = "%s/%s.log" % (logFilesPath, Identifier)
    if os.path.exists(__logFilePath):
        if os.path.exists("%s.old" % __logFilePath):
            os.remove("%s.old" % __logFilePath)
        os.rename(__logFilePath, "%s.old" % __logFilePath)

    # Now we can start logging
    PMS.Log("(Framework) Bundle verification complete", False)

    # Check whether debugging is enabled
    try:
        _debug = infoplist.xpath(
            '//key[text()="PlexPluginDebug"]//following-sibling::string/text()'
        )[0]
        if _debug == "1":
            Debug = True
            PMS.Log("(Framework) Debugging is enabled")
    except:
        pass

    # Log the system encoding (set during bootstrap)
    PMS.Log("(Framework) Default encoding is " + sys.getdefaultencoding())

    # Set up framework paths
    Prefs.__prefsPath = "%s/Preferences/%s.xml" % (supportFilesPath,
                                                   Identifier)
    Data.__dataPath = "%s/Data/%s" % (supportFilesPath, Identifier)
    Data.__dataItemPath = "%s/DataItems" % Data.__dataPath
    if not os.path.isdir(Data.__dataItemPath):
        FirstRun = True
        os.makedirs(Data.__dataItemPath)
    Resource.__resourcePath = "%s/Contents/Resources" % __bundlePath
    Helper.__helperPath = "%s/Contents/Helpers" % __bundlePath
    Resource.__sharedResourcePath = "%s/Plug-ins/Framework.bundle/Contents/Resources/Versions/1/Resources" % pmsPath
    Database.__databasePath = "%s/Databases/%s.db" % (supportFilesPath,
                                                      Identifier)
    os.chdir(Data.__dataItemPath)
    Locale.SetDefaultLocale()
    PMS.Log("(Framework) Configured framework modules")

    # Attempt to import the plug-in module - if debugging is enabled, don't catch exceptions
    if Debug:
        import Code as _plugin
        PMS.Log("(Framework) Imported plug-in module")
    else:
        try:
            import Code as _plugin
            PMS.Log("(Framework) Imported plug-in module")
        except ImportError:
            PMS.Log("(Framework) Couldn't import plug-in from bundle")
            __exit()
            return

    # Load the list of trusted plug-ins
    _trusted = []
    try:
        _trustedJSON = Resource.LoadShared("trust.json")
        if _trustedJSON:
            _trusted = JSON.ObjectFromString(_trustedJSON)
    except:
        pass

    # Populate the permission lists
    __setupPermissionLists()

    # Register the plug-in with the framework
    __pluginModule = _plugin

    # Check the imported module to make sure nothing untoward is happening!
    if Identifier in _trusted:
        PMS.Log("(Framework) Plug-in is trusted, skipping module check")
    else:
        __scanModules()
        _allowed = []
        for n in PMS.__dict__:
            if n[0] != "_":
                if type(PMS.__dict__[n]).__name__ == "module":
                    _allowed.append(n)
        for n in __modWhitelist:
            _allowed.append(n)
        __checkModule(_plugin, _allowed)
        PMS.Log("(Framework) Checked module imports")

    # Initialize the framework modules
    Dict.__load()
    if not FirstRun:
        __checkFrameworkCompatibility()
    Prefs.__load()
    HTTP.__loadCookieJar()
    HTTP.__loadCache()
    PMS.Log("(Framework) Initialized framework modules")

    # Call the plug-in's Start method
    PMS.Log("(Framework) Attempting to start the plug-in...")
    __call(__pluginModule.Start)
    PMS.Log("(Framework) Plug-in started", False)

    # Start timers
    __startCacheManager(firstRun=FirstRun)

    PMS.Log("(Framework) Entering run loop")
    # Enter a run loop to handle requests
    while True:
        try:
            # Read the input
            path = raw_input()
            path = path.lstrip("GET ").strip()
            LastPrefix = None

            # Read headers
            headers = {}
            stop = False
            while stop == False:
                line = raw_input()
                if len(line) == 1:
                    stop = True
                else:
                    split = string.split(line.strip(), ":", maxsplit=1)
                    if len(split) == 2:
                        headers[split[0].strip()] = split[1].strip()

            # Set the locale
            if headers.has_key("X-Plex-Language"):
                loc = headers["X-Plex-Language"].lower()
                Locale.__loadLocale(loc)

            # Set the version
            if headers.has_key("X-Plex-Version"):
                Client.__setVersion(headers["X-Plex-Version"])

            # Extract arguments
            kwargs = {}
            mpath = path
            if path.find("?") >= 0:
                parts = path.split("?")
                mpath = parts[0]
                args = parts[1].split("&")
                for arg in args:
                    kwarg = arg.split("=")
                    if len(kwarg) == 2:
                        name = urllib.unquote(kwarg[0])
                        value = urllib.unquote(kwarg[1])
                        kwargs[name] = value
            if mpath[-1] == "/":
                mpath = mpath[:-1]

            # Split the path into components and decode.
            pathNouns = path.split('/')
            pathNouns = [urllib.unquote(p) for p in pathNouns]

            # If no input was given, return an error
            if len(pathNouns) <= 1:
                __return("%s\r\n\r\n" % PMS.Error['BadRequest'])

            # Otherwise, attempt to handle the request
            else:
                result = None
                pathNouns.pop(0)
                count = len(pathNouns)
                if pathNouns[-1] == "":
                    pathNouns.pop(len(pathNouns) - 1)
                PMS.Log("(Framework) Handling request :  %s" % path, False)

                # Check for a management request
                if pathNouns[0] == ":":
                    result = __handlePMSRequest(pathNouns, path, **kwargs)

                else:
                    handler = None
                    isPrefixHandler = False

                    # See if there's a prefix handler available
                    for key in __prefixHandlers:
                        if mpath.count(key, 0, len(key)) == 1:
                            LastPrefix = key
                    if mpath in __prefixHandlers:
                        handler = __prefixHandlers[mpath]["handler"]
                        isPrefixHandler = True

                    else:
                        # Check each request handler to see if it handles the current prefix
                        popped = False
                        for key in __requestHandlers:
                            if handler is None:
                                if path.count(key, 0, len(key)) == 1:
                                    # Remove the prefix from the path
                                    keyNounCount = len(key.split('/')) - 1
                                    for i in range(keyNounCount):
                                        pathNouns.pop(0)
                                    count = count - keyNounCount
                                    # Find the request handler
                                    handler = __requestHandlers[key]["handler"]
                                    LastPrefix = key
                                    popped = True

                        # If no path request handler was found, make sure we still pop the prefix so internal requests work
                        for key in __prefixHandlers:
                            if popped == False:
                                if mpath.count(key, 0, len(key)) == 1:
                                    keyNounCount = len(key.split('/')) - 1
                                    for i in range(keyNounCount):
                                        pathNouns.pop(0)
                                    popped = True

                    # Check whether we should handle the request internally
                    handled = False
                    if count > 0:
                        if pathNouns[0] == ":":
                            handled = True
                            result = __handleInternalRequest(
                                pathNouns, path, **kwargs)

                    # Check if the App Store has flagged the plug-in as broken
                    if os.path.exists(
                            os.path.join(frameworkSupportFilesPath,
                                         "%s.broken" % Identifier)):
                        #TODO: Localise this bit, use message from the App Store if available
                        handled = True
                        result = PMS.Objects.MessageContainer(
                            "Please try again later",
                            "This plug-in is currently unavailable")
                        PMS.Log("(Framework) Plug-in is flagged as broken")

                    # If the request hasn't been handled, and we have a valid request handler, call it
                    else:
                        if not handled and handler is not None:
                            if isPrefixHandler:
                                result = handler(**kwargs)
                            else:
                                result = handler(pathNouns, path, **kwargs)

                # If the request wasn't handled, return an error
                if result == None:
                    PMS.Log("(Framework) Request not handled by plug-in",
                            False)
                    response = "%s\r\n\r\n" % PMS.Error['NotFound']

                # If the plugin returned an error, return it to PMS
                elif result in PMS.Error.values():
                    PMS.Log(
                        "(Framework) Plug-in returned an error :  %s" % result,
                        False)
                    response = "%s\r\n" % result

                # Otherwise, check if a valid object was returned, and return the result
                elif __objectManager.ObjectHasBase(result, Objects.Object):
                    PMS.Log("(Framework) Response OK")
                    resultStr = result.Content()
                    resultStatus = result.Status()
                    resultHeaders = result.Headers()
                    if resultStr is not None:
                        resultLen = len(resultStr)
                        if resultLen > 0:
                            resultHeaders += "Content-Length: %i\r\n" % resultLen
                        resultStr = "\r\n%s" % resultStr
                    else:
                        resultStr = ""
                    response = str("%s\r\n%s" %
                                   (resultStatus, resultHeaders)) + str(
                                       resultStr) + str("\r\n")

                __return(response)

        # If a KeyboardInterrupt (SIGINT) is raised, stop the plugin
        except KeyboardInterrupt:
            # Save data & exit
            __saveData()
            __exit()

        except EOFError:
            # Save data & exit
            __saveData()
            __exit()

        # If another exception is raised, deal with the problem
        except:
            __except()
            __return("%s\r\n\r\n" % PMS.Error['InternalError'])

        # Make sure the plugin's data is saved
        finally:
            __saveData()