Example #1
0
    def test_new_hacked(self):
        class Sec6:
            pass

        cerealizer.register(Sec6)
        o = Sec6()
        Sec6.__new__ = lambda Class: self.fail()
        cerealizer.loads(cerealizer.dumps(o))
Example #2
0
    def test_setstate_hacked(self):
        class Sec4:
            pass

        cerealizer.register(Sec4)
        o = Sec4()
        Sec4.__setstate__ = lambda obj, state: self.fail()
        cerealizer.loads(cerealizer.dumps(o))
Example #3
0
    def test_getstate_hacked(self):
        class Sec5:
            pass

        cerealizer.register(Sec5)
        o = Sec5()
        Sec5.__getstate__ = lambda obj: self.fail()
        cerealizer.loads(cerealizer.dumps(o))
Example #4
0
    def __init__(self, infoFileName):
        self.songName      = os.path.basename(os.path.dirname(infoFileName))
        self.fileName      = infoFileName
        self.info          = ConfigParser()
        self._difficulties = None

        try:
            self.info.read(infoFileName)
        except:
            pass

        # Read highscores and verify their hashes.
        # There ain't no security like security throught obscurity :)
        self.highScores = {}

        scores = self._get("scores", str, "")
        if scores:
            scores = cerealizer.loads(binascii.unhexlify(scores))
            for difficulty in scores.keys():
                try:
                    difficulty = difficulties[difficulty]
                except KeyError:
                    continue
                for score, stars, name, hash in scores[difficulty.id]:
                    if self.getScoreHash(difficulty, score, stars, name) == hash:
                        self.addHighscore(difficulty, score, stars, name)
                    else:
                        Log.warn("Weak hack attempt detected. Better luck next time.")
Example #5
0
 def poll(self):
   while 1:
     readable_socks, writeable_socks, dropit = select.select(self.socks, self.socks_writing, [], 0.0)
     for sock in readable_socks:
       if   sock is self.udp:
         data = self.udp.recv(65000)
         code = data[0]
         
         self.nb_byte  += len(data) + 8 # 8 is for UDP header
         
         
         if   code == CODE_STATE:
           
           self.nb_state += 1
           
           #import random
           #if random.random() < 0.2: continue
           
           self.udp.send(CODE_ACK_STATE + data[1:13])
           
           level = Unique.undumpsuid(data[1:3])
           round = struct.unpack("!Q", data[3:11])[0]
           
           if level and level.queued_state_round < round:
             level.queued_state       = data[11:]
             level.queued_state_round = round
             
         else: raise NetworkError("Unknown code '%s'!" % code)
         
       elif sock is self.tcp:
         data = sock.read()
         if not data:
           if sock.closed: raise NetworkError("Connexion to server closed!")
           continue
         
         self.nb_byte  += 4 + len(data) + 8
         
         
         print "DATA", len(data), "'%s'" % data[0]
         code = data[0]
         if   code == CODE_MESSAGE:
           obj = Unique.undumpsuid(data[1:3])
           obj.do_message(data[3:])
           
         elif code == CODE_OBJ:
           obj = cerealizer.loads(data[1:])
           obj.loaded() # This calls level.add_mobile if needed
           if   isinstance(obj, Mobile): print "* Tofu * %s received in level %s." % (obj, obj.level)
           elif isinstance(obj, Level ): print "* Tofu * %s received with %s." % (obj, ", ".join([repr(mobile) for mobile in obj.mobiles]))
           else:                         print "* Tofu * %s received." % obj
           
         elif code == CODE_REMOVE_MOBILE:
           mobile = Unique.undumpsuid(data[1:3])
           print "* Tofu * %s removed from %s." % (mobile, mobile.level)
           mobile.level.remove_mobile(mobile)
           mobile.discard()
           
         elif code == CODE_OWN_CONTROL:
           mobile = Unique.undumpsuid(data[1:3])
           mobile.control_owned()
Example #6
0
 def load(self, filename): #load savegame data
     datafileobj = open(filename, "rb")
     data = datafileobj.read()#read in save data
     datafileobj.close()
     data = zlib.decompress(data) #decompress it
     data = cerealizer.loads(data)
     self.obj_props = data[0] #get object properties
     self.game_props = data[1] #and game properties
Example #7
0
 def test_cycle2(self):
   class Obj11(object):
     pass
   cerealizer.register(Obj11)
   o = Obj11()
   o.o = o
   o2 = cerealizer.loads(cerealizer.dumps(o))
   assert o2.o is o2
Example #8
0
	def load(self, filename): #load savegame data
		datafileobj = open(filename, "rb")
		data = datafileobj.read()#read in save data
		datafileobj.close()
		data = zlib.decompress(data) #decompress it
		data = cerealizer.loads(data)
		self.obj_props = data[0] #get object properties
		self.game_props = data[1] #and game properties
Example #9
0
    def test_cycle2(self):
        class ObjEmpty(object):
            pass

        cerealizer.register(ObjEmpty)
        o = ObjEmpty()
        o.o = o
        o2 = cerealizer.loads(cerealizer.dumps(o))
        assert o2.o is o2
Example #10
0
 def test_cycle3(self):
   class Parent: pass
   class Child:
     def __init__(self, parent): self.parent = parent
     def __getstate__(self): return (self.parent,)
     def __setstate__(self, state): self.parent = state[0]
   cerealizer.register(Parent)
   cerealizer.register(Child)
   
   p = Parent()
   p.c = Child(p)
   p2 = cerealizer.loads(cerealizer.dumps(p))
   assert not p2.c.parent is None
Example #11
0
    def testHash(self):
        # For the record, the worldchart used to reject the following 3 hashes...
        # (name strings are UTF8 encoded)
        scoresHash = "63657265616c310a330a646963740a6c6973740a7475706c650a340a"\
                     "6936333834360a69350a7531310a50617363616c4769617264733430"\
                     "0a343839666538656632343239646564373637363835373930303936"\
                     "31323531633136303662373863310a72310a69310a310a72320a72300a"
        scores = cerealizer.loads(binascii.unhexlify(scoresHash))
        #print scores[1][0][2]
        self.assertEqual(scores[1][0][2], "PascalGiard")
        #scoreExtHash = "63657265616c310a330a646963740a6c6973740a7475706c650a"\
        #               "390a7334300a3438396665386566323432396465643736373638"\
        #               "353739303039363132353163313630366237386369350a693236"\
        #               "310a693237300a6937320a7331310a466f4669582d332e313030"\
        #               "69300a73300a6936333834360a310a72310a69310a310a72320a"\
        #               "72300a"
        #songHash = "6551c0f99efddfd3c5c7ef2d407c81b8e3001a43"

        # Worldchart accepts this one (name string is NOT UTF8 encoded)
        scoresHash = "63657265616c310a330a646963740a6c6973740a7475706c650a340a"\
                     "693234323032320a69350a73350a417a7a636f7334300a3233336431"\
                     "37373139653539323066366461373034633432343864646632313930"\
                     "32323939656438310a72310a69300a310a72320a72300a"
        scores = cerealizer.loads(binascii.unhexlify(scoresHash))
        self.assertEqual(scores[0][0][2], "Azzco")
        #print scores[0][0] # Shows that name string IS NOT UTF8 encoded

        # Worldchart used to reject this one (name string is UTF8 encoded)
        scoresHash = "63657265616c310a330a646963740a6c6973740a7475706c650a340a"\
                     "693135313632390a69340a75350a417a7a636f7334300a3661306562"\
                     "35346438343962613065376464363836396430373966386631316366"\
                     "61333133633264310a72310a69300a310a72320a72300a"
        scores = cerealizer.loads(binascii.unhexlify(scoresHash))
        self.assertEqual(scores[0][0][2], "Azzco")
        print scores[0][0] # Shows that name string IS UTF8 encoded
        print scores[0][0][2]
        score = scores[0][0][0], scores[0][0][1], str(scores[0][0][2]), scores[0][0][3]
        print score
Example #12
0
    def test_cycle3(self):
        class Parent: pass
        class Child:
            def __init__(self, parent): self.parent = parent
            def __getstate__(self): return (self.parent,)
            def __setstate__(self, state): self.parent = state[0]

        cerealizer.register(Parent)
        cerealizer.register(Child)

        p = Parent()
        p.c = Child(p)
        p2 = cerealizer.loads(cerealizer.dumps(p))
        assert p2.c.parent is not None
Example #13
0
 def test_alias1(self):
   class OldObj(object):
     def __init__(self):
       self.x    = 1
       self.name = "jiba"
   cerealizer.register(OldObj)
   o = OldObj()
   s = cerealizer.dumps(o)
   
   reload(cerealizer)
   class NewObj(object):
     def __init__(self):
       self.x    = 2
       self.name = "jiba2"
   cerealizer.register(NewObj)
   cerealizer.register_alias(NewObj, "__main__.OldObj")
   o = cerealizer.loads(s)
   assert o.__class__ is NewObj
   assert o.x    == 1
   assert o.name == "jiba"
Example #14
0
    def test_alias(self):
        class OldObj(object):
            def __init__(self):
                self.x = 1
                self.name = "jiba"
        cerealizer.register(OldObj)
        o = OldObj()
        s = cerealizer.dumps(o)

        imp.reload(cerealizer)
        class NewObj(object):
            def __init__(self):
                self.x = 2
                self.name = "jiba2"
        cerealizer.register(NewObj)
        cerealizer.register_alias(NewObj, "__main__.OldObj")
        o = cerealizer.loads(s)
        assert o.__class__ is NewObj
        assert o.x == 1
        assert o.name == "jiba"
Example #15
0
def MediaInfoLookup(url):

	"""
	Returns the media info stored in the recently browsed item list
	for the given provider URL or None if the item isn't found in the
	recently browsed item list.
	"""
	
	# Get clean copy of URL user has played.
	decoded_url = String.Decode(str(url))
	#Log(decoded_url)
	
	# See if the URL being played is on our recently browsed list.
	item = cerealizer.loads(Data.Load(BROWSED_ITEMS_KEY)).getByURL(decoded_url)

	if (item is None):
		Log("****** ERROR: Watching Item which hasn't been browsed to")
		return ""
	
	# Return the media info that was stored in the recently browsed item.
	return demjson.encode(item[0])
Example #16
0
def loads(s):
  return cerealizer.loads(base64.decodestring(s))
Example #17
0
 def test_craked_file1(self):
     craked_file = "cereal1\n2\n__builtin__.dict\nfile\n0\nr0\nr1\n"
     #self.assertRaises(StandardError, lambda: cerealizer.loads(craked_file))
     self.assertRaises(Exception, lambda: cerealizer.loads(craked_file))
Example #18
0
 def test_cycle1(self):
   obj1 = [1, [2.2, "jiba"]]
   obj1[1].append(obj1)
   obj2 = cerealizer.loads(cerealizer.dumps(obj1))
   assert repr(obj1) == repr(obj2) # Cannot use == on cyclic list!
Example #19
0
 def loads_dumps_and_compare(self, obj1):
   obj2 = cerealizer.loads(cerealizer.dumps(obj1))
   assert obj1 == obj2
Example #20
0
 def test_identity(self):
     o = {}
     l1 = [o, o]
     l2 = cerealizer.loads(cerealizer.dumps(l1))
     assert l2[0] is l2[1]
Example #21
0
def loads(objstr):
    """ De-serialize the given string into it's original form. """
    obj = cerealizer.loads(objstr)
    return obj
Example #22
0
def unpack(string):
    unquoted_string = urllib.unquote(string)
    decoded_string = safe_decode(unquoted_string)
    return cerealizer.loads(decoded_string)
Example #23
0
 def test_new_hacked(self):
   class Sec6: pass
   cerealizer.register(Sec6)
   o = Sec6()
   Sec6.__new__ = lambda Class: self.fail()
   cerealizer.loads(cerealizer.dumps(o))
Example #24
0
 def test_craked_file1(self):
   craked_file = "cereal1\n2\n__builtin__.dict\nfile\n0\nr0\nr1\n"
   self.assertRaises(StandardError, lambda : cerealizer.loads(craked_file))
Example #25
0
 def testIntegrity(self):
     expected = self.scores
     scoresSerial = binascii.hexlify(cerealizer.dumps(self.scores))
     result = cerealizer.loads(binascii.unhexlify(scoresSerial))
     self.assertEqual(result, expected)
Example #26
0
 def deserialize(in_string):
     try:
         return pickle.loads(in_string)
     except EOFError:
         fail_message = Message(FAILURE,FAILURE)
         return fail_message
Example #27
0
 def loads_dumps_and_compare(self, obj1):
     obj2 = cerealizer.loads(cerealizer.dumps(obj1))
     assert obj1 == obj2
Example #28
0
cerealizer.freeze_configuration()


l = []
for i in range(20000):
  o = O()
  if l: o.o = l[-1]
  l.append(o)

print("cerealizer")
t = time.time()
s = cerealizer.dumps(l)
print("dumps in", time.time() - t, "s,", len(s), "bytes length")

t = time.time()
l2 = cerealizer.loads(s)
print("loads in", time.time() - t, "s")


import pickle

print()
print("pickle")
t = time.time()
s = pickle.dumps(l)
print("dumps in", time.time() - t, "s,", len(s), "bytes length")

t = time.time()
l2 = pickle.loads(s)
print("loads in", time.time() - t, "s")
Example #29
0
def add_score(request):
    """
    Add a score for a player and a song

    Returns a binary HttpResponse.
    """
    # scores_to_insert = list()

    # get GET params
    song_title = escape(request.GET.get('songName', None))
    song_hash = escape(request.GET.get('songHash', None))
    song_instrument = escape(request.GET.get('songPart', None))
    scores = escape(request.GET.get('scores', None))
    version = escape(request.GET.get('version', None))
    timestamp = escape(request.GET.get("timestamp", timezone.now()))
    remote_addr = request.META.get("REMOTE_ADDR", None)

    # check params
    if song_title is None or scores is None:
        return HttpResponse(False)

    # decode scores
    try:
        scores_decoded = cerealizer.loads(binascii.unhexlify(scores))
    except ValueError:
        return HttpResponse(False)

    # log the event
    logger.info(f"New scores for the game version {version} at {remote_addr} for the song '{song_title}'",
        version, remote_addr, song_title)

    # find the song or create it
    song, created_song = Song.objects.get_or_create(
        defaults={'title': song_title},
        title__iexact=song_title,
    )
    if not song.notes:
        song.notes = song_hash
        song.save()
    # multiple Songs with the same title
    if song.notes != song_hash:
        now_iso = datetime.now().isoformat()
        new_song_title = song_title + ' ' + now_iso
        song = Song.objects.create(title=new_song_title, notes=song_hash)
        logger.info(f"Duplicate the song '{song_title}'", song_title)

    # get scores items
    for difficulty_id, scores_items in scores_decoded.items():
        for score, stars, name, hash_score in scores_items:
            # check the hash
            hash_str = "%d%d%d%s" % (difficulty_id, score, stars, name)
            hash_bytes = bytes(hash_str, 'utf-8')
            hash_sha = hashlib.sha1(hash_bytes).hexdigest()
            if hash_score != hash_sha:
                continue

            # check stars number
            if stars < 0 or stars > Score.MAX_STARS:
                continue

            # check the difficulty
            if difficulty_id < 0 or difficulty_id >= len(Score.DIFFICULTIES):
                continue
            difficulty = Score.DIFFICULTIES[difficulty_id][0]

            # add scores to the list
            logger.info(f"Insert: score {score}, stars {stars}, difficulty {difficulty}, song '{name}'",
                score, stars, difficulty, name)
            # scores_to_insert.append((difficulty, score, stars, name))

            # find the player or create it
            player, created_player = Player.objects.get_or_create(
                name=name,
            )
            player.remote_address = remote_addr
            player.save()

            # write scores
            try:
                Score.objects.update_or_create(
                    song=song,
                    player=player,
                    difficulty=difficulty,
                    score=score,
                    stars=stars,
                    date=timestamp,
                    version=version,
                    instrument=song_instrument,
                )
            except IntegrityError:
                return HttpResponse(False)

    return HttpResponse(True)
Example #30
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
    if sys.platform == "win32":
        if 'PLEXLOCALAPPDATA' in os.environ:
            key = 'PLEXLOCALAPPDATA'
        else:
            key = 'LOCALAPPDATA'
        pmsPath = os.path.join(os.environ[key], 'Plex Media Server')
        logFilesPath = os.path.join(os.environ[key], "Plex Media Server",
                                    "Logs", "PMS Plugin Logs")
    else:
        pmsPath = "%s/Library/Application Support/Plex Media Server" % os.environ[
            "HOME"]
        logFilesPath = "%s/Library/Logs/Plex Media Server/PMS Plugin Logs" % os.environ[
            "HOME"]

    supportFilesPath = "%s/Plug-in Support" % pmsPath
    frameworkSupportFilesPath = "%s/Framework Support" % pmsPath

    # 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()
    if HTTP_TIMEOUT_VAR_NAME in os.environ:
        HTTP.SetTimeout(float(os.environ[HTTP_TIMEOUT_VAR_NAME]))
    else:
        HTTP.SetTimeout(HTTP_DEFAULT_TIMEOUT)
    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"])

            PMS.Request.Headers.clear()
            PMS.Request.Headers.update(headers)

            req = urlparse.urlparse(path)
            path = req.path
            qs_args = cgi.parse_qs(req.query)
            kwargs = {}
            if 'function_args' in qs_args:
                try:
                    unquoted_args = urllib.unquote(qs_args['function_args'][0])
                    decoded_args = PMS.String.Decode(unquoted_args)
                    kwargs = cerealizer.loads(decoded_args)
                except:
                    PMS.Log(PMS.Plugin.Traceback())
                    raise Exception("Unable to deserialize arguments")

            for arg_name in qs_args:
                if arg_name != 'function_args':
                    kwargs[arg_name] = qs_args[arg_name][0]

            # First, try to match a connected route
            rpath = path
            for key in __prefixHandlers:
                if rpath.count(key, 0, len(key)) == 1:
                    rpath = rpath[len(key):]
                    break
            f, route_kwargs = MatchRoute(rpath)

            if f is not None:
                PMS.Log("(Framework) Handling route request :  %s" % path,
                        False)
                route_kwargs.update(kwargs)
                result = f(**route_kwargs)

            # No route, fall back to other path handling methods
            else:
                mpath = path

                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)

            response = None

            # 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\r\n" % result

            # Otherwise, check if a valid object was returned, and return the result
            elif __objectManager.ObjectHasBase(result, Objects.Object):
                resultStr = result.Content()
                resultStatus = result.Status()
                resultHeaders = result.Headers()

            elif isinstance(result, basestring):
                resultStr = result
                resultStatus = '200 OK'
                resultHeaders = "Content-type: text/plain\r\n"

            if resultStr is not None:
                PMS.Log("(Framework) Response OK")
                resultLen = len(resultStr)
                if resultLen > 0:
                    resultHeaders += "Content-Length: %i\r\n" % resultLen
                    resultStr = "\r\n" + resultStr

            else:
                resultStr = ""
                resultStatus = '500 Internal Server Error'
                resultHeaders = ''
                PMS.Log("(Framework) Unknown response type")

            if response == None:
                response = str("%s\r\n%s" %
                               (resultStatus,
                                resultHeaders)) + str(resultStr) + str("\r\n")

            #PMS.Log("\n---\n"+response+"---\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()
Example #31
0
 def test_getstate_hacked(self):
   class Sec5: pass
   cerealizer.register(Sec5)
   o = Sec5()
   Sec5.__getstate__ = lambda obj: self.fail()
   cerealizer.loads(cerealizer.dumps(o))
Example #32
0
 def test_identity(self):
   o  = {}
   l1 = [o, o]
   l2 = cerealizer.loads(cerealizer.dumps(l1))
   assert l2[0] is l2[1]
Example #33
0
 def test_setstate_hacked(self):
   class Sec4: pass
   cerealizer.register(Sec4)
   o = Sec4()
   Sec4.__setstate__ = lambda obj, state: self.fail()
   cerealizer.loads(cerealizer.dumps(o))
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
  if sys.platform == "win32":
    if 'PLEXLOCALAPPDATA' in os.environ:
      key = 'PLEXLOCALAPPDATA'
    else:
      key = 'LOCALAPPDATA'
    pmsPath = os.path.join(os.environ[key], 'Plex Media Server')
    logFilesPath = os.path.join(os.environ[key], "Plex Media Server", "Logs", "PMS Plugin Logs")
  else:
    pmsPath = "%s/Library/Application Support/Plex Media Server" % os.environ["HOME"]
    logFilesPath = "%s/Library/Logs/PMS Plugin Logs" % os.environ["HOME"]
  
  supportFilesPath = "%s/Plug-in Support" % pmsPath
  frameworkSupportFilesPath = "%s/Framework Support" % pmsPath
  
  # 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()
  if HTTP_TIMEOUT_VAR_NAME in os.environ:
    HTTP.SetTimeout(float(os.environ[HTTP_TIMEOUT_VAR_NAME]))
  else:
    HTTP.SetTimeout(HTTP_DEFAULT_TIMEOUT)
  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"])

      PMS.Request.Headers.clear()
      PMS.Request.Headers.update(headers)
      
      req = urlparse.urlparse(path)
      path = req.path
      qs_args = cgi.parse_qs(req.query)
      kwargs = {}
      if 'function_args' in qs_args:
        try:
          unquoted_args = urllib.unquote(qs_args['function_args'][0])
          decoded_args = PMS.String.Decode(unquoted_args)
          kwargs = cerealizer.loads(decoded_args)
        except:
          PMS.Log(PMS.Plugin.Traceback())
          raise Exception("Unable to deserialize arguments")
      
      for arg_name in qs_args:
        if arg_name != 'function_args':
          kwargs[arg_name] = qs_args[arg_name][0]
      
      # First, try to match a connected route
      rpath = path
      for key in __prefixHandlers:
        if rpath.count(key, 0, len(key)) == 1:
          rpath = rpath[len(key):]
          break
      f, route_kwargs = MatchRoute(rpath)
      
      if f is not None:
        PMS.Log("(Framework) Handling route request :  %s" % path, False)
        route_kwargs.update(kwargs)
        result = f(**route_kwargs)

      # No route, fall back to other path handling methods
      else:
        mpath = path
        
        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)
        
      response = None
      
      # 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\r\n" % result
        
      # Otherwise, check if a valid object was returned, and return the result
      elif __objectManager.ObjectHasBase(result, Objects.Object):
        resultStr = result.Content()
        resultStatus = result.Status()
        resultHeaders = result.Headers()
      
      elif isinstance(result, basestring):
        resultStr = result
        resultStatus = '200 OK'
        resultHeaders = "Content-type: text/plain\r\n"
      
      if resultStr is not None:
        PMS.Log("(Framework) Response OK")
        resultLen = len(resultStr)
        if resultLen > 0:
          resultHeaders += "Content-Length: %i\r\n" % resultLen
          resultStr = "\r\n"+resultStr
        
      else:
        resultStr = ""
        resultStatus = '500 Internal Server Error'
        resultHeaders = ''
        PMS.Log("(Framework) Unknown response type")
        
      if response == None:
        response = str("%s\r\n%s" % (resultStatus, resultHeaders)) + str(resultStr) + str("\r\n")
      
      #PMS.Log("\n---\n"+response+"---\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()
Example #35
0
 def test_cycle1(self):
     obj1 = [1, [2.2, "jiba"]]
     obj1[1].append(obj1)
     obj2 = cerealizer.loads(cerealizer.dumps(obj1))
     assert repr(obj1) == repr(obj2) # Cannot use == on cyclic list!