def render_POST(self, request): response = {} logger.info('Received a new request from the client') try : # process the message encoding encoding = request.getHeader('Content-Type') data = request.content.read() if encoding == 'application/json' : try: input_json_str = json.loads(data.decode('utf-8')) input_json = json.loads(input_json_str) jrpc_id = input_json["id"] response = self._process_request(input_json_str) except AttributeError: logger.error("Error while loading input json") response = utility.create_error_response( WorkorderError.UNKNOWN_ERROR, jrpc_id, "UNKNOWN_ERROR: Error while loading the input JSON file") return response else : # JRPC response with 0 as id is returned because id can't be fecthed # from a request with unknown encoding response = utility.create_error_response( WorkorderError.UNKNOWN_ERROR, 0, "UNKNOWN_ERROR: unknown message encoding") return response except : logger.exception('exception while decoding http request %s', request.path) # JRPC response with 0 as id is returned because id can't be # fetched from improper request response = utility.create_error_response( WorkorderError.UNKNOWN_ERROR, 0, "UNKNOWN_ERROR: unable to decode incoming request") return response # send back the results try : if encoding == 'application/json' : response = json.dumps(response) logger.info('response[%s]: %s', encoding, response) request.setHeader('content-type', encoding) request.setResponseCode(http.OK) return response.encode('utf8') except : logger.exception('unknown exception while processing request %s', request.path) response = utility.create_error_response( WorkorderError.UNKNOWN_ERROR, jrpc_id, "UNKNOWN_ERROR: unknown exception processing http \ request {0}".format(request.path)) return response
def putCart(self, merch, num_field, add): print("Putting merchandize in cart...") self.statusBar().showMessage('Putting merchandize in cart...') if self.login_status: url = QtCore.QUrl(self.url_list['cart']) request = QNetworkRequest() request.setUrl(url) request.setHeader(QNetworkRequest.ContentTypeHeader, "application/x-www-form-urlencoded") data = QtCore.QByteArray() data.append(''.join(['token=', self.user_token, '&'])) data.append(''.join(['submethod=', 'change', '&'])) data.append(''.join(['merchid=', str(merch.id), '&'])) if add: data.append(''.join(['merchnum=', str(num_field.value())])) else: data.append(''.join(['merchnum=-', str(num_field.value())])) self.replyObjectPutCart = self.manager.post(request, data) self.replyObjectPutCart.finished.connect(self.putCartResult) else: msg = QtWidgets.QMessageBox.information( self, 'Information', 'You need to log in first\nto use shopping cart!', QtWidgets.QMessageBox.Ok) self.statusBar().showMessage('Not logged in yet.')
def paste(self, name, title, text, parent=None): """Paste the text into a pastebin and return the URL. Args: name: The username to post as. title: The post title. text: The text to post. parent: The parent paste to reply to. """ data = { 'text': text, 'title': title, 'name': name, } if parent is not None: data['reply'] = parent encoded_data = urllib.parse.urlencode(data).encode('utf-8') create_url = urllib.parse.urljoin(self.API_URL, 'create') request = QNetworkRequest(QUrl(create_url)) request.setHeader(QNetworkRequest.ContentTypeHeader, 'application/x-www-form-urlencoded;charset=utf-8') reply = self._nam.post(request, encoded_data) if reply.isFinished(): self.on_reply_finished(reply) else: reply.finished.connect(functools.partial( self.on_reply_finished, reply))
def render_POST(self, request): response = "" logger.info('Received a new request from the client') try: # Process the message encoding encoding = request.getHeader('Content-Type') data = request.content.read().decode('utf-8') if encoding == 'text/plain; charset=utf-8': response = self._process_request(data) else: response = 'UNKNOWN_ERROR: unknown message encoding' return response except: logger.exception('exception while decoding http request %s', request.path) response = 'UNKNOWN_ERROR: unable to decode incoming request ' return response # Send back the results try: logger.info('response[%s]: %s', encoding, response.encode('utf-8')) request.setHeader('content-type', encoding) request.setResponseCode(http.OK) return response.encode('utf-8') except: logger.exception('unknown exception while processing request %s', request.path) response = 'UNKNOWN_ERROR: unknown exception processing ' + \ 'http request {0}'.format(request.path) return response
def register(self, name, pass1, pass2): print("Registering...") if not name.text() or not pass1.text() or not pass2.text(): msg = QtWidgets.QMessageBox.warning( self, 'Unfilled fields', 'You didn\'t fill all required fields!', QtWidgets.QMessageBox.Ok) return if pass1.text() != pass2.text(): msg = QtWidgets.QMessageBox.warning( self, 'Passwords mismatch', 'Passwords entered in both fields are not same!', QtWidgets.QMessageBox.Ok) return self.statusBar().showMessage('Registering...') url = QtCore.QUrl(self.url_list['register']) request = QNetworkRequest() request.setUrl(url) request.setHeader(QNetworkRequest.ContentTypeHeader, "application/x-www-form-urlencoded") data = QtCore.QByteArray() data.append(''.join(['user='******'&'])) data.append(''.join(['password=', pass1.text()])) self.replyObjectReg = self.manager.post(request, data) self.replyObjectReg.finished.connect(self.registerFinalize)
def responseComplete(self): request = self.serverInterface().requestHandler() params = request.parameterMap() QgsMessageLog.logMessage("SimpleHelloFilter.responseComplete") if params.get('SERVICE', '').upper() == 'SIMPLE': request.clear() request.setHeader('Content-type', 'text/plain') request.appendBody('Hello from SimpleServer!'.encode('utf-8'))
def responseComplete(self): request = self.serverInterface().requestHandler() params = request.parameterMap() QgsMessageLog.logMessage("SimpleHelloFilter.responseComplete") if params.get('SERVICE', '').upper() == 'SIMPLE': request.clear() request.setHeader('Content-type', 'text/plain') request.appendBody('Hello from SimpleServer!'.encode('utf-8'))
def responseComplete(self): request = self.serverInterface().requestHandler() params = request.parameterMap() QgsMessageLog.logMessage("SimpleHelloFilter.responseComplete") if params.get("SERVICE", "").upper() == "SIMPLE": request.clearHeaders() request.setHeader("Content-type", "text/plain") request.clearBody() request.appendBody("Hello from SimpleServer!".encode("utf-8"))
def render(self, request): print("ExternalProcessPipeline render") try: if self.contentType: request.setHeader('Content-Type', self.contentType) except AttributeError: pass ExternalProcessProducer(self.pipeline_description % self.uri, request) return server.NOT_DONE_YET
def render(self, request): print('ExternalProcessPipeline render') if self.pipeline_description is None: raise NotImplementedError( 'Warning: operation cancelled. You must set a value for ' 'ExternalProcessPipeline.pipeline_description') if self.contentType is not None: request.setHeader(b'Content-Type', self.contentType) ExternalProcessProducer(self.pipeline_description % self.uri, request) return server.NOT_DONE_YET
def render_POST(self, request): response = {} response['error'] = {} response['error']['code'] = WorkorderError.UNKNOWN_ERROR logger.info('Received a new request from the client') try: # process the message encoding encoding = request.getHeader('Content-Type') data = request.content.read() if encoding == 'application/json': try: input_json = json.loads(data.decode('utf-8')) response = self._process_request(input_json) except AttributeError: logger.error("Error while loading input json") response['error'][ 'message'] = 'UNKNOWN_ERROR: Error while loading the input JSON file' return response else: response['error'][ 'message'] = 'UNKNOWN_ERROR: unknown message encoding' return response except: logger.exception('exception while decoding http request %s', request.path) response['error'][ 'message'] = 'UNKNOWN_ERROR: unable to decode incoming request ' return response # send back the results try: if encoding == 'application/json': response = json.dumps(response) logger.info('response[%s]: %s', encoding, response) request.setHeader('content-type', encoding) request.setResponseCode(http.OK) return response.encode('utf8') except: logger.exception('unknown exception while processing request %s', request.path) response['error'][ 'message'] = 'UNKNOWN_ERROR: unknown exception processing http request {0}'.format( request.path) return response
def purchase(self): print("Confirming purchase...") self.statusBar().showMessage('Confirming purchase...') url = QtCore.QUrl(self.url_list['checkout']) request = QNetworkRequest() request.setUrl(url) request.setHeader(QNetworkRequest.ContentTypeHeader, "application/x-www-form-urlencoded") data = QtCore.QByteArray() data.append(''.join(['token=', self.user_token])) self.replyObjectPur = self.manager.post(request, data) self.replyObjectPur.finished.connect(self.purchaseFinalize)
def cartPrepare(self): print("Fetching user cart...") self.statusBar().showMessage('Fetching user cart...') url = QtCore.QUrl(self.url_list['cart']) request = QNetworkRequest() request.setUrl(url) request.setHeader(QNetworkRequest.ContentTypeHeader, "application/x-www-form-urlencoded") data = QtCore.QByteArray() data.append(''.join(['token=', self.user_token, '&'])) data.append(''.join(['submethod=', 'get'])) self.replyObjectCart = self.manager.post(request, data) self.replyObjectCart.finished.connect(self.cartDialog)
def render_GET(self, request): self.info(f'render GET {request}') request.setResponseCode(200) if self.contentType is not None: request.setHeader(b'Content-Type', self.contentType) request.write(b'') headers = request.getAllHeaders() if ('connection' in headers and headers['connection'] == 'close'): pass self.start(request) return server.NOT_DONE_YET
def render_GET(self, request): self.info('render GET %r', request) request.setResponseCode(200) if hasattr(self, 'contentType'): request.setHeader('Content-Type', self.contentType) request.write('') headers = request.getAllHeaders() if ('connection' in headers and headers['connection'] == 'close'): pass self.start(request) return server.NOT_DONE_YET
def login(self, name_field, pass_field): print("Logging in...") self.statusBar().showMessage('Logging in...') self.Username = name_field.text() url = QtCore.QUrl(self.url_list['login']) request = QNetworkRequest() request.setUrl(url) request.setHeader(QNetworkRequest.ContentTypeHeader, "application/x-www-form-urlencoded") data = QtCore.QByteArray() data.append(''.join(['user='******'&'])) data.append(''.join(['password=', pass_field.text()])) self.replyObjectLogin = self.manager.post(request, data) self.replyObjectLogin.finished.connect(self.loginFinalize)
def post(self, url, data=None): """Create a new POST request. Args: url: The URL to post to, as QUrl. data: A dict of data to send. """ if data is None: data = {} encoded_data = urllib.parse.urlencode(data).encode('utf-8') request = HTTPRequest(url) request.setHeader(QNetworkRequest.ContentTypeHeader, 'application/x-www-form-urlencoded;charset=utf-8') reply = self._nam.post(request, encoded_data) self._handle_reply(reply)
def post(self, url, data=None): """Create a new POST request. Args: url: The URL to post to, as QUrl. data: A dict of data to send. """ if data is None: data = {} encoded_data = urllib.parse.urlencode(data).encode('utf-8') request = QNetworkRequest(url) request.setHeader(QNetworkRequest.ContentTypeHeader, 'application/x-www-form-urlencoded;charset=utf-8') reply = self._nam.post(request, encoded_data) self._handle_reply(reply)
def got_streams(streams): if self.stream_id not in streams: self.warning("stream not found for %s@%s", self.url, self.stream_id) request.setResponseCode(http.NOT_FOUND) request.write('') return request.setHeader('Content-Type', self.content_type) request.setResponseCode(http.OK) if request.method == 'HEAD': request.write('') return d_open_stream = threads.deferToThread(streams[self.stream_id].open) d_open_stream.addCallback(stream_opened)
def got_streams(streams): if self.stream_id not in streams: self.warning(f'stream not found for ' f'{self.url}@{self.stream_id}') request.setResponseCode(http.NOT_FOUND) request.write(b'') return request.setHeader(b'Content-Type', self.content_type.encode('ascii')) request.setResponseCode(http.OK) if request.method == b'HEAD': request.write(b'') return d_open_stream = threads.deferToThread(streams[self.stream_id].open) d_open_stream.addCallback(stream_opened)
def process_post_call(self, url, url_query_items, data, is_read_only=True, report_url=True): """ Run a POST request and return reply data :param url: url for request :param url_query_items: :param data: :param is_read_only: True if the request does not update data :param report_url: True if URL should be reported to feedback :return: response or error message in json format """ if self.connection.read_only and not is_read_only: return { "error": { "msg": "Graphium connection is set to read-only!" } } url_query = QUrl(url) if report_url: self.report_info('POST ' + url_query.toString()) if url_query_items: url_query.setQuery(url_query_items) # data_byte_array = json.dumps(data).encode('utf8') # data = QtCore.QByteArray( json.dumps( json_request ) ) data_byte_array = QJsonDocument.fromVariant(data) request = QNetworkRequest(url_query) if self.connection.auth_cfg != '': request.setRawHeader("Accept".encode("utf-8"), "*/*".encode("utf-8")) request.setHeader(QNetworkRequest.ContentTypeHeader, "application/json") reply = self.network_access_manager.blockingPost( request, data_byte_array.toJson(), self.connection.auth_cfg, True, self.feedback) return self.process_qgs_reply(reply)
def tox_dns(email): """ TOX DNS 4 :param email: data like '*****@*****.**' :return: tox id on success else None """ site = email.split('@')[1] data = {"action": 3, "name": "{}".format(email)} urls = ('https://{}/api'.format(site), 'http://{}/api'.format(site)) s = settings.Settings.get_instance() if not s['proxy_type']: # no proxy for url in urls: try: return send_request(url, data) except Exception as ex: log('TOX DNS ERROR: ' + str(ex)) else: # proxy netman = QtNetwork.QNetworkAccessManager() proxy = QtNetwork.QNetworkProxy() proxy.setType(QtNetwork.QNetworkProxy.Socks5Proxy if s['proxy_type'] == 2 else QtNetwork.QNetworkProxy.HttpProxy) proxy.setHostName(s['proxy_host']) proxy.setPort(s['proxy_port']) netman.setProxy(proxy) for url in urls: try: request = QtNetwork.QNetworkRequest() request.setUrl(QtCore.QUrl(url)) request.setHeader(QtNetwork.QNetworkRequest.ContentTypeHeader, "application/json") reply = netman.post(request, bytes(json.dumps(data), 'utf-8')) while not reply.isFinished(): QtCore.QThread.msleep(1) QtCore.QCoreApplication.processEvents() data = bytes(reply.readAll().data()) result = json.loads(str(data, 'utf-8')) if not result['c']: return result['tox_id'] except Exception as ex: log('TOX DNS ERROR: ' + str(ex)) return None # error
def render_GET(self, request): self.info(f'render GET {request}') request.setResponseCode(200) if hasattr(self, 'contentType'): request.setHeader(b'Content-Type', self.contentType) request.write(b'') headers = request.getAllHeaders() if ('connection' in headers and headers['connection'] == 'close'): pass if self.requests: if self.streamheader: self.debug('writing streamheader') for h in self.streamheader: request.write(h.data) self.requests.append(request) else: self.parse_pipeline() self.start(request) return server.NOT_DONE_YET
def tox_dns(email): """ TOX DNS 4 :param email: data like '*****@*****.**' :return: tox id on success else None """ site = email.split('@')[1] data = {"action": 3, "name": "{}".format(email)} urls = ('https://{}/api'.format(site), 'http://{}/api'.format(site)) s = settings.Settings.get_instance() if not s['proxy_type']: # no proxy for url in urls: try: return send_request(url, data) except Exception as ex: log('TOX DNS ERROR: ' + str(ex)) else: # proxy netman = QtNetwork.QNetworkAccessManager() proxy = QtNetwork.QNetworkProxy() proxy.setType(QtNetwork.QNetworkProxy.Socks5Proxy if s['proxy_type'] == 2 else QtNetwork.QNetworkProxy.HttpProxy) proxy.setHostName(s['proxy_host']) proxy.setPort(s['proxy_port']) netman.setProxy(proxy) for url in urls: try: request = QtNetwork.QNetworkRequest(url) request.setHeader(QtNetwork.QNetworkRequest.ContentTypeHeader, "application/json") reply = netman.post(request, bytes(json.dumps(data), 'utf-8')) while not reply.isFinished(): QtCore.QThread.msleep(1) QtCore.QCoreApplication.processEvents() data = bytes(reply.readAll().data()) result = json.loads(str(data, 'utf-8')) if not result['c']: return result['tox_id'] except Exception as ex: log('TOX DNS ERROR: ' + str(ex)) return None # error
def prepare_headers(self, ch, request): request.setHeader('transferMode.dlna.org', request._dlna_transfermode) if hasattr(ch, 'item') and hasattr(ch.item, 'res'): if ch.item.res[0].protocolInfo is not None: additional_info = ch.item.res[0].get_additional_info() if additional_info != '*': request.setHeader('contentFeatures.dlna.org', additional_info) elif 'getcontentfeatures.dlna.org' in request.getAllHeaders(): request.setHeader( 'contentFeatures.dlna.org', "DLNA.ORG_OP=01;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=01500000000000000000000000000000" )
def render_HEAD(self, request): self.info(f'render HEAD {request}') request.setResponseCode(200) request.setHeader(b'Content-Type', self.contentType) request.write(b'')
def render_HEAD(self, request): self.info('render HEAD %r', request) request.setResponseCode(200) request.setHeader('Content-Type', self.contentType) request.write('')
def getChildWithDefault(self, path, request): self.info('%s getChildWithDefault, %s, %s, %s %s', self.server.device_type, request.method, path, request.uri, request.client) headers = request.getAllHeaders() self.msg(request.getAllHeaders()) try: if headers['getcontentfeatures.dlna.org'] != '1': request.setResponseCode(400) return static.Data( '<html><p>wrong value for getcontentFeatures.dlna.org</p></html>', 'text/html') except: pass if request.method == 'HEAD': if 'getcaptioninfo.sec' in headers: self.warning("requesting srt file for id %s", path) ch = self.store.get_by_id(path) try: location = ch.get_path() caption = ch.caption if caption is None: raise KeyError request.setResponseCode(200) request.setHeader('CaptionInfo.sec', caption) return static.Data('', 'text/html') except: print(traceback.format_exc()) request.setResponseCode(404) return static.Data( '<html><p>the requested srt file was not found</p></html>', 'text/html') try: request._dlna_transfermode = headers['transfermode.dlna.org'] except KeyError: request._dlna_transfermode = 'Streaming' if request.method in ('GET', 'HEAD'): if COVER_REQUEST_INDICATOR.match(request.uri): self.info("request cover for id %s", path) def got_item(ch): if ch is not None: request.setResponseCode(200) file = ch.get_cover() if file and os.path.exists(file): self.info("got cover %s", file) return StaticFile(file) request.setResponseCode(404) return static.Data( '<html><p>cover requested not found</p></html>', 'text/html') dfr = defer.maybeDeferred(self.store.get_by_id, path) dfr.addCallback(got_item) dfr.isLeaf = True return dfr if ATTACHMENT_REQUEST_INDICATOR.match(request.uri): self.info("request attachment %r for id %s", request.args, path) def got_attachment(ch): try: #FIXME same as below if 'transcoded' in request.args: if self.server.coherence.config.get( 'transcoding', 'no') == 'yes': format = request.args['transcoded'][0] type = request.args['type'][0] self.info("request transcoding %r %r", format, type) try: from coherence.transcoder import TranscoderManager manager = TranscoderManager( self.server.coherence) return manager.select( format, ch.item.attachments[ request.args['attachment'][0]]) except: self.debug(traceback.format_exc()) request.setResponseCode(404) return static.Data( '<html><p>the requested transcoded file was not found</p></html>', 'text/html') else: request.setResponseCode(404) return static.Data( "<html><p>This MediaServer doesn't support transcoding</p></html>", 'text/html') else: return ch.item.attachments[ request.args['attachment'][0]] except: request.setResponseCode(404) return static.Data( '<html><p>the requested attachment was not found</p></html>', 'text/html') dfr = defer.maybeDeferred(self.store.get_by_id, path) dfr.addCallback(got_attachment) dfr.isLeaf = True return dfr if request.method in ('GET', 'HEAD') and TRANSCODED_REQUEST_INDICATOR.match( request.uri): self.info("request transcoding to %s for id %s", request.uri.split('/')[-1], path) if self.server.coherence.config.get('transcoding', 'no') == 'yes': def got_stuff_to_transcode(ch): #FIXME create a generic transcoder class and sort the details there format = request.uri.split('/')[ -1] # request.args['transcoded'][0] uri = ch.get_path() try: from coherence.transcoder import TranscoderManager manager = TranscoderManager(self.server.coherence) return manager.select(format, uri) except: self.debug(traceback.format_exc()) request.setResponseCode(404) return static.Data( '<html><p>the requested transcoded file was not found</p></html>', 'text/html') dfr = defer.maybeDeferred(self.store.get_by_id, path) dfr.addCallback(got_stuff_to_transcode) dfr.isLeaf = True return dfr request.setResponseCode(404) return static.Data( "<html><p>This MediaServer doesn't support transcoding</p></html>", 'text/html') if request.method == 'POST' and request.uri.endswith('?import'): d = self.import_file(path, request) if isinstance(d, defer.Deferred): d.addBoth(self.import_response, path) d.isLeaf = True return d return self.import_response(None, path) if ('user-agent' in headers and (headers['user-agent'].find('Xbox/') == 0 or # XBox headers['user-agent'].startswith( """Mozilla/4.0 (compatible; UPnP/1.0; Windows""")) and # wmp11 path in ['description-1.xml', 'description-2.xml']): self.info( 'XBox/WMP alert, we need to simulate a Windows Media Connect server' ) if 'xbox-description-1.xml' in self.children: self.msg('returning xbox-description-1.xml') return self.children['xbox-description-1.xml'] # resource http://XXXX/<deviceID>/config # configuration for the given device # accepted methods: # GET, HEAD: returns the configuration data (in XML format) # POST: stop the current device and restart it with the posted configuration data if path in ('config'): backend = self.server.backend backend_type = backend.__class__.__name__ def constructConfigData(backend): msg = "<plugin active=\"yes\">" msg += "<backend>" + backend_type + "</backend>" for key, value in list(backend.config.items()): msg += "<" + key + ">" + value + "</" + key + ">" msg += "</plugin>" return msg if request.method in ('GET', 'HEAD'): # the client wants to retrieve the configuration parameters for the backend msg = constructConfigData(backend) request.setResponseCode(200) return static.Data(msg, 'text/xml') elif request.method in ('POST'): # the client wants to update the configuration parameters for the backend # we relaunch the backend with the new configuration (after content validation) def convert_elementtree_to_dict(root): active = False for name, value in list(root.items()): if name == 'active': if value in ('yes'): active = True break if active is False: return None dict = {} for element in root.getchildren(): key = element.tag text = element.text if key != 'backend': dict[key] = text return dict new_config = None try: element_tree = etree.fromstring(request.content.getvalue()) new_config = convert_elementtree_to_dict(element_tree) self.server.coherence.remove_plugin(self.server) self.warning("%s %s (%s) with id %s desactivated", backend.name, self.server.device_type, backend, str(self.server.uuid)[5:]) if new_config is None: msg = "<plugin active=\"no\"/>" else: new_backend = self.server.coherence.add_plugin( backend_type, **new_config) if self.server.coherence.writeable_config(): self.server.coherence.store_plugin_config( new_backend.uuid, new_config) msg = "<html><p>Device restarted. Config file has been modified with posted data.</p></html>" # constructConfigData(new_backend) else: msg = "<html><p>Device restarted. Config file not modified</p></html>" # constructConfigData(new_backend) request.setResponseCode(202) return static.Data(msg, 'text/html') # 'text/xml') except SyntaxError as e: request.setResponseCode(400) return static.Data( "<html><p>Invalid data posted:<BR>%s</p></html>" % e, 'text/html') else: # invalid method requested request.setResponseCode(405) return static.Data( "<html><p>This resource does not allow the requested HTTP method</p></html>", 'text/html') if path in self.children: return self.children[path] if request.uri == '/': return self return self.getChild(path, request)
def getChildWithDefault(self, path, request): self.info( f'{self.server.device_type} getChildWithDefault, ' f'{request.method}, {path}, {request.uri} {request.client}' ) headers = request.getAllHeaders() self.debug(f'\t-> headers are: {headers}') if not isinstance(path, bytes): path = path.encode('ascii') if path.endswith(b'\''): self.warning(f'\t modified wrong path from {path} to {path[:-1]}') path = path[:-1] self.debug(f'\t-> path is: {path} [{type(path)}]') try: if ( b'getcontentfeatures.dlna.org' in headers and headers[b'getcontentfeatures.dlna.org'] != b'1' ): request.setResponseCode(400) return static.Data( b'<html><p>wrong value for ' b'getcontentFeatures.dlna.org</p></html>', 'text/html', ) except Exception as e1: self.error(f'MSRoot.getChildWithDefault: {e1}') if request.method == b'HEAD': if b'getcaptioninfo.sec' in headers: self.warning(f'requesting srt file for id {path}') ch = self.store.get_by_id(path) try: location = ch.get_path() caption = ch.caption if caption is None: raise KeyError request.setResponseCode(200) request.setHeader(b'CaptionInfo.sec', caption) return static.Data(b'', 'text/html') except Exception as e2: self.error( f'MSRoot.getChildWithDefault (method: HEAD): {e2}' ) print(traceback.format_exc()) request.setResponseCode(404) return static.Data( b'<html><p>the requested srt file ' b'was not found</p></html>', 'text/html', ) try: request._dlna_transfermode = headers[b'transfermode.dlna.org'] except KeyError: request._dlna_transfermode = b'Streaming' if request.method in (b'GET', b'HEAD'): if COVER_REQUEST_INDICATOR.match(request.uri.decode('utf-8')): self.info(f'request cover for id {path}') def got_item(ch): if ch is not None: request.setResponseCode(200) file = ch.get_cover() if file and os.path.exists(file): self.info(f'got cover {file}') return StaticFile(file) request.setResponseCode(404) return static.Data( b'<html><p>cover requested not found</p></html>', 'text/html', ) dfr = defer.maybeDeferred(self.store.get_by_id, path) dfr.addCallback(got_item) dfr.isLeaf = True return dfr if ATTACHMENT_REQUEST_INDICATOR.match(request.uri.decode('utf-8')): self.info(f'request attachment {request.args} for id {path}') def got_attachment(ch): try: # FIXME same as below if 'transcoded' in request.args: if ( self.server.coherence.config.get( 'transcoding', 'no' ) == 'yes' ): format = request.args['transcoded'][0] type = request.args['type'][0] self.info( f'request transcoding {format} {type}' ) try: from coherence.transcoder import ( TranscoderManager, ) manager = TranscoderManager( self.server.coherence ) return manager.select( format, ch.item.attachments[ request.args['attachment'][0] ], ) except Exception: self.debug(traceback.format_exc()) request.setResponseCode(404) return static.Data( b'<html><p>the requested transcoded file ' b'was not found</p></html>', 'text/html', ) else: request.setResponseCode(404) return static.Data( b'<html><p>This MediaServer ' b'doesn\'t support transcoding</p></html>', 'text/html', ) else: return ch.item.attachments[ request.args['attachment'][0] ] except Exception: request.setResponseCode(404) return static.Data( b'<html><p>the requested attachment ' b'was not found</p></html>', 'text/html', ) dfr = defer.maybeDeferred(self.store.get_by_id, path) dfr.addCallback(got_attachment) dfr.isLeaf = True return dfr if request.method in ( b'GET', b'HEAD', ) and TRANSCODED_REQUEST_INDICATOR.match(request.uri.decode('utf-8')): self.info( f'request transcoding to ' f'{request.uri.split(b"/")[-1]} for id {path}' ) if self.server.coherence.config.get('transcoding', 'no') == 'yes': def got_stuff_to_transcode(ch): # FIXME create a generic transcoder class # and sort the details there format = request.uri.split(b'/')[ -1 ] # request.args['transcoded'][0] uri = ch.get_path() try: from coherence.transcoder import TranscoderManager manager = TranscoderManager(self.server.coherence) return manager.select(format, uri) except Exception: self.debug(traceback.format_exc()) request.setResponseCode(404) return static.Data( b'<html><p>the requested transcoded file ' b'was not found</p></html>', 'text/html', ) dfr = defer.maybeDeferred(self.store.get_by_id, path) dfr.addCallback(got_stuff_to_transcode) dfr.isLeaf = True return dfr request.setResponseCode(404) return static.Data( b'<html><p>This MediaServer ' b'doesn\'t support transcoding</p></html>', 'text/html', ) if request.method == b'POST' and request.uri.endswith(b'?import'): d = self.import_file(path, request) if isinstance(d, defer.Deferred): d.addBoth(self.import_response, path) d.isLeaf = True return d return self.import_response(None, path) if ( b'user-agent' in headers and ( headers[b'user-agent'].find(b'Xbox/') in [0, None] or headers[b'user-agent'].startswith( # XBox # wmp11 b'''Mozilla/4.0 (compatible; UPnP/1.0; Windows''' ) ) and path in [b'description-1.xml', b'description-2.xml'] ): self.info( 'XBox/WMP alert, we need to ' 'simulate a Windows Media Connect server' ) if b'xbox-description-1.xml' in self.children: self.msg('returning xbox-description-1.xml') return self.children[b'xbox-description-1.xml'] # resource http://XXXX/<deviceID>/config # configuration for the given device # accepted methods: # GET, HEAD: # returns the configuration data (in XML format) # POST: stop the current device and restart it # with the posted configuration data if path in (b'config'): backend = self.server.backend backend_type = backend.__class__.__name__ def constructConfigData(backend): msg = '<plugin active="yes">' msg += '<backend>' + to_string(backend_type) + '</backend>' for key, value in list(backend.config.items()): msg += ( '<' + to_string(key) + '>' + to_string(value) + '</' + to_string(key) + '>' ) msg += '</plugin>' return to_bytes(msg) if request.method in (b'GET', b'HEAD'): # the client wants to retrieve the # configuration parameters for the backend msg = constructConfigData(backend) request.setResponseCode(200) return static.Data(msg, 'text/xml') elif request.method in (b'POST'): # the client wants to update the configuration parameters # for the backend we relaunch the backend with the # new configuration (after content validation) def convert_elementtree_to_dict(root): active = False for name, value in list(root.items()): if name == 'active': if value in ('yes'): active = True break if active is False: return None dict = {} for element in root.getchildren(): key = element.tag text = element.text if key != 'backend': dict[key] = text return dict new_config = None try: element_tree = etree.fromstring(request.content.getvalue()) new_config = convert_elementtree_to_dict(element_tree) self.server.coherence.remove_plugin(self.server) self.warning( f'{backend.name} {self.server.device_type} ({backend})' f' with id {str(self.server.uuid)[5:]} deactivated' ) if new_config is None: msg = '<plugin active="no"/>' else: new_backend = self.server.coherence.add_plugin( backend_type, **new_config ) if self.server.coherence.writeable_config(): self.server.coherence.store_plugin_config( new_backend.uuid, new_config ) msg = ( '<html><p>Device restarted. Config file ' + 'has been modified with posted data.</p>' + '</html>' ) # constructConfigData(new_backend) else: msg = ( '<html><p>Device restarted. ' + 'Config file not modified</p>' + '</html>' ) # constructConfigData(new_backend) request.setResponseCode(202) return static.Data(msg.encode('ascii'), 'text/html') except SyntaxError as e: request.setResponseCode(400) return static.Data( f'<html>' f'<p>Invalid data posted:<BR>{e}</p>' f'</html>'.encode('ascii'), 'text/html', ) else: # invalid method requested request.setResponseCode(405) return static.Data( b'<html><p>This resource does not allow ' + b'the requested HTTP method</p></html>', 'text/html', ) if path in self.children: return self.children[path] if request.uri == b'/': return self return self.getChild(path, request)