예제 #1
0
    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
예제 #2
0
 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.')
예제 #3
0
    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))
예제 #4
0
    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
예제 #5
0
 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)
예제 #6
0
 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'))
예제 #7
0
 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'))
예제 #8
0
 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"))
예제 #9
0
    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
예제 #10
0
    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
예제 #11
0
    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
예제 #12
0
 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)
예제 #13
0
 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)
예제 #14
0
    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
예제 #15
0
    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
예제 #16
0
 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)
예제 #17
0
    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)
예제 #18
0
    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)
예제 #19
0
    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)
예제 #20
0
        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)
예제 #22
0
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
예제 #23
0
    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
예제 #24
0
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
예제 #25
0
 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"
                 )
예제 #26
0
 def render_HEAD(self, request):
     self.info(f'render HEAD {request}')
     request.setResponseCode(200)
     request.setHeader(b'Content-Type', self.contentType)
     request.write(b'')
예제 #27
0
 def render_HEAD(self, request):
     self.info('render HEAD %r', request)
     request.setResponseCode(200)
     request.setHeader('Content-Type', self.contentType)
     request.write('')
예제 #28
0
    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)
예제 #29
0
    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)