def __init__(self):
		self.playerData = ThreadQueue()
		self.playerDataPump = ePythonMessagePump()
		self.subMgr = SubscriptionManager()
class RemoteHandler(BaseHTTPRequestHandler):
	"""
	Serves a HEAD request
	"""
	session = None
	playerCallback = None
	progress = None
	currentCommandId = 0
	protocol_version = 'HTTP/1.1'

	#===========================================================================
	#
	#===========================================================================
	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:
			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()

			data = {"command": "updateCommandId", "uuid": self.headers.get('X-Plex-Client-Identifier', self.client_address[0]), "commandID": params.get('commandID', False)}
			self.playerCallback(data)
			self.resetCallback()

			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)

				printl("host: " + str(host), self, "D")
				printl("protocol: " + str(protocol), self, "D")
				printl("port: " + str(port), self, "D")
				printl("uuid: " + str(uuid), self, "D")
				printl("commandID: " + str(commandID), self, "D")

				data = {"command": "addSubscriber", "protocol": protocol, "host": host, "port": port, "uuid": uuid, "commandID": commandID}
				#subMgr.addSubscriber(protocol, host, port, uuid, commandID)
				self.playerCallback(data)
				self.resetCallback()

			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]
				data = {"command": "removeSubscriber", "uuid": uuid}
				#subMgr.removeSubscriber(uuid)
				self.playerCallback(data)
				self.resetCallback()

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

			elif request_path == "player/timeline/poll":
				commandID = params.get('commandID', 0)
				self.subMgr = SubscriptionManager()
				try:
					e2params = self.session.current_dialog.getPlayerState()
					if e2params:
						self.subMgr.progressFromEnigma2 = e2params['progress']
						self.subMgr.playerStateFromEnigma2 = e2params["state"]
						self.subMgr.durationFromEnigma2 = e2params["duration"]
						self.subMgr.lastkey = e2params["lastKey"]

					self.answerPoll(commandID)
					sleep(1)
				except:
					print "no params"
					self.answerPoll(commandID)
					sleep(1)

			elif request_path == "player/playback/setParameters":
				volume = params["volume"]
				data = {"command": "setVolume", "volume": volume}

				self.playerCallback(data)
				self.resetCallback()

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

				self.playerCallback(data)
				self.resetCallback()

			elif request_path == "player/playback/play":
				self.response(getOKMsg(), getPlexHeaders())
				data = {"command": "play"}

				self.playerCallback(data)
				self.resetCallback()

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

				self.playerCallback(data)
				self.resetCallback()

			elif request_path == "player/playback/skipNext":
				self.response(getOKMsg(), getPlexHeaders())
				data = {"command": "skipNext"}
				self.playerCallback(data)
				self.resetCallback()

			elif request_path == "player/playback/skipPrevious":
				self.response(getOKMsg(), getPlexHeaders())
				data = {"command": "skipPrevious"}

				self.playerCallback(data)
				self.resetCallback()

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

				self.playerCallback(data)
				self.resetCallback()

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

				self.playerCallback(data)
				self.resetCallback()

			elif request_path == "player/playback/seekTo":
				self.response(getOKMsg(), getPlexHeaders())
				offset =  params["offset"]
				data = {"command": "seekTo", "offset": offset}

				self.playerCallback(data)
				self.resetCallback()

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

				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.getMixedContentFromSection(self.currentProtocol + "://" + self.currentAddress + ":" + self.currentPort + self.currentKey, fromRemotePlayer=True)

						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"
						splittedData = self.currentKey.split("/")
						subtitleData = self.plexInstance.getSelectedSubtitleDataById(self.currentCompleteAddress, splittedData[-1])

						data = {"command": "playMedia", "currentKey": self.currentKey, "listViewList": listViewList, "mediaContainer": mediaContainer, "autoPlayMode": autoPlayMode, "forceResume":  forceResume, "resumeMode": resumeMode, "playbackMode": playbackMode, "currentIndex": currentIndex, "libraryName": libraryName, "subtitleData": subtitleData }

						self.playerCallback(data)
						self.resetCallback()

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

			else:
				self.response(getOKMsg(), getPlexHeaders())
		except:
				traceback.print_exc()
				self.wfile.close()

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

		printl("", self, "C")

	#===========================================================================
	#
	#===========================================================================
	def resetCallback(self):
		# we do this due to the fact that the messagepump is triggered mor often than we want to via playercallback for this reason we set to idle so that for example playMedia command is not called more than once
		data = {"command": "idle"}
		self.playerCallback(data)

	#===========================================================================
	#
	#===========================================================================
	def answerPoll(self, commandID):
		self.response(re.sub(r"INSERTCOMMANDID", str(commandID), self.subMgr.msg(self.getPlayers())), {
			'Access-Control-Expose-Headers': 'X-Plex-Client-Identifier',
			'Content-Type': 'text/xml'
			})

	#===========================================================================
	#
	#===========================================================================
	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

	#===========================================================================
	#
	#===========================================================================
	def getPlayers(self):
		ret = {}

		try:
			ret = self.session.current_dialog.getPlayer()
		except:
			pass

		return ret
class HttpDeamon(Thread):

	session = None
	httpd = None
	deamonState = None

	#===========================================================================
	#
	#===========================================================================
	def __init__(self):
		self.playerData = ThreadQueue()
		self.playerDataPump = ePythonMessagePump()
		self.subMgr = SubscriptionManager()

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

		printl("", self, "C")
		return self.playerDataPump

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

		printl("", self, "C")
		return self.playerData

	#===========================================================================
	#
	#===========================================================================
	def setSession(self, session):
		self.session = session
		self.subMgr.session = session
		self.start()

	#===========================================================================
	#PROPERTIES
	#===========================================================================
	PlayerDataPump = property(getPlayerDataPump)
	PlayerData = property(getPlayerDataQueue)

	#===========================================================================
	#
	#===========================================================================
	def notifySubscribers(self, players):
		self.subMgr.notify(players)

	#===========================================================================
	#
	#===========================================================================
	def addSubscriber(self, protocol, host, port, uuid, commandID):
		self.subMgr.addSubscriber(protocol, host, port, uuid, commandID)

	#===========================================================================
	#
	#===========================================================================
	def getSubscribersList(self):
		return self.subMgr.getSubscribersList()

	#===========================================================================
	#
	#===========================================================================
	def removeSubscriber(self, uuid):
		self.subMgr.removeSubscriber(uuid)

	#===========================================================================
	#
	#===========================================================================
	def updateCommandID(self, uuid, commandID):
		self.subMgr.updateCommandID(uuid, commandID)

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

		Thread.__init__(self)

		self.HandlerClass = RemoteHandler
		self.ServerClass = HTTPServer
		self.protocol = "HTTP/1.0"
		self.myIp = getMyIp()

		if not self.myIp:
			self.deamonState = False
			self.registered = False
			return

		try:
			# this starts updatemechanism to show up as player in devices like ios
			self.client = PlexGdm()
			self.client.setClientDetails()
			self.client.start_registration()
		except:
			self.deamonState = False
			return

		if self.client.check_client_registration():
			self.registered = True
			printl("Successfully registered", self, "D")
		else:
			self.registered = False
			printl("Unsuccessfully registered", self, "D")

		self.deamonState = True

		printl("", self, "C")

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

		printl("", self, "C")
		return self.registered, self.deamonState

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

		self.client.stop_all()

		self.httpd.shutdown()

		printl("", self, "C")

	#===========================================================================
	#
	#===========================================================================
	#def runHttp(session, playerCallback, HandlerClass = MyHandler,ServerClass = HTTPServer, protocol="HTTP/1.0"):
	def run(self):
		printl("", __name__, "S")
		server_address = ("", config.plugins.dreamplex.remotePort.value)

		self.HandlerClass.protocol_version = self.protocol
		self.HandlerClass.session = self.session
		self.HandlerClass.playerCallback = self.nowDoIt
		self.httpd = self.ServerClass(server_address, self.HandlerClass)

		sa = self.httpd.socket.getsockname()

		self.remoteListenerInformation = "Serving HTTP on " + str(sa[0]) + " port " + str(sa[1])

		printl(self.remoteListenerInformation, __name__, "D")
		self.httpd.serve_forever()

		printl("", __name__, "C")

	#===========================================================================
	#
	#===========================================================================
	def nowDoIt(self, data):
		printl("", __name__, "S")

		self.playerData.push((data,))
		self.playerDataPump.send(0)

		printl("", __name__, "C")
	def answer_request(self):
		printl("", self, "S")

		try:
			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()

			data = {"command": "updateCommandId", "uuid": self.headers.get('X-Plex-Client-Identifier', self.client_address[0]), "commandID": params.get('commandID', False)}
			self.playerCallback(data)
			self.resetCallback()

			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)

				printl("host: " + str(host), self, "D")
				printl("protocol: " + str(protocol), self, "D")
				printl("port: " + str(port), self, "D")
				printl("uuid: " + str(uuid), self, "D")
				printl("commandID: " + str(commandID), self, "D")

				data = {"command": "addSubscriber", "protocol": protocol, "host": host, "port": port, "uuid": uuid, "commandID": commandID}
				#subMgr.addSubscriber(protocol, host, port, uuid, commandID)
				self.playerCallback(data)
				self.resetCallback()

			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]
				data = {"command": "removeSubscriber", "uuid": uuid}
				#subMgr.removeSubscriber(uuid)
				self.playerCallback(data)
				self.resetCallback()

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

			elif request_path == "player/timeline/poll":
				commandID = params.get('commandID', 0)
				self.subMgr = SubscriptionManager()
				try:
					e2params = self.session.current_dialog.getPlayerState()
					if e2params:
						self.subMgr.progressFromEnigma2 = e2params['progress']
						self.subMgr.playerStateFromEnigma2 = e2params["state"]
						self.subMgr.durationFromEnigma2 = e2params["duration"]
						self.subMgr.lastkey = e2params["lastKey"]

					self.answerPoll(commandID)
					sleep(1)
				except:
					print "no params"
					self.answerPoll(commandID)
					sleep(1)

			elif request_path == "player/playback/setParameters":
				volume = params["volume"]
				data = {"command": "setVolume", "volume": volume}

				self.playerCallback(data)
				self.resetCallback()

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

				self.playerCallback(data)
				self.resetCallback()

			elif request_path == "player/playback/play":
				self.response(getOKMsg(), getPlexHeaders())
				data = {"command": "play"}

				self.playerCallback(data)
				self.resetCallback()

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

				self.playerCallback(data)
				self.resetCallback()

			elif request_path == "player/playback/skipNext":
				self.response(getOKMsg(), getPlexHeaders())
				data = {"command": "skipNext"}
				self.playerCallback(data)
				self.resetCallback()

			elif request_path == "player/playback/skipPrevious":
				self.response(getOKMsg(), getPlexHeaders())
				data = {"command": "skipPrevious"}

				self.playerCallback(data)
				self.resetCallback()

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

				self.playerCallback(data)
				self.resetCallback()

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

				self.playerCallback(data)
				self.resetCallback()

			elif request_path == "player/playback/seekTo":
				self.response(getOKMsg(), getPlexHeaders())
				offset =  params["offset"]
				data = {"command": "seekTo", "offset": offset}

				self.playerCallback(data)
				self.resetCallback()

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

				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.getMixedContentFromSection(self.currentProtocol + "://" + self.currentAddress + ":" + self.currentPort + self.currentKey, fromRemotePlayer=True)

						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"
						splittedData = self.currentKey.split("/")
						subtitleData = self.plexInstance.getSelectedSubtitleDataById(self.currentCompleteAddress, splittedData[-1])

						data = {"command": "playMedia", "currentKey": self.currentKey, "listViewList": listViewList, "mediaContainer": mediaContainer, "autoPlayMode": autoPlayMode, "forceResume":  forceResume, "resumeMode": resumeMode, "playbackMode": playbackMode, "currentIndex": currentIndex, "libraryName": libraryName, "subtitleData": subtitleData }

						self.playerCallback(data)
						self.resetCallback()

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

			else:
				self.response(getOKMsg(), getPlexHeaders())
		except:
				traceback.print_exc()
				self.wfile.close()

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

		printl("", self, "C")
Exemple #5
0
 def __init__(self):
     self.playerData = ThreadQueue()
     self.playerDataPump = ePythonMessagePump()
     self.subMgr = SubscriptionManager()
Exemple #6
0
class HttpDeamon(Thread):

    session = None
    httpd = None
    deamonState = None

    #===========================================================================
    #
    #===========================================================================
    def __init__(self):
        self.playerData = ThreadQueue()
        self.playerDataPump = ePythonMessagePump()
        self.subMgr = SubscriptionManager()

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

        printl("", self, "C")
        return self.playerDataPump

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

        printl("", self, "C")
        return self.playerData

    #===========================================================================
    #
    #===========================================================================
    def setSession(self, session):
        self.session = session
        self.subMgr.session = session
        self.start()

    #===========================================================================
    #PROPERTIES
    #===========================================================================
    PlayerDataPump = property(getPlayerDataPump)
    PlayerData = property(getPlayerDataQueue)

    #===========================================================================
    #
    #===========================================================================
    def notifySubscribers(self, players):
        self.subMgr.notify(players)

    #===========================================================================
    #
    #===========================================================================
    def addSubscriber(self, protocol, host, port, uuid, commandID):
        self.subMgr.addSubscriber(protocol, host, port, uuid, commandID)

    #===========================================================================
    #
    #===========================================================================
    def getSubscribersList(self):
        return self.subMgr.getSubscribersList()

    #===========================================================================
    #
    #===========================================================================
    def removeSubscriber(self, uuid):
        self.subMgr.removeSubscriber(uuid)

    #===========================================================================
    #
    #===========================================================================
    def updateCommandID(self, uuid, commandID):
        self.subMgr.updateCommandID(uuid, commandID)

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

        Thread.__init__(self)

        self.HandlerClass = RemoteHandler
        self.ServerClass = HTTPServer
        self.protocol = "HTTP/1.0"
        self.myIp = getMyIp()

        if not self.myIp:
            self.deamonState = False
            self.registered = False
            return

        try:
            # this starts updatemechanism to show up as player in devices like ios
            self.client = PlexGdm()
            self.client.setClientDetails()
            self.client.start_registration()
        except:
            self.deamonState = False
            return

        if self.client.check_client_registration():
            self.registered = True
            printl("Successfully registered", self, "D")
        else:
            self.registered = False
            printl("Unsuccessfully registered", self, "D")

        self.deamonState = True

        printl("", self, "C")

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

        printl("", self, "C")
        return self.registered, self.deamonState

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

        self.client.stop_all()

        self.httpd.shutdown()

        printl("", self, "C")

    #===========================================================================
    #
    #===========================================================================
    #def runHttp(session, playerCallback, HandlerClass = MyHandler,ServerClass = HTTPServer, protocol="HTTP/1.0"):
    def run(self):
        printl("", __name__, "S")
        server_address = ("", config.plugins.dreamplex.remotePort.value)

        self.HandlerClass.protocol_version = self.protocol
        self.HandlerClass.session = self.session
        self.HandlerClass.playerCallback = self.nowDoIt
        self.httpd = self.ServerClass(server_address, self.HandlerClass)

        sa = self.httpd.socket.getsockname()

        self.remoteListenerInformation = "Serving HTTP on " + str(
            sa[0]) + " port " + str(sa[1])

        printl(self.remoteListenerInformation, __name__, "D")
        self.httpd.serve_forever()

        printl("", __name__, "C")

    #===========================================================================
    #
    #===========================================================================
    def nowDoIt(self, data):
        printl("", __name__, "S")

        self.playerData.push((data, ))
        self.playerDataPump.send(0)

        printl("", __name__, "C")
Exemple #7
0
class RemoteHandler(BaseHTTPRequestHandler):
    """
	Serves a HEAD request
	"""
    session = None
    playerCallback = None
    progress = None
    currentCommandId = 0
    protocol_version = 'HTTP/1.1'

    #===========================================================================
    #
    #===========================================================================
    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:
            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()

            data = {
                "command":
                "updateCommandId",
                "uuid":
                self.headers.get('X-Plex-Client-Identifier',
                                 self.client_address[0]),
                "commandID":
                params.get('commandID', False)
            }
            self.playerCallback(data)
            self.resetCallback()

            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)

                printl("host: " + str(host), self, "D")
                printl("protocol: " + str(protocol), self, "D")
                printl("port: " + str(port), self, "D")
                printl("uuid: " + str(uuid), self, "D")
                printl("commandID: " + str(commandID), self, "D")

                data = {
                    "command": "addSubscriber",
                    "protocol": protocol,
                    "host": host,
                    "port": port,
                    "uuid": uuid,
                    "commandID": commandID
                }
                #subMgr.addSubscriber(protocol, host, port, uuid, commandID)
                self.playerCallback(data)
                self.resetCallback()

            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]
                data = {"command": "removeSubscriber", "uuid": uuid}
                #subMgr.removeSubscriber(uuid)
                self.playerCallback(data)
                self.resetCallback()

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

            elif request_path == "player/timeline/poll":
                commandID = params.get('commandID', 0)
                self.subMgr = SubscriptionManager()
                try:
                    e2params = self.session.current_dialog.getPlayerState()
                    if e2params:
                        self.subMgr.progressFromEnigma2 = e2params['progress']
                        self.subMgr.playerStateFromEnigma2 = e2params["state"]
                        self.subMgr.durationFromEnigma2 = e2params["duration"]
                        self.subMgr.lastkey = e2params["lastKey"]

                    self.answerPoll(commandID)
                    sleep(1)
                except:
                    print "no params"
                    self.answerPoll(commandID)
                    sleep(1)

            elif request_path == "player/playback/setParameters":
                volume = params["volume"]
                data = {"command": "setVolume", "volume": volume}

                self.playerCallback(data)
                self.resetCallback()

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

                self.playerCallback(data)
                self.resetCallback()

            elif request_path == "player/playback/play":
                self.response(getOKMsg(), getPlexHeaders())
                data = {"command": "play"}

                self.playerCallback(data)
                self.resetCallback()

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

                self.playerCallback(data)
                self.resetCallback()

            elif request_path == "player/playback/skipNext":
                self.response(getOKMsg(), getPlexHeaders())
                data = {"command": "skipNext"}
                self.playerCallback(data)
                self.resetCallback()

            elif request_path == "player/playback/skipPrevious":
                self.response(getOKMsg(), getPlexHeaders())
                data = {"command": "skipPrevious"}

                self.playerCallback(data)
                self.resetCallback()

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

                self.playerCallback(data)
                self.resetCallback()

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

                self.playerCallback(data)
                self.resetCallback()

            elif request_path == "player/playback/seekTo":
                self.response(getOKMsg(), getPlexHeaders())
                offset = params["offset"]
                data = {"command": "seekTo", "offset": offset}

                self.playerCallback(data)
                self.resetCallback()

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

                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.getMixedContentFromSection(
                            self.currentProtocol + "://" +
                            self.currentAddress + ":" + self.currentPort +
                            self.currentKey,
                            fromRemotePlayer=True)

                        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"
                        splittedData = self.currentKey.split("/")
                        subtitleData = self.plexInstance.getSelectedSubtitleDataById(
                            self.currentCompleteAddress, splittedData[-1])

                        data = {
                            "command": "playMedia",
                            "currentKey": self.currentKey,
                            "listViewList": listViewList,
                            "mediaContainer": mediaContainer,
                            "autoPlayMode": autoPlayMode,
                            "forceResume": forceResume,
                            "resumeMode": resumeMode,
                            "playbackMode": playbackMode,
                            "currentIndex": currentIndex,
                            "libraryName": libraryName,
                            "subtitleData": subtitleData
                        }

                        self.playerCallback(data)
                        self.resetCallback()

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

            else:
                self.response(getOKMsg(), getPlexHeaders())
        except:
            traceback.print_exc()
            self.wfile.close()

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

        printl("", self, "C")

    #===========================================================================
    #
    #===========================================================================
    def resetCallback(self):
        # we do this due to the fact that the messagepump is triggered mor often than we want to via playercallback for this reason we set to idle so that for example playMedia command is not called more than once
        data = {"command": "idle"}
        self.playerCallback(data)

    #===========================================================================
    #
    #===========================================================================
    def answerPoll(self, commandID):
        self.response(
            re.sub(r"INSERTCOMMANDID", str(commandID),
                   self.subMgr.msg(self.getPlayers())),
            {
                'Access-Control-Expose-Headers': 'X-Plex-Client-Identifier',
                'Content-Type': 'text/xml'
            })

    #===========================================================================
    #
    #===========================================================================
    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

    #===========================================================================
    #
    #===========================================================================
    def getPlayers(self):
        ret = {}

        try:
            ret = self.session.current_dialog.getPlayer()
        except:
            pass

        return ret
Exemple #8
0
    def answer_request(self):
        printl("", self, "S")

        try:
            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()

            data = {
                "command":
                "updateCommandId",
                "uuid":
                self.headers.get('X-Plex-Client-Identifier',
                                 self.client_address[0]),
                "commandID":
                params.get('commandID', False)
            }
            self.playerCallback(data)
            self.resetCallback()

            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)

                printl("host: " + str(host), self, "D")
                printl("protocol: " + str(protocol), self, "D")
                printl("port: " + str(port), self, "D")
                printl("uuid: " + str(uuid), self, "D")
                printl("commandID: " + str(commandID), self, "D")

                data = {
                    "command": "addSubscriber",
                    "protocol": protocol,
                    "host": host,
                    "port": port,
                    "uuid": uuid,
                    "commandID": commandID
                }
                #subMgr.addSubscriber(protocol, host, port, uuid, commandID)
                self.playerCallback(data)
                self.resetCallback()

            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]
                data = {"command": "removeSubscriber", "uuid": uuid}
                #subMgr.removeSubscriber(uuid)
                self.playerCallback(data)
                self.resetCallback()

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

            elif request_path == "player/timeline/poll":
                commandID = params.get('commandID', 0)
                self.subMgr = SubscriptionManager()
                try:
                    e2params = self.session.current_dialog.getPlayerState()
                    if e2params:
                        self.subMgr.progressFromEnigma2 = e2params['progress']
                        self.subMgr.playerStateFromEnigma2 = e2params["state"]
                        self.subMgr.durationFromEnigma2 = e2params["duration"]
                        self.subMgr.lastkey = e2params["lastKey"]

                    self.answerPoll(commandID)
                    sleep(1)
                except:
                    print "no params"
                    self.answerPoll(commandID)
                    sleep(1)

            elif request_path == "player/playback/setParameters":
                volume = params["volume"]
                data = {"command": "setVolume", "volume": volume}

                self.playerCallback(data)
                self.resetCallback()

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

                self.playerCallback(data)
                self.resetCallback()

            elif request_path == "player/playback/play":
                self.response(getOKMsg(), getPlexHeaders())
                data = {"command": "play"}

                self.playerCallback(data)
                self.resetCallback()

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

                self.playerCallback(data)
                self.resetCallback()

            elif request_path == "player/playback/skipNext":
                self.response(getOKMsg(), getPlexHeaders())
                data = {"command": "skipNext"}
                self.playerCallback(data)
                self.resetCallback()

            elif request_path == "player/playback/skipPrevious":
                self.response(getOKMsg(), getPlexHeaders())
                data = {"command": "skipPrevious"}

                self.playerCallback(data)
                self.resetCallback()

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

                self.playerCallback(data)
                self.resetCallback()

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

                self.playerCallback(data)
                self.resetCallback()

            elif request_path == "player/playback/seekTo":
                self.response(getOKMsg(), getPlexHeaders())
                offset = params["offset"]
                data = {"command": "seekTo", "offset": offset}

                self.playerCallback(data)
                self.resetCallback()

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

                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.getMixedContentFromSection(
                            self.currentProtocol + "://" +
                            self.currentAddress + ":" + self.currentPort +
                            self.currentKey,
                            fromRemotePlayer=True)

                        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"
                        splittedData = self.currentKey.split("/")
                        subtitleData = self.plexInstance.getSelectedSubtitleDataById(
                            self.currentCompleteAddress, splittedData[-1])

                        data = {
                            "command": "playMedia",
                            "currentKey": self.currentKey,
                            "listViewList": listViewList,
                            "mediaContainer": mediaContainer,
                            "autoPlayMode": autoPlayMode,
                            "forceResume": forceResume,
                            "resumeMode": resumeMode,
                            "playbackMode": playbackMode,
                            "currentIndex": currentIndex,
                            "libraryName": libraryName,
                            "subtitleData": subtitleData
                        }

                        self.playerCallback(data)
                        self.resetCallback()

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

            else:
                self.response(getOKMsg(), getPlexHeaders())
        except:
            traceback.print_exc()
            self.wfile.close()

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

        printl("", self, "C")