示例#1
0
class RemoteHandler(BaseHTTPRequestHandler):
    """
	Serves a HEAD request
	"""
    session = None
    playerCallback = None

    #===========================================================================
    #
    #===========================================================================
    def do_HEAD(self):
        printl("", self, "S")

        printl("Serving HEAD request...", self, "D")
        self.answer_request()

        printl("", self, "C")

    #===========================================================================
    #
    #===========================================================================
    def do_GET(self):
        printl("", self, "S")

        printl("Serving GET request...", self, "D")
        self.answer_request()

        printl("", self, "C")

    #===========================================================================
    #
    #===========================================================================
    def do_OPTIONS(self):
        printl("", self, "S")

        printl("Serving OPTIONS request...", self, "D")
        self.send_response(200)
        self.setAccessControlHeaders()

        printl("", self, "C")

    #===========================================================================
    #
    #===========================================================================
    def answer_request(self):
        printl("", self, "S")

        try:
            self.send_response(200)
            self.setAccessControlHeaders()

            request_path = self.path[1:]
            request_path = re.sub(r"\?.*", "", request_path)

            printl("request path is: [%s]" % request_path, self, "D")

            if request_path == "player/timeline/poll":
                sleep(10)
                xml = "<MediaContainer location='navigation' commandID='10'><Timeline state='stopped' time='0' type='music' /><Timeline state='stopped' time='0' type='video' /><Timeline state='stopped' time='0' type='photo' /></MediaContainer>"
                self.setXmlHeader(xml)
                self.end_headers()
                self.wfile.write(xml)

            elif request_path == "resources":
                xml = self.getResourceXml()
                self.setXmlHeader(xml)
                self.end_headers()
                self.wfile.write(xml)

            elif request_path == "player/timeline/subscribe":
                xml = "<MediaContainer location='navigation' commandID='10'><Timeline state='stopped' time='0' type='music' /><Timeline state='stopped' time='0' type='video' /><Timeline state='stopped' time='0' type='photo' /></MediaContainer>"
                self.setXmlHeader(xml)
                self.end_headers()
                self.wfile.write(xml)

            elif request_path == "player/playback/seekTo":
                params = self.getParams()
                offset = params["offset"][0]

            elif request_path == "player/playback/setParameters":
                params = self.getParams()
                volume = params["volume"][0]

                url = "http://localhost/web/vol?set=set" + str(volume)

                urllib.urlopen(url)
                self.send_response(200)

            elif request_path == "/player/playback/pause":
                url = "http://localhost/web/remotecontrol?command=400"

                urllib.urlopen(url)
                xml = "<MediaContainer location='navigation' commandID='10'><Timeline state='paused' time='0' type='music' /><Timeline state='paused' time='0' type='video' /><Timeline state='paused' time='0' type='photo' /></MediaContainer>"
                self.setXmlHeader(xml)
                self.end_headers()
                self.wfile.write(xml)

            elif request_path == "player/playback/stop":
                url = "http://localhost/web/remotecontrol?command=377"

                urllib.urlopen(url)
                self.send_response(200)

            elif request_path == "player/playback/skipNext":
                url = "http://localhost/web/remotecontrol?command=407"

                urllib.urlopen(url)
                self.send_response(200)

            elif request_path == "player/playback/stepForward":
                url = "http://localhost/web/remotecontrol?command=10"

                urllib.urlopen(url)
                self.send_response(200)

            elif request_path == "player/playback/stepBack":
                url = "http://localhost/web/remotecontrol?command=8"
                urllib.urlopen(url)
                self.send_response(200)

            elif request_path == "player/playback/skipPrevious":
                url = "http://localhost/web/remotecontrol?command=412"

                urllib.urlopen(url)
                self.send_response(200)

            elif request_path == "player/playback/playMedia":

                url = "http://localhost/web/powerstate?newstate=4"
                urllib.urlopen(url)

                params = self.getParams()

                address = params["address"][0]
                port = params["port"][0]
                completeAddress = address + ":" + port
                protocol = params["protocol"][0]
                key = params["key"][0]

                if "offset" in params:
                    offset = int(params["offset"][0])
                else:
                    offset = 0

                machineIdentifier = params["machineIdentifier"][0]
                printl("target machineIdentifier: " + str(machineIdentifier),
                       self, "D")

                for serverConfig in config.plugins.dreamplex.Entries:
                    printl(
                        "current machineIdentifier: " +
                        str(serverConfig.machineIdentifier.value), self, "D")

                    if machineIdentifier in serverConfig.machineIdentifier.value:

                        printl("we have a match ...", self, "D")
                        self.g_serverConfig = serverConfig

                        self.plexInstance = Singleton().getPlexInstance(
                            PlexLibrary(self.session, self.g_serverConfig,
                                        completeAddress, machineIdentifier))

                        listViewList, mediaContainer = self.plexInstance.getMoviesFromSection(
                            protocol + "://" + address + ":" + port + key)

                        autoPlayMode = False

                        if offset > 0:
                            forceResume = True
                        else:
                            forceResume = False

                        resumeMode = False  # this is always false because the ios and android app ask itself if we want to resume :-) no need to ask second time

                        playbackMode = self.g_serverConfig.playbackType.value
                        currentIndex = 0
                        libraryName = "Mixed"

                        data = {
                            "listViewList": listViewList,
                            "mediaContainer": mediaContainer,
                            "autoPlayMode": autoPlayMode,
                            "forceResume": forceResume,
                            "resumeMode": resumeMode,
                            "playbackMode": playbackMode,
                            "currentIndex": currentIndex,
                            "libraryName": libraryName
                        }

                        self.playerCallback(data)

                        xml = "<MediaContainer location='navigation' commandID='10'><Timeline state='stopped' time='0' type='music' /><Timeline state='stopped' time='0' type='video' /><Timeline state='stopped' time='0' type='photo' /></MediaContainer>"
                        self.setXmlHeader(xml)
                        self.end_headers()
                        self.wfile.write(xml)

                    else:
                        printl("no match ...", self, "D")

            else:
                self.send_response(200)
        except:
            traceback.print_exc()
            self.wfile.close()

            printl("", self, "C")
            return
        try:
            self.wfile.close()
        except:
            pass

        printl("", self, "C")

    #===========================================================================
    #
    #===========================================================================
    def address_string(self):
        printl("", self, "S")

        host, port = self.client_address[:2]
        #return socket.getfqdn(host)

        printl("", self, "C")
        return host

    #===========================================================================
    #
    #===========================================================================
    def getResourceXml(self):
        printl("", self, "S")

        xml = "<MediaContainer><Player protocolCapabilities='playback, navigation' product='" + getMyIp(
        ) + "' platformVersion='" + getVersion(
        ) + "' platform='Enigma2' machineIdentifier='" + getUUID(
        ) + "' title='" + config.plugins.dreamplex.boxName.value + "' protocolVersion='1' deviceClass='stb'/></MediaContainer>"

        printl("", self, "C")
        return xml

    #===========================================================================
    #
    #===========================================================================
    def setXmlHeader(self, xml):
        printl("", self, "S")

        self.send_header('Content-type', 'text/xml; charset="utf-8"')
        self.send_header('Content-Length', str(len(xml)))

        printl("", self, "S")

    #===========================================================================
    #
    #===========================================================================
    def setAccessControlHeaders(self):
        printl("", self, "S")

        self.send_header('Access-Control-Allow-Credentials', 'true')
        self.send_header('Access-Control-Allow-Origin', '*')
        self.send_header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')
        self.send_header(
            "Access-Control-Allow-Headers",
            "x-plex-client-identifier,x-plex-device,x-plex-device-name,x-plex-platform,x-plex-platform-version,x-plex-product,x-plex-target-client-identifier,x-plex-username,x-plex-version"
        )

        printl("", self, "S")

    #===========================================================================
    #
    #===========================================================================
    def getParams(self):
        printl("", self, "S")

        printl("", self, "C")
        return parse_qs(urlparse(self.path).query)
示例#2
0
class RemoteHandler(BaseHTTPRequestHandler):
	"""
	Serves a HEAD request
	"""
	session = None
	playerCallback = None


	#===========================================================================
	#
	#===========================================================================
	def do_HEAD(self):
		printl("", self, "S")

		printl("Serving HEAD request...", self, "D")
		self.answer_request()

		printl("", self, "C")

	#===========================================================================
	#
	#===========================================================================
	def do_GET(self):
		printl("", self, "S")

		printl("Serving GET request...", self, "D")
		self.answer_request()

		printl("", self, "C")

	#===========================================================================
	#
	#===========================================================================
	def do_OPTIONS(self):
		printl("", self, "S")

		printl("Serving OPTIONS request...", self, "D")
		self.send_response(200)
		self.setAccessControlHeaders()

		printl("", self, "C")

	#===========================================================================
	#
	#===========================================================================
	def answer_request(self):
		printl("", self, "S")

		try:
			self.send_response(200)
			self.setAccessControlHeaders()

			request_path=self.path[1:]
			request_path=re.sub(r"\?.*","",request_path)

			printl("request path is: [%s]" % request_path, self, "D")

			if request_path == "player/timeline/poll":
				sleep(10)
				xml = "<MediaContainer location='navigation' commandID='10'><Timeline state='stopped' time='0' type='music' /><Timeline state='stopped' time='0' type='video' /><Timeline state='stopped' time='0' type='photo' /></MediaContainer>"
				self.setXmlHeader(xml)
				self.end_headers()
				self.wfile.write(xml)

			elif request_path == "resources":
				xml = self.getResourceXml()
				self.setXmlHeader(xml)
				self.end_headers()
				self.wfile.write(xml)

			elif request_path == "player/timeline/subscribe":
				xml = "<MediaContainer location='navigation' commandID='10'><Timeline state='stopped' time='0' type='music' /><Timeline state='stopped' time='0' type='video' /><Timeline state='stopped' time='0' type='photo' /></MediaContainer>"
				self.setXmlHeader(xml)
				self.end_headers()
				self.wfile.write(xml)

			elif request_path == "player/playback/seekTo":
				params = self.getParams()
				offset =  params["offset"][0]

			elif request_path == "player/playback/setParameters":
				params = self.getParams()
				volume = params["volume"][0]

				url = "http://localhost/web/vol?set=set" + str(volume)

				urllib.urlopen(url)
				self.send_response(200)

			elif request_path == "/player/playback/pause":
				url = "http://localhost/web/remotecontrol?command=400"

				urllib.urlopen(url)
				xml = "<MediaContainer location='navigation' commandID='10'><Timeline state='paused' time='0' type='music' /><Timeline state='paused' time='0' type='video' /><Timeline state='paused' time='0' type='photo' /></MediaContainer>"
				self.setXmlHeader(xml)
				self.end_headers()
				self.wfile.write(xml)

			elif request_path == "player/playback/stop":
				url = "http://localhost/web/remotecontrol?command=377"

				urllib.urlopen(url)
				self.send_response(200)

			elif request_path == "player/playback/skipNext":
				url = "http://localhost/web/remotecontrol?command=407"

				urllib.urlopen(url)
				self.send_response(200)

			elif request_path == "player/playback/stepForward":
				url = "http://localhost/web/remotecontrol?command=10"

				urllib.urlopen(url)
				self.send_response(200)

			elif request_path == "player/playback/stepBack":
				url = "http://localhost/web/remotecontrol?command=8"
				urllib.urlopen(url)
				self.send_response(200)

			elif request_path == "player/playback/skipPrevious":
				url = "http://localhost/web/remotecontrol?command=412"

				urllib.urlopen(url)
				self.send_response(200)

			elif request_path == "player/playback/playMedia":

				url = "http://localhost/web/powerstate?newstate=4"
				urllib.urlopen(url)

				params = self.getParams()

				address = params["address"][0]
				port = params["port"][0]
				completeAddress = address+":"+port
				protocol = params["protocol"][0]
				key = params["key"][0]

				if "offset" in params:
					offset = int(params["offset"][0])
				else:
					offset = 0

				machineIdentifier = params["machineIdentifier"][0]
				printl("target machineIdentifier: " + str(machineIdentifier), self, "D")

				for serverConfig in config.plugins.dreamplex.Entries:
					printl("current machineIdentifier: " + str(serverConfig.machineIdentifier.value), self, "D")

					if machineIdentifier in serverConfig.machineIdentifier.value:

						printl("we have a match ...", self, "D")
						self.g_serverConfig = serverConfig

						self.plexInstance = Singleton().getPlexInstance(PlexLibrary(self.session, self.g_serverConfig, completeAddress, machineIdentifier))

						listViewList, mediaContainer = self.plexInstance.getMoviesFromSection(protocol + "://" + address + ":" + port + key)

						autoPlayMode = False

						if offset > 0:
							forceResume = True
						else:
							forceResume = False

						resumeMode = False # this is always false because the ios and android app ask itself if we want to resume :-) no need to ask second time

						playbackMode = self.g_serverConfig.playbackType.value
						currentIndex = 0
						libraryName = "Mixed"

						data = {"listViewList": listViewList, "mediaContainer": mediaContainer, "autoPlayMode": autoPlayMode, "forceResume":  forceResume, "resumeMode": resumeMode, "playbackMode": playbackMode, "currentIndex": currentIndex, "libraryName": libraryName}

						self.playerCallback(data)

						xml = "<MediaContainer location='navigation' commandID='10'><Timeline state='stopped' time='0' type='music' /><Timeline state='stopped' time='0' type='video' /><Timeline state='stopped' time='0' type='photo' /></MediaContainer>"
						self.setXmlHeader(xml)
						self.end_headers()
						self.wfile.write(xml)

					else:
						printl("no match ...", self, "D")

			else:
				self.send_response(200)
		except:
				traceback.print_exc()
				self.wfile.close()

				printl("", self, "C")
				return
		try:
			self.wfile.close()
		except:
			pass

		printl("", self, "C")

	#===========================================================================
	#
	#===========================================================================
	def address_string(self):
		printl("", self, "S")

		host, port = self.client_address[:2]
		#return socket.getfqdn(host)

		printl("", self, "C")
		return host

	#===========================================================================
	#
	#===========================================================================
	def getResourceXml(self):
		printl("", self, "S")

		xml = "<MediaContainer><Player protocolCapabilities='playback, navigation' product='"+ getMyIp() +"' platformVersion='"+ getVersion() +"' platform='Enigma2' machineIdentifier='"+ getUUID() +"' title='"+ config.plugins.dreamplex.boxName.value +"' protocolVersion='1' deviceClass='stb'/></MediaContainer>"

		printl("", self, "C")
		return xml

	#===========================================================================
	#
	#===========================================================================
	def setXmlHeader(self, xml):
		printl("", self, "S")

		self.send_header('Content-type', 'text/xml; charset="utf-8"')
		self.send_header('Content-Length', str(len(xml)))

		printl("", self, "S")

	#===========================================================================
	#
	#===========================================================================
	def setAccessControlHeaders(self):
		printl("", self, "S")

		self.send_header('Access-Control-Allow-Credentials', 'true')
		self.send_header('Access-Control-Allow-Origin', '*')
		self.send_header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')
		self.send_header("Access-Control-Allow-Headers", "x-plex-client-identifier,x-plex-device,x-plex-device-name,x-plex-platform,x-plex-platform-version,x-plex-product,x-plex-target-client-identifier,x-plex-username,x-plex-version")

		printl("", self, "S")

	#===========================================================================
	#
	#===========================================================================
	def getParams(self):
		printl("", self, "S")

		printl("", self, "C")
		return parse_qs(urlparse(self.path).query)
示例#3
0
class RemoteHandler(BaseHTTPRequestHandler):
	"""
	Serves a HEAD request
	"""
	session = None
	playerCallback = None
	progress = None
	currentCommandId = 0
	protocol_version = 'HTTP/1.1'
	webifInstalled = config.plugins.dreamplex.webifInstalled.value

	#===========================================================================
	#
	#===========================================================================
	def do_HEAD(self):
		printl("", self, "S")

		printl("Serving HEAD request...", self, "D")
		self.answer_request()

		printl("", self, "C")

	#===========================================================================
	#
	#===========================================================================
	def do_GET(self):
		printl("", self, "S")

		printl("Serving GET request...", self, "D")
		self.answer_request()

		printl("", self, "C")

	#===========================================================================
	#
	#===========================================================================
	def do_OPTIONS(self):
		printl("", self, "S")

		printl("Serving OPTIONS request...", self, "D")
		self.send_response(200)
		self.send_header('Content-Length', '0')
		self.send_header('Content-Type', 'text/plain')
		self.send_header('Connection', 'close')
		self.setAccessControlHeaders()
		self.end_headers()
		self.wfile.close()

		printl("", self, "C")

	#===========================================================================
	#
	#===========================================================================
	def response(self, body, headers = {}, code = 200):
		printl("", self, "S")

		try:
			self.send_response(code)

			for key in headers:
				self.send_header(key, headers[key])

			self.send_header('Content-Length', len(body))
			self.send_header('Connection', "close")

			self.setAccessControlHeaders()

			self.end_headers()
			self.wfile.write(body)
			self.wfile.close()
		except:
			pass

		printl("", self, "C")


	#===========================================================================
	#
	#===========================================================================
	def answer_request(self):
		printl("", self, "S")

		try:
			self.send_response(200)

			request_path=self.path[1:]
			request_path=re.sub(r"\?.*","",request_path)

			printl("request path is: [%s]" % request_path, self, "D")

			# first we get all params form url
			params = self.getParams()

			subMgr.updateCommandID(self.headers.get('X-Plex-Client-Identifier', self.client_address[0]), params.get('commandID', False))

			if request_path == "player/timeline/subscribe":
				self.response(getOKMsg(), getPlexHeaders())

				protocol = params.get('protocol', False)
				host = self.client_address[0]
				port = params.get('port', False)
				uuid = self.headers.get('X-Plex-Client-Identifier', "")
				commandID = params.get('commandID', 0)

				print "host: " + str(host)
				print "protocol: " + str(protocol)
				print "port: " + str(port)
				print "uuid: " + str(uuid)
				print "commandID: " + str(commandID)

				subMgr.addSubscriber(protocol, host, port, uuid, commandID)

			elif "player/timeline/unsubscribe" in request_path:
				self.response(getOKMsg(), getPlexHeaders())
				uuid = self.headers.get('X-Plex-Client-Identifier', False) or self.client_address[0]
				subMgr.removeSubscriber(uuid)

			elif request_path == "resources":
				responseContent = getXMLHeader()
				responseContent += str(self.getResourceXml())
				self.response(responseContent, getPlexHeaders())

			elif request_path == "player/timeline/poll":
				if params.get('wait', False) == '1':
					sleep(950)
				commandID = params.get('commandID', 0)
				self.response(re.sub(r"INSERTCOMMANDID", str(commandID), subMgr.msg(getPlayers())), {
				'Access-Control-Expose-Headers': 'X-Plex-Client-Identifier',
				'Content-Type': 'text/xml'
				})

			elif request_path == "playerProgress":
				# subMgr.lastkey = self.currentKey
				# subMgr.server = self.currentServer
				# subMgr.port = self.currentPort
				# subMgr.protocol = self.currentProtocol
				subMgr.progressFromEnigma2 = params['progress']
				subMgr.playerStateFromEnigma2 = params["state"]
				subMgr.durationFromEnigma2 = params["duration"]
				subMgr.lastkey = params["lastKey"]
				subMgr.notify()

			elif request_path == "player/playback/seekTo":
				offset =  params["offset"]

			elif request_path == "player/playback/setParameters":
				volume = params["volume"]

				if self.webifInstalled:
					self.response(getOKMsg(), getPlexHeaders())
					url = "http://localhost/web/vol?set=set" + str(volume)
					urllib.urlopen(url)

			elif request_path == "/player/playback/pause":
				self.response(getOKMsg(), getPlexHeaders())

				if self.webifInstalled:
					url = "http://localhost/web/remotecontrol?command=400"
					urllib.urlopen(url)

			elif request_path == "player/playback/stop":
				self.response(getOKMsg(), getPlexHeaders())

				if self.webifInstalled:
					url = "http://localhost/web/remotecontrol?command=377"
					urllib.urlopen(url)

			elif request_path == "player/playback/skipNext":
				self.response(getOKMsg(), getPlexHeaders())

				if self.webifInstalled:
					url = "http://localhost/web/remotecontrol?command=407"
					urllib.urlopen(url)

			elif request_path == "player/playback/stepForward":
				self.response(getOKMsg(), getPlexHeaders())

				if self.webifInstalled:
					url = "http://localhost/web/remotecontrol?command=10"
					urllib.urlopen(url)

			elif request_path == "player/playback/stepBack":
				self.response(getOKMsg(), getPlexHeaders())

				if self.webifInstalled:
					url = "http://localhost/web/remotecontrol?command=8"
					urllib.urlopen(url)

			elif request_path == "player/playback/skipPrevious":
				self.response(getOKMsg(), getPlexHeaders())
				if self.webifInstalled:
					url = "http://localhost/web/remotecontrol?command=412"
					urllib.urlopen(url)

			elif request_path == "player/playback/playMedia":
				self.response(getOKMsg(), getPlexHeaders())

				if self.webifInstalled:
					url = "http://localhost/web/powerstate?newstate=4"
					urllib.urlopen(url)

				self.currentAddress = params.get('address', self.client_address[0])
				self.currentKey = params['key']
				self.currentPort = params['port']
				self.currentProtocol = params.get('protocol', "http")
				self.currentCompleteAddress = self.currentAddress + ":" + self.currentPort

				if "offset" in params:
					offset = int(params["offset"])
				else:
					offset = 0

				machineIdentifier = params["machineIdentifier"]
				printl("target machineIdentifier: " + str(machineIdentifier), self, "D")

				for serverConfig in config.plugins.dreamplex.Entries:
					printl("current machineIdentifier: " + str(serverConfig.machineIdentifier.value), self, "D")

					if machineIdentifier in serverConfig.machineIdentifier.value:

						printl("we have a match ...", self, "D")
						self.g_serverConfig = serverConfig

						self.plexInstance = Singleton().getPlexInstance(PlexLibrary(self.session, self.g_serverConfig, self.currentCompleteAddress, machineIdentifier))

						listViewList, mediaContainer = self.plexInstance.getMoviesFromSection(self.currentProtocol + "://" + self.currentAddress + ":" + self.currentPort + self.currentKey)

						autoPlayMode = False

						if offset > 0:
							forceResume = True
						else:
							forceResume = False

						resumeMode = False # this is always false because the ios and android app ask itself if we want to resume :-) no need to ask second time

						playbackMode = self.g_serverConfig.playbackType.value
						currentIndex = 0
						libraryName = "Mixed"

						data = {"listViewList": listViewList, "mediaContainer": mediaContainer, "autoPlayMode": autoPlayMode, "forceResume":  forceResume, "resumeMode": resumeMode, "playbackMode": playbackMode, "currentIndex": currentIndex, "libraryName": libraryName}

						self.playerCallback(data)

						# subMgr.lastkey = self.currentKey
						# subMgr.server = self.currentAddress
						# subMgr.port = self.currentPort
						# subMgr.protocol = self.currentProtocol
						# subMgr.notify()

					else:
						printl("no match ...", self, "D")

			else:
				self.send_response(200)
		except:
				traceback.print_exc()
				self.wfile.close()

				printl("", self, "C")
				return
		try:
			self.wfile.close()
		except:
			pass

		printl("", self, "C")

	#===========================================================================
	#
	#===========================================================================
	def address_string(self):
		printl("", self, "S")

		host, port = self.client_address[:2]
		#return socket.getfqdn(host)

		printl("", self, "C")
		return host

	#===========================================================================
	#
	#===========================================================================
	def getResourceXml(self):
		printl("", self, "S")

		xml = "<MediaContainer><Player protocolCapabilities='playback, navigation' product='"+ getMyIp() +"' platformVersion='"+ getVersion() +"' platform='Enigma2' machineIdentifier='"+ getUUID() +"' title='"+ config.plugins.dreamplex.boxName.value +"' protocolVersion='1' deviceClass='stb'/></MediaContainer>"

		printl("", self, "C")
		return xml

	#===========================================================================
	#
	#===========================================================================
	def setXmlHeader(self, xml):
		printl("", self, "S")

		self.send_header('Content-type', 'text/xml; charset="utf-8"')
		self.send_header('Content-Length', str(len(xml)))

		printl("", self, "S")

	#===========================================================================
	#
	#===========================================================================
	def setAccessControlHeaders(self):
		printl("", self, "S")

		self.send_header('X-Plex-Client-Identifier', getUUID())
		self.send_header('Access-Control-Max-Age', '1209600')
		self.send_header('Access-Control-Allow-Credentials', 'true')
		self.send_header('Access-Control-Allow-Origin', '*')
		self.send_header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')
		self.send_header("Access-Control-Allow-Headers", "x-plex-client-identifier,x-plex-device,x-plex-device-name,x-plex-platform,x-plex-platform-version,x-plex-product,x-plex-target-client-identifier,x-plex-username,x-plex-version")

		printl("", self, "S")

	#===========================================================================
	#
	#===========================================================================
	def getParams(self):
		printl("", self, "S")

		params = {}
		paramarrays = parse_qs(urlparse(self.path).query)

		for key in paramarrays:
			params[key] = paramarrays[key][0]

		printl("", self, "C")
		return params