Пример #1
0
def test_subscription_remove_period(client, session):
    password = "******"
    user = UserFactory(active=True, password=password)
    author = AuthorFactory()
    sub = SubscriptionFactory(user=user, author=author, active=True)
    sub.add_period(PERIOD.DAILY)

    assert sub.has_period(PERIOD.DAILY)
    assert len(sub.periods) == 1

    h = Headers()
    auth = requests.auth._basic_auth_str(user.email, password)
    h.add("Authorization", auth)
    url = "{0}{1}{2}{3}".format(
        url_for("subscriptions.remove_period"),
        "?period=Daily",
        "&subscription_id=",
        str(sub.id),
    )

    response = client.post(url, headers=h)

    assert response.status_code == 302

    assert len(sub.periods) == 0
    assert sub.has_period(PERIOD.DAILY) is False
Пример #2
0
 def test07_access_token_handler(self):
     with dummy_app.test_request_context('/a_request'):
         auth = IIIFAuthGoogle(client_secret_file=csf)
         response = auth.access_token_handler()
         self.assertEqual( response.status_code, 200 )
         self.assertEqual( response.headers['Content-type'], 'application/json' )
         j = json.loads(response.get_data())
         self.assertEqual( j['error_description'], "No login details received" )
         self.assertEqual( j['error'], "client_unauthorized" )
     # add callback but no account cookie
     with dummy_app.test_request_context('/a_request?callback=CB'):
         auth = IIIFAuthGoogle(client_secret_file=csf)
         response = auth.access_token_handler()
         self.assertEqual( response.status_code, 200 )
         self.assertEqual( response.headers['Content-type'], 'application/javascript' )
         # strip JavaScript wrapper and then check JSON
         js = response.get_data()
         self.assertTrue( re.match('CB\(.*\);',js) )
         j = json.loads(js.lstrip('CB(').rstrip(');'))
         self.assertEqual( j['error_description'], "No login details received" )
         self.assertEqual( j['error'], "client_unauthorized" )
     # add an account cookie
     h = Headers()
     h.add('Cookie', 'lol_account=ACCOUNT_TOKEN')
     with dummy_app.test_request_context('/a_request', headers=h):
         auth = IIIFAuthGoogle(client_secret_file=csf, cookie_prefix='lol_')
         response = auth.access_token_handler()
         self.assertEqual( response.status_code, 200 )
         self.assertEqual( response.headers['Content-type'], 'application/json' )
         j = json.loads(response.get_data())
         self.assertEqual( j['access_token'], "ACCOUNT_TOKEN" )
         self.assertEqual( j['token_type'], "Bearer" )
Пример #3
0
def song(id, ext):
	song = db.session.query(Song.id, Song.filename, Song.length, Song.mimetype, Song.artist, Song.album, Song.title, Song.track).filter(Song.id == id).first()
	if song == None or not os.path.exists(song.filename):
		return abort(404)
	headers = Headers()
	headers.add("X-Content-Duration", song.length)
	headers.add("X-Accel-Buffering", "no")
	range_header = request.headers.get('Range', None)
	if range_header is not None:
		range_header = range_header.split("-")
		try:
			range_header = intval(range_header[0])
		except:
			range_header = None
	if range_header is None or range_header == 0:
		db.session.add(Download(song, request))
		db.session.commit()
	
	ext = ext.lower()

	for extension, mimeset in mimetypes.items():
		if song.mimetype in mimeset and extension == ext:
			return send_file_partial(song.filename, mimetype=song.mimetype, attachment_filename=generate_download_filename(song, ext), headers=headers)

	if ext not in [ "ogg", "mp3", "flac", "wav", "webm" ]:
		return abort(404)
	transcode_options = [ 'avconv', '-loglevel', 'quiet', '-i', song.filename, '-f', ext, '-y', '-fflags', 'nobuffer' ];
	if ext == "ogg" or ext == "webm":
		transcode_options.extend([ '-acodec', 'libvorbis', '-aq', '5' ])
	elif ext == "mp3":
		transcode_options.extend([ '-ab', '160k' ])
	transcode_options.append('-')
	return send_process(transcode_options, mimetype=mimetypes[ext][0], attachment_filename=generate_download_filename(song, ext), headers=headers)
Пример #4
0
    def iter_request_header_errors(self, request_headers):
        """
        Validates individual request headers against the schema, yielding
        a :class:`~spectastic.errors.FieldError` for each failure.
        """
        header_schemas = self.header_schemas()
        if len(header_schemas) == 0:
            return

        request_headers = Headers(request_headers)

        for header, value in request_headers.iteritems():
            if header in header_schemas:
                schema = self.header_schema(header)
                for error in self.validator.iter_errors(value, schema):
                    yield FieldError(error.message, 'header', header)

        for name, schema in header_schemas.iteritems():
            if schema.get('required') and name.lower() \
                    not in request_headers:
                yield FieldError(
                    'Required header is missing',
                    'header',
                    schema.get('name')
                )
Пример #5
0
def credentials(scope="module"):
    """
    Note that these credentials match those mentioned in test.htpasswd
    """
    h = Headers()
    h.add("Authorization", "Basic " + base64.b64encode("username:password"))
    return h
Пример #6
0
 def __init__(self, response = None, status = None, headers = None, mimetype = None, content_type = None, direct_passthrough = False):
     if isinstance(headers, Headers):
         self.headers = headers
     elif not headers:
         self.headers = Headers()
     else:
         self.headers = Headers(headers)
     if content_type is None:
         if mimetype is None and 'content-type' not in self.headers:
             mimetype = self.default_mimetype
         if mimetype is not None:
             mimetype = get_content_type(mimetype, self.charset)
         content_type = mimetype
     if content_type is not None:
         self.headers['Content-Type'] = content_type
     if status is None:
         status = self.default_status
     if isinstance(status, (int, long)):
         self.status_code = status
     else:
         self.status = status
     self.direct_passthrough = direct_passthrough
     self._on_close = []
     if response is None:
         self.response = []
     elif isinstance(response, basestring):
         self.data = response
     else:
         self.response = response
Пример #7
0
    def handle_error(self, e):
        '''
        Error handler for the API transforms a raised exception into a Flask response,
        with the appropriate HTTP status code and body.

        :param Exception e: the raised Exception object

        '''
        got_request_exception.send(current_app._get_current_object(), exception=e)

        headers = Headers()
        if e.__class__ in self.error_handlers:
            handler = self.error_handlers[e.__class__]
            result = handler(e)
            default_data, code, headers = unpack(result, 500)
        elif isinstance(e, HTTPException):
            code = e.code
            default_data = {
                'message': getattr(e, 'description', HTTP_STATUS_CODES.get(code, ''))
            }
            headers = e.get_response().headers
        elif self._default_error_handler:
            result = self._default_error_handler(e)
            default_data, code, headers = unpack(result, 500)
        else:
            code = 500
            default_data = {
                'message': HTTP_STATUS_CODES.get(code, str(e)),
            }

        default_data['message'] = default_data.get('message', str(e))
        data = getattr(e, 'data', default_data)
        fallback_mediatype = None

        if code >= 500:
            exc_info = sys.exc_info()
            if exc_info[1] is None:
                exc_info = None
            current_app.log_exception(exc_info)

        elif code == 404 and current_app.config.get("ERROR_404_HELP", True):
            data['message'] = self._help_on_404(data.get('message', None))

        elif code == 406 and self.default_mediatype is None:
            # if we are handling NotAcceptable (406), make sure that
            # make_response uses a representation we support as the
            # default mediatype (so that make_response doesn't throw
            # another NotAcceptable error).
            supported_mediatypes = list(self.representations.keys())
            fallback_mediatype = supported_mediatypes[0] if supported_mediatypes else "text/plain"

        # Remove blacklisted headers
        for header in HEADERS_BLACKLIST:
            headers.pop(header, None)

        resp = self.make_response(data, code, headers, fallback_mediatype=fallback_mediatype)

        if code == 401:
            resp = self.unauthorized(resp)
        return resp
Пример #8
0
def test_200_with_credentials(client, test_user):
    headers = Headers()
    headers.set('Authorization', 'Basic ' + base64.b64encode('[email protected]:secret123'))

    response = client.get('/user', headers=headers)
    assert response.status_code == 200
    assert response.json.get('user') == test_user.id
Пример #9
0
    def handler_b2s_image(self, id=None):
        """ Handler for `/b2s_image` url for json data.

        It accepts only Communication Kit Notifications.

        """
        if id is None:
            raise BadRequest()
        headers = request.httprequest.headers
        self._validate_headers(headers)
        correspondence_obj = request.env['correspondence'].sudo()
        correspondence = correspondence_obj.search([('uuid', '=', id)])
        if not correspondence:
            raise NotFound()
        data = correspondence.get_image()
        headers = Headers()
        if correspondence.letter_format == 'zip':
            fname = fields.Date.today() + ' letters.zip'
            headers.add(
                'Content-Disposition', 'attachment',
                filename=fname)
            response = Response(data, content_type='application/zip',
                                headers=headers)
        else:
            headers.add(
                'Content-Disposition', 'attachment',
                filename=correspondence.file_name)
            response = Response(data, content_type='application/pdf',
                                headers=headers)
        return response
Пример #10
0
def test_200_with_authorization_header(client, access_token, test_user):
    headers = Headers()
    headers.set('Authorization', 'Bearer ' + access_token)

    response = client.get('/user', headers=headers)
    assert response.status_code == 200
    assert response.json.get('user') == test_user.id
Пример #11
0
def test_401_with_invalid_credentials(client):
    headers = Headers()
    headers.set('Authorization', 'Basic ' + base64.b64encode('invalid-username:invalid-password'))

    response = client.get('/user', headers=headers)
    assert response.status_code == 401
    assert response.json.get('error') == 'invalid_token'
Пример #12
0
def test_401_with_unsupported_authorization_header(client):
    headers = Headers()
    headers.set('Authorization', 'MAC 123456789')

    response = client.get('/user', headers=headers)
    assert response.status_code == 401
    assert response.json.get('error') == 'invalid_token'
Пример #13
0
def test_401_with_invalid_token(client):
    headers = Headers()
    headers.set('Authorization', 'Bearer invalid-token')

    response = client.get('/user', headers=headers)
    assert response.status_code == 401
    assert response.json.get('error') == 'invalid_token'
Пример #14
0
def test_user_rss_url_etag(session, client):
    entries = EntryFactory.create_batch(5)
    author1 = AuthorFactory()
    author1.entries.extend(entries)
    user = UserFactory(active=True)
    user.userfeed.private = False
    sub1 = Subscription(user=user, author=author1)
    sub1.save()

    h = Headers()
    h.add("If-None-Match", None)
    response1 = client.get(url_for("users.user_feed", user_id=user.id), headers=h)

    assert response1.status_code == 200
    etag = response1.headers.get("ETag")
    assert response1.data
    assert (
        response1.headers.get("Content-Type") == "application/atom+xml; charset=utf-8"
    )

    h.add("If-None-Match", etag)
    response2 = client.get(url_for("users.user_feed", user_id=user.id), headers=h)

    assert response2.status_code == 304
    etag2 = response2.headers.get("ETag")
    assert etag2 == etag
    assert not response2.data
Пример #15
0
def test_subscription_remove_period(subhandler, client, session):
    # users = User.query.all()
    # pprint(users)

    password = '******'
    user = UserFactory(active=True, password=password)
    author = AuthorFactory()
    sub = SubscriptionFactory(user=user, author=author, active=True)
    sub.add_period(PERIOD.DAILY)

    # with client as c:
    assert sub.has_period(PERIOD.DAILY)
    assert len(sub.periods) == 1

    h = Headers()
    auth = requests.auth._basic_auth_str(user.email, password)
    h.add('Authorization', auth)
    url = url_for('subscriptions.remove_period') + '?period=Daily' + '&subscription_id=' + str(sub.id)

    response = client.post(url, headers=h)

    assert response.status_code == 302

    assert len(sub.periods) == 0
    assert sub.has_period(PERIOD.DAILY) is False
Пример #16
0
def test_200_with_authorization_header(client, access_token):
    headers = Headers()
    headers.set('Authorization', 'Bearer ' + access_token)

    response = client.get('/secrets', headers=headers)
    assert response.status_code == 200
    assert isinstance(response.json.get('secrets'), list)
Пример #17
0
def test_200_with_credentials(client):
    headers = Headers()
    headers.set('Authorization', basic_auth_encode('*****@*****.**', 'secret123'))

    response = client.get('/secrets', headers=headers)
    assert response.status_code == 200
    assert isinstance(response.json.get('secrets'), list)
Пример #18
0
    def test_crossdomain(self):

        class Foo(flask_restful.Resource):
            @cors.crossdomain(allow_origin='*')
            def get(self):
                return "data"

        app = Flask(__name__)
        api = flask_restful.Api(app)
        api.add_resource(Foo, '/')

        with app.test_client() as client:
            h = Headers()
            origin = "http://foo.bar"
            h.add('Origin', origin)
            res = client.get('/', headers=h)
            headers = res.headers
            assert_equals(res.status_code, 200)
            assert_true(headers['Access-Control-Allow-Origin'] in ('*',
                                                                   origin))
            assert_equals(headers['Access-Control-Max-Age'], '21600')
            allow_methods = headers['Access-Control-Allow-Methods']
            assert_true('HEAD' in allow_methods)
            assert_true('OPTIONS' in allow_methods)
            assert_true('GET' in allow_methods)
Пример #19
0
    def jsonpost(self, *args, **kwargs):
        """Convenience method for making JSON POST requests."""
        kwargs.setdefault('content_type', 'application/json')
        if 'data' in kwargs:
            kwargs['data'] = json.dumps(kwargs['data'])

        headers = Headers()
        override_headers = kwargs.pop('headers', {})
        if override_headers:
            for k, v in override_headers.items():
                headers.add(k, v)

        if 'useragent' in kwargs:
            useragent = kwargs.pop('useragent')
            headers.add('User-Agent', useragent)

        # Set a quick JSON lookup attribute.
        if 'method' in kwargs:
            method = getattr(self.client, kwargs.get('method').lower())
        else:
            method = self.client.post

        response = method(headers=headers, *args, **kwargs)

        try:
            response.json = json.loads(response.data)
        except:
            response.json = None

        return response
Пример #20
0
 def test_admin_page_rejects_bad_username(self):
     """ Check that incorrect username won't allow access """
     h = Headers()
     auth = 'foo:{0}'.format(Config.PASSWORD).encode('ascii')
     h.add('Authorization', b'Basic ' + base64.b64encode(auth))
     rv = Client.open(self.client, path='/', headers=h)
     self.assert_401(rv)
Пример #21
0
def item_ogg(item_id, ogg_q):
    from subprocess import Popen, PIPE
    import mimetypes;
    item = g.lib.get_item(item_id)
    filename = os.path.split(item.path)[1]
    filename = os.path.splitext(filename)[0] + '.ogg'

    headers = Headers()
    headers.add('Content-Type', 'audio/ogg')
    headers.add('Content-Disposition', 'attachment', filename=filename)

    if mimetypes.guess_type(item.path)[0] == 'audio/mpeg':
        decoded_fp = Popen(
            ["mpg123", "-q", "-w", "/dev/stdout", item.path],
            stdout=PIPE)
        ogg_fp = Popen(
            ["oggenc", "-q", str(ogg_q), "-Q", "-"],
            stdin=decoded_fp.stdout,
            stdout=PIPE);
        decoded_fp.stdout.close()
    else:
        ogg_fp = Popen(
            ["oggenc", "-q",  str(ogg_q),"-Q", "-o", "/dev/stdout", item.path],
            stdout=PIPE);

    res = Response(
        #wrap_file(request.environ, ogg_fp.stdout),
        ogg_fp.stdout,
        headers=headers,
        direct_passthrough=True)
    res.implicit_sequence_conversion = False

    return res
Пример #22
0
def excel_response(spreadsheet, filename=u'export.xls'):
    """
    Prepares an excel spreadsheet for response in Flask
    :param spreadsheet: the spreadsheet
    :type spreadsheet:class:`xlwt.Workbook`
    :param filename: the name of the file when downloaded
    :type filename: unicode
    :return: the flask response
    :rtype:class:`flask.Response`
    """
    response = Response()
    response.status_code = 200
    output = StringIO.StringIO()
    spreadsheet.save(output)
    response.data = output.getvalue()
    mimetype_tuple = mimetypes.guess_type(filename)

    #HTTP headers for forcing file download
    response_headers = Headers({
        u'Pragma': u"public",  # required,
        u'Expires': u'0',
        u'Cache-Control': [u'must-revalidate, post-check=0, pre-check=0', u'private'],
        u'Content-Type': mimetype_tuple[0],
        u'Content-Disposition': u'attachment; filename=\"%s\";' % filename,
        u'Content-Transfer-Encoding': u'binary',
        u'Content-Length': len(response.data)
    })

    if not mimetype_tuple[1] is None:
        response_headers.update({u'Content-Encoding': mimetype_tuple[1]})

    response.headers = response_headers
    response.set_cookie(u'fileDownload', u'true', path=u'/')
    return response
Пример #23
0
    def test_resubscribe(self):
        user_email = '*****@*****.**'
        user_password = '******'
        add_admin(user_email, user_password)

        hub = 'http://push.superfeedr.com'
        responses.add(responses.POST,
                      hub,
                      body='{"title": "Success"}',
                      status=204,
                      content_type='application/json')

        less_24 = datetime.utcnow() + relativedelta(hours=10)
        feed1 = FeedFactory(lease_end=less_24,
                            status=STATUS.SUBSCRIBED,
                            hub=hub)
        feed1.save()

        with self.app.test_client() as c:
            h = Headers()
            auth = requests.auth._basic_auth_str(user_email, user_password)
            h.add('Authorization', auth)
            url = url_for('pubsubhubbub.resubscribe')
            response = c.post(url, headers=h)
            self.assertEqual(response.status_code, 200)
def test_200_with_credentials(client):
    headers = Headers()
    headers.set("Authorization", basic_auth_encode("*****@*****.**", "secret123"))

    response = client.get("/secrets", headers=headers)
    assert response.status_code == 200
    assert isinstance(response.json.get("secrets"), list)
Пример #25
0
 def test07_access_token_handler(self):
     with dummy_app.test_request_context('/a_request'):
         auth = IIIFAuthBasic()
         response = auth.access_token_handler()
         self.assertEqual( response.status_code, 200 )
         self.assertEqual( response.headers['Content-type'], 'application/json' )
         j = json.loads(response.get_data())
         self.assertEqual( j['error_description'], "No login details received" )
         self.assertEqual( j['error'], "client_unauthorized" )
     # add Authorization header, check we get token
     h = Headers()
     h.add('Authorization', 'Basic ' + base64.b64encode('userpass:userpass'))
     with dummy_app.test_request_context('/a_request', headers=h):
         auth = IIIFAuthBasic()
         response = auth.access_token_handler()
         self.assertEqual( response.status_code, 200 )
         self.assertEqual( response.headers['Content-type'], 'application/json' )
         j = json.loads(response.get_data())
         self.assertEqual( j['access_token'], "secret_token_here" ) #FIXME
         self.assertEqual( j['token_type'], "Bearer" )
         self.assertEqual( j['expires_in'], 3600 )
     # add callback but no Authorization header
     with dummy_app.test_request_context('/a_request?callback=CB'):
         auth = IIIFAuthBasic()
         response = auth.access_token_handler()
         self.assertEqual( response.status_code, 200 )
         self.assertEqual( response.headers['Content-type'], 'application/javascript' )
         # strip JavaScript wrapper and then check JSON
         js = response.get_data()
         self.assertTrue( re.match('CB\(.*\);',js) )
         j = json.loads(js.lstrip('CB(').rstrip(');'))
         self.assertEqual( j['error_description'], "No login details received" )
         self.assertEqual( j['error'], "client_unauthorized" )
def test_401_with_invalid_token(client):
    headers = Headers()
    headers.set("Authorization", "Bearer invalid-token")

    response = client.get("/secrets", headers=headers)
    assert response.status_code == 401
    assert response.json.get("error") == "invalid_token"
def test_200_with_authorization_header(client, access_token):
    headers = Headers()
    headers.set("Authorization", "Bearer " + access_token)

    response = client.get("/secrets", headers=headers)
    assert response.status_code == 200
    assert isinstance(response.json.get("secrets"), list)
Пример #28
0
def fetch():
    url = request.form['url']
    print url
    try:
        h = Headers(request.headers)
        h.clear()
        h.add('referer', 'https://www.facebook.com/')

        r = requests.request(
            method='GET',
            url=url,
            headers=h,
            timeout=5
        )
    except (
            requests.exceptions.Timeout,
            requests.exceptions.ConnectTimeout,
            requests.exceptions.ReadTimeout):
        return Response(status=504)
    except (
            requests.exceptions.ConnectionError,
            requests.exceptions.HTTPError,
            requests.exceptions.TooManyRedirects):
        return Response(status=502)
    except (
            requests.exceptions.RequestException,
            Exception) as e:
        if app.debug:
            raise e
        return Response(status=500)

    mimetype = "text/html"
    return Response(r.content, mimetype=mimetype)
def test_401_with_unsupported_authorization_header(client):
    headers = Headers()
    headers.set("Authorization", "MAC 123456789")

    response = client.get("/secrets", headers=headers)
    assert response.status_code == 401
    assert response.json.get("error") == "invalid_token"
Пример #30
0
 def test_admin_page_rejects_bad_password(self):
     """ Check that incorrect password won't allow access """
     h = Headers()
     auth = '{0}:foo'.format(Config.USERNAME).encode('ascii')
     h.add('Authorization', b'Basic ' + base64.b64encode(auth))
     rv = Client.open(self.client, path='/', headers=h)
     self.assert_401(rv)
Пример #31
0
    def handle_error(self, e):
        """Error handler for the API transforms a raised exception into a Flask
        response, with the appropriate HTTP status code and body.

        :param e: the raised Exception object
        :type e: Exception

        """
        got_request_exception.send(current_app._get_current_object(),
                                   exception=e)

        if not isinstance(e,
                          HTTPException) and current_app.propagate_exceptions:
            exc_type, exc_value, tb = sys.exc_info()
            if exc_value is e:
                raise e
            else:
                raise e

        headers = Headers()
        if isinstance(e, HTTPException):
            code = e.code
            default_data = {
                'message': getattr(e, 'description', http_status_message(code))
            }
            headers = e.get_response().headers
        else:
            code = 500
            default_data = {
                'message': http_status_message(code),
            }

        # Werkzeug exceptions generate a content-length header which is added
        # to the response in addition to the actual content-length header
        # https://github.com/flask-restful/flask-restful/issues/534
        remove_headers = ('Content-Length', )

        for header in remove_headers:
            headers.pop(header, None)

        data = getattr(e, 'data', default_data)

        if code and code >= 500:
            exc_info = sys.exc_info()
            if exc_info[1] is None:
                exc_info = None
            current_app.log_exception(exc_info)

        error_cls_name = type(e).__name__
        if error_cls_name in self.errors:
            custom_data = self.errors.get(error_cls_name, {})
            code = custom_data.get('status', 500)
            data.update(custom_data)

        if code == 406 and self.default_mediatype is None:
            # if we are handling NotAcceptable (406), make sure that
            # make_response uses a representation we support as the
            # default mediatype (so that make_response doesn't throw
            # another NotAcceptable error).
            supported_mediatypes = list(self.representations.keys())
            fallback_mediatype = supported_mediatypes[
                0] if supported_mediatypes else "text/plain"
            resp = self.make_response(data,
                                      code,
                                      headers,
                                      fallback_mediatype=fallback_mediatype)
        else:
            resp = self.make_response(data, code, headers)

        if code == 401:
            resp = self.unauthorized(resp)
        return resp
Пример #32
0
def send_file(
    filename_or_fp,
    mimetype=None,
    as_attachment=False,
    attachment_filename=None,
    add_etags=True,
    cache_timeout=None,
    conditional=False,
    last_modified=None,
):
    """Sends the contents of a file to the client.  This will use the
    most efficient method available and configured.  By default it will
    try to use the WSGI server's file_wrapper support.  Alternatively
    you can set the application's :attr:`~Flask.use_x_sendfile` attribute
    to ``True`` to directly emit an ``X-Sendfile`` header.  This however
    requires support of the underlying webserver for ``X-Sendfile``.

    By default it will try to guess the mimetype for you, but you can
    also explicitly provide one.  For extra security you probably want
    to send certain files as attachment (HTML for instance).  The mimetype
    guessing requires a `filename` or an `attachment_filename` to be
    provided.

    ETags will also be attached automatically if a `filename` is provided. You
    can turn this off by setting `add_etags=False`.

    If `conditional=True` and `filename` is provided, this method will try to
    upgrade the response stream to support range requests.  This will allow
    the request to be answered with partial content response.

    Please never pass filenames to this function from user sources;
    you should use :func:`send_from_directory` instead.

    .. versionadded:: 0.2

    .. versionadded:: 0.5
       The `add_etags`, `cache_timeout` and `conditional` parameters were
       added.  The default behavior is now to attach etags.

    .. versionchanged:: 0.7
       mimetype guessing and etag support for file objects was
       deprecated because it was unreliable.  Pass a filename if you are
       able to, otherwise attach an etag yourself.  This functionality
       will be removed in Flask 1.0

    .. versionchanged:: 0.9
       cache_timeout pulls its default from application config, when None.

    .. versionchanged:: 0.12
       The filename is no longer automatically inferred from file objects. If
       you want to use automatic mimetype and etag support, pass a filepath via
       `filename_or_fp` or `attachment_filename`.

    .. versionchanged:: 0.12
       The `attachment_filename` is preferred over `filename` for MIME-type
       detection.

    .. versionchanged:: 1.0
        UTF-8 filenames, as specified in `RFC 2231`_, are supported.

    .. _RFC 2231: https://tools.ietf.org/html/rfc2231#section-4

    .. versionchanged:: 1.0.3
        Filenames are encoded with ASCII instead of Latin-1 for broader
        compatibility with WSGI servers.

    .. versionchanged:: 1.1
        Filename may be a :class:`~os.PathLike` object.

    .. versionadded:: 1.1
        Partial content supports :class:`~io.BytesIO`.

    :param filename_or_fp: the filename of the file to send.
                           This is relative to the :attr:`~Flask.root_path`
                           if a relative path is specified.
                           Alternatively a file object might be provided in
                           which case ``X-Sendfile`` might not work and fall
                           back to the traditional method.  Make sure that the
                           file pointer is positioned at the start of data to
                           send before calling :func:`send_file`.
    :param mimetype: the mimetype of the file if provided. If a file path is
                     given, auto detection happens as fallback, otherwise an
                     error will be raised.
    :param as_attachment: set to ``True`` if you want to send this file with
                          a ``Content-Disposition: attachment`` header.
    :param attachment_filename: the filename for the attachment if it
                                differs from the file's filename.
    :param add_etags: set to ``False`` to disable attaching of etags.
    :param conditional: set to ``True`` to enable conditional responses.

    :param cache_timeout: the timeout in seconds for the headers. When ``None``
                          (default), this value is set by
                          :meth:`~Flask.get_send_file_max_age` of
                          :data:`~flask.current_app`.
    :param last_modified: set the ``Last-Modified`` header to this value,
        a :class:`~datetime.datetime` or timestamp.
        If a file was passed, this overrides its mtime.
    """
    mtime = None
    fsize = None

    if hasattr(filename_or_fp, "__fspath__"):
        filename_or_fp = fspath(filename_or_fp)

    if isinstance(filename_or_fp, string_types):
        filename = filename_or_fp
        if not os.path.isabs(filename):
            filename = os.path.join(current_app.root_path, filename)
        file = None
        if attachment_filename is None:
            attachment_filename = os.path.basename(filename)
    else:
        file = filename_or_fp
        filename = None

    if mimetype is None:
        if attachment_filename is not None:
            mimetype = (
                mimetypes.guess_type(attachment_filename)[0]
                or "application/octet-stream"
            )

        if mimetype is None:
            raise ValueError(
                "Unable to infer MIME-type because no filename is available. "
                "Please set either `attachment_filename`, pass a filepath to "
                "`filename_or_fp` or set your own MIME-type via `mimetype`."
            )

    headers = Headers()
    if as_attachment:
        if attachment_filename is None:
            raise TypeError("filename unavailable, required for sending as attachment")

        if not isinstance(attachment_filename, text_type):
            attachment_filename = attachment_filename.decode("utf-8")

        try:
            attachment_filename = attachment_filename.encode("ascii")
        except UnicodeEncodeError:
            filenames = {
                "filename": unicodedata.normalize("NFKD", attachment_filename).encode(
                    "ascii", "ignore"
                ),
                "filename*": "UTF-8''%s" % url_quote(attachment_filename, safe=b""),
            }
        else:
            filenames = {"filename": attachment_filename}

        headers.add("Content-Disposition", "attachment", **filenames)

    if current_app.use_x_sendfile and filename:
        if file is not None:
            file.close()
        headers["X-Sendfile"] = filename
        fsize = os.path.getsize(filename)
        headers["Content-Length"] = fsize
        data = None
    else:
        if file is None:
            file = open(filename, "rb")
            mtime = os.path.getmtime(filename)
            fsize = os.path.getsize(filename)
            headers["Content-Length"] = fsize
        elif isinstance(file, io.BytesIO):
            try:
                fsize = file.getbuffer().nbytes
            except AttributeError:
                # Python 2 doesn't have getbuffer
                fsize = len(file.getvalue())
            headers["Content-Length"] = fsize
        data = wrap_file(request.environ, file)

    rv = current_app.response_class(
        data, mimetype=mimetype, headers=headers, direct_passthrough=True
    )

    if last_modified is not None:
        rv.last_modified = last_modified
    elif mtime is not None:
        rv.last_modified = mtime

    rv.cache_control.public = True
    if cache_timeout is None:
        cache_timeout = current_app.get_send_file_max_age(filename)
    if cache_timeout is not None:
        rv.cache_control.max_age = cache_timeout
        rv.expires = int(time() + cache_timeout)

    if add_etags and filename is not None:
        from warnings import warn

        try:
            rv.set_etag(
                "%s-%s-%s"
                % (
                    os.path.getmtime(filename),
                    os.path.getsize(filename),
                    adler32(
                        filename.encode("utf-8")
                        if isinstance(filename, text_type)
                        else filename
                    )
                    & 0xFFFFFFFF,
                )
            )
        except OSError:
            warn(
                "Access %s failed, maybe it does not exist, so ignore etags in "
                "headers" % filename,
                stacklevel=2,
            )

    if conditional:
        try:
            rv = rv.make_conditional(request, accept_ranges=True, complete_length=fsize)
        except RequestedRangeNotSatisfiable:
            if file is not None:
                file.close()
            raise
        # make sure we don't send x-sendfile for servers that
        # ignore the 304 status code for x-sendfile.
        if rv.status_code == 304:
            rv.headers.pop("x-sendfile", None)
    return rv
Пример #33
0
def get_headers():
    return Headers([('X-Real-Ip', '172.20.0.1'), ('Host', 'up-distributey'),
                    ('Connection', 'close'), ('User-Agent', 'curl/7.68.0'),
                    ('Accept', '*/*'),
                    ('Authorization', f'Bearer {get_jwt()}')])
Пример #34
0
def handler(request):
    headers = Headers()
    headers.add('Content-Type', 'application/json')
    return Response(response=json.dumps({"data": "Hello World!"}),
                    headers=headers)
Пример #35
0
 def fixing_start_response(status, headers, exc_info=None):
     headers = Headers(headers)
     self.fix_headers(environ, headers, status)
     return start_response(status, headers.to_wsgi_list(), exc_info)
Пример #36
0
class Request(object):
    """
    A Request object.

    This should not be manually created. Instead, it is automatically provided by Kyokai.

    If you must create one, use :meth:`from_data` or :meth:`parse`.

    :ivar method: The HTTP method (GET, POST, PUT, etc)
    :ivar path: The full path of the request (``/api/v1/whatever``)
    :ivar headers: A :class:`IOrderedDict` representing the headers of the request.
    :ivar query: The raw query string (``a=b&c=d``)
    :ivar body: The raw body of the request.

    :ivar cookies: A :class:`cookies.SimpleCookie` containing the cookies of the request.

    :ivar args: The arguments from the query string, parsed out.
    :ivar form: The form data for the request. If the request was JSON, this is automatically parsed out.
    :ivar values: THe arguments and the form combined.

    :ivar source: The source IP of the request.
    """
    def __init__(self):
        """
        Creates a new request.

        The request is probably useless right now, but the HTTP parser will then go on to set the right attributes on
        it.
        """
        # Empty values.
        self.method = ""

        # This differs from path/query because it's the full `/a/b/?c=d`.
        # This is then urlsplit into a path and query string in _parse_path.
        self.full_path = b""

        self.path = ""
        self.query = ""
        self.version = ""

        # Empty body, as this isn't known until it's passed in.
        self.body = ""

        self.cookies = cookies.SimpleCookie()

        # We use a Headers object here as it serves our purposes the best.
        self.headers = Headers()

        # Args, values, and forms are OrderedMultiDicts.
        # So are files.
        self.args = OrderedMultiDict()
        self._form = OrderedMultiDict()
        self.values = OrderedMultiDict()
        self.files = OrderedMultiDict()

        # Protocol-specific data.
        self.ip = ""
        self.port = 0

        # Extra values, for hooks.
        self.extra = {}

        self.should_keep_alive = False

    @property
    def form(self) -> dict:
        """
        Returns the form data for the specified request.
        JSON forms are lazy loaded. This means that parsing is done in the first call to `.form`, rather than when
        the request is created.
        """
        if self._form:
            return self._form
        # Parse JSON, otherwise.
        if self.headers.get("Content-Type") == "application/json":
            self._form = json.loads(self.body)
            self.values.update(self._form if self._form else {})
        return self._form

    def _parse_path(self):
        """
        urlsplits the full path.
        """
        split = uparse.urlsplit(self.full_path.decode())
        self.path = split.path
        self.query = split.query

    def _parse_query(self):
        """
        Parses the query string, and updates `args` with it as appropriate.
        """
        new_args = uparse.parse_qs(self.query)
        # Unpack the urlparsed arguments.
        for name, value in new_args.items():
            if len(value) == 1:
                self.args[name] = value[0]
            elif len(value) == 0:
                self.args[name] = None
            else:
                self.args[name] = value

    def _parse_body(self):
        """
        Parses the body data.
        """
        if self.headers.get("Content-Type") != "application/json":
            # Parse the form data out.
            f_parser = formparser.FormDataParser()

            # Wrap the body in a BytesIO.
            body = BytesIO(self.body.encode())

            # The headers can't be directly passed into Werkzeug.
            # Instead, we have to get a the custom content type, then pass in some fake WSGI options.
            mimetype, c_t_args = parse_options_header(
                self.headers.get("Content-Type"))

            if mimetype:
                # We have a valid mimetype.
                # This is good!
                # Now parse the body.

                # Construct a fake WSGI environment.
                env = {
                    "Content-Type": self.headers.get("Content-Type"),
                    "Content-Length": self.headers.get("Content-Length")
                }

                # Take the boundary out of the Content-Type, if applicable.
                boundary = c_t_args.get("boundary")
                if boundary is not None:
                    env["boundary"] = boundary

                # Get a good content length.
                content_length = self.headers.get("Content-Length")
                try:
                    content_length = int(content_length)
                except ValueError:
                    content_length = len(self.body)
                except TypeError:
                    # NoneType...
                    raise HTTPException(411)

                # Then, the form body itself is parsed.

                data = f_parser.parse(body,
                                      mimetype,
                                      content_length,
                                      options=env)

                # Extract the new data from the form parser.
                self._form.update(data[1])
                self.files.update(data[2])

    def parse_all(self):
        """
        Called when all data is parsed.

        This tells the request to re-parse everything based off of the raw data.

        This is an internal method.

        .. versionadded:: 1.9
        """
        # Call _parse_path to parse the path.
        self._parse_path()
        # Call _parse_query to parse the query string.
        self._parse_query()
        # Call _parse_body to parse the body.
        self._parse_body()

        # Load cookies.
        cookie_header = self.headers.get_all("Cookie")
        for c in cookie_header:
            self.cookies.load(c)
Пример #37
0
    def report_download(self, data, token):

        requestcontent = json.loads(data)

        url, type = requestcontent[0], requestcontent[1]
        try:
            if type == 'qweb-pdf':
                reportname = url.split('/report/pdf/')[1].split('?')[0]
                docids = None
                if '/' in reportname:
                    reportname, docids = reportname.split('/')

                if docids:
                    # Generic report:
                    response = self.report_routes(reportname,
                                                  docids=docids,
                                                  converter='pdf')
                else:
                    # Particular report:
                    data = url_decode(url.split(
                        '?')[1])  # decoding the args represented in JSON
                    response = self.report_routes(reportname,
                                                  converter='pdf',
                                                  **dict(data))
                    temp_dict = {}
                    temp_dict.update(json.loads(dict(data).pop('options')))

                    if 'skit_report_type' in temp_dict.keys(
                    ) and temp_dict['skit_report_type'] == 'XLS':
                        report = request.env[
                            'ir.actions.report']._get_report_from_name(
                                reportname)
                        filename = "%s.%s" % (report.name, "xls")
                        # Customize the report name must be what we want
                        # from print xls report ,pass the report_name and customize it.
                        # code added for skit.event.report module execute same model for all event report
                        if 'report_name' in temp_dict.keys(
                        ) and temp_dict['skit_report_type'] == 'XLS':
                            filename = "%s.%s" % (temp_dict['report_name'],
                                                  "xls")
                        response.headers.add('Content-Disposition',
                                             content_disposition(filename))
                        response.set_cookie('fileToken', token)
                        return response

                report = request.env[
                    'ir.actions.report']._get_report_from_name(reportname)
                filename = "%s.%s" % (report.name, "pdf")
                response.headers.add('Content-Disposition',
                                     content_disposition(filename))
                response.set_cookie('fileToken', token)
                return response
            elif type == 'controller':
                reqheaders = Headers(request.httprequest.headers)
                response = Client(request.httprequest.app,
                                  BaseResponse).get(url,
                                                    headers=reqheaders,
                                                    follow_redirects=True)
                response.set_cookie('fileToken', token)
                return response
            else:
                return
        except Exception as e:
            se = _serialize_exception(e)
            error = {'code': 200, 'message': "Odoo Server Error", 'data': se}
            return request.make_response(html_escape(json.dumps(error)))
Пример #38
0
 def add_cors_headers(status, headers, exc_info=None):
     headers = Headers(headers)
     headers.add("Access-Control-Allow-Origin", self.origin)
     headers.add("Access-Control-Allow-Headers", "CsrfCheck")
     headers.add("Access-Control-Allow-Credentials", "true")
     headers.add("Access-Control-Allow-Methods", "GET, POST")
     headers.add("Access-Control-Expose-Headers", "...")
     return start_response(status, headers, exc_info)
Пример #39
0
def send_file(filename_or_fp,
              mimetype=None,
              as_attachment=False,
              attachment_filename=None,
              add_etags=True,
              cache_timeout=None,
              conditional=False,
              last_modified=None):
    """Sends the contents of a file to the client.  This will use the
    most efficient method available and configured.  By default it will
    try to use the WSGI server's file_wrapper support.  Alternatively
    you can set the application's :attr:`~Flask.use_x_sendfile` attribute
    to ``True`` to directly emit an ``X-Sendfile`` header.  This however
    requires support of the underlying webserver for ``X-Sendfile``.

    By default it will try to guess the mimetype for you, but you can
    also explicitly provide one.  For extra security you probably want
    to send certain files as attachment (HTML for instance).  The mimetype
    guessing requires a `filename` or an `attachment_filename` to be
    provided.

    ETags will also be attached automatically if a `filename` is provided. You
    can turn this off by setting `add_etags=False`.

    If `conditional=True` and `filename` is provided, this method will try to
    upgrade the response stream to support range requests.  This will allow
    the request to be answered with partial content response.

    Please never pass filenames to this function from user sources;
    you should use :func:`send_from_directory` instead.

    .. versionadded:: 0.2

    .. versionadded:: 0.5
       The `add_etags`, `cache_timeout` and `conditional` parameters were
       added.  The default behavior is now to attach etags.

    .. versionchanged:: 0.7
       mimetype guessing and etag support for file objects was
       deprecated because it was unreliable.  Pass a filename if you are
       able to, otherwise attach an etag yourself.  This functionality
       will be removed in Flask 1.0

    .. versionchanged:: 0.9
       cache_timeout pulls its default from application config, when None.

    .. versionchanged:: 0.12
       The filename is no longer automatically inferred from file objects. If
       you want to use automatic mimetype and etag support, pass a filepath via
       `filename_or_fp` or `attachment_filename`.

    .. versionchanged:: 0.12
       The `attachment_filename` is preferred over `filename` for MIME-type
       detection.

    :param filename_or_fp: the filename of the file to send in `latin-1`.
                           This is relative to the :attr:`~Flask.root_path`
                           if a relative path is specified.
                           Alternatively a file object might be provided in
                           which case ``X-Sendfile`` might not work and fall
                           back to the traditional method.  Make sure that the
                           file pointer is positioned at the start of data to
                           send before calling :func:`send_file`.
    :param mimetype: the mimetype of the file if provided. If a file path is
                     given, auto detection happens as fallback, otherwise an
                     error will be raised.
    :param as_attachment: set to ``True`` if you want to send this file with
                          a ``Content-Disposition: attachment`` header.
    :param attachment_filename: the filename for the attachment if it
                                differs from the file's filename.
    :param add_etags: set to ``False`` to disable attaching of etags.
    :param conditional: set to ``True`` to enable conditional responses.

    :param cache_timeout: the timeout in seconds for the headers. When ``None``
                          (default), this value is set by
                          :meth:`~Flask.get_send_file_max_age` of
                          :data:`~flask.current_app`.
    :param last_modified: set the ``Last-Modified`` header to this value,
        a :class:`~datetime.datetime` or timestamp.
        If a file was passed, this overrides its mtime.
    """
    mtime = None
    fsize = None
    if isinstance(filename_or_fp, string_types):
        filename = filename_or_fp
        if not os.path.isabs(filename):
            filename = os.path.join(current_app.root_path, filename)
        file = None
        if attachment_filename is None:
            attachment_filename = os.path.basename(filename)
    else:
        file = filename_or_fp
        filename = None

    if mimetype is None:
        if attachment_filename is not None:
            mimetype = mimetypes.guess_type(attachment_filename)[0] \
                or 'application/octet-stream'

        if mimetype is None:
            raise ValueError(
                'Unable to infer MIME-type because no filename is available. '
                'Please set either `attachment_filename`, pass a filepath to '
                '`filename_or_fp` or set your own MIME-type via `mimetype`.')

    headers = Headers()
    if as_attachment:
        if attachment_filename is None:
            raise TypeError('filename unavailable, required for '
                            'sending as attachment')
        headers.add('Content-Disposition',
                    'attachment',
                    filename=attachment_filename)

    if current_app.use_x_sendfile and filename:
        if file is not None:
            file.close()
        headers['X-Sendfile'] = filename
        fsize = os.path.getsize(filename)
        headers['Content-Length'] = fsize
        data = None
    else:
        if file is None:
            file = open(filename, 'rb')
            mtime = os.path.getmtime(filename)
            fsize = os.path.getsize(filename)
            headers['Content-Length'] = fsize
        data = wrap_file(request.environ, file)

    rv = current_app.response_class(data,
                                    mimetype=mimetype,
                                    headers=headers,
                                    direct_passthrough=True)

    if last_modified is not None:
        rv.last_modified = last_modified
    elif mtime is not None:
        rv.last_modified = mtime

    rv.cache_control.public = True
    if cache_timeout is None:
        cache_timeout = current_app.get_send_file_max_age(filename)
    if cache_timeout is not None:
        rv.cache_control.max_age = cache_timeout
        rv.expires = int(time() + cache_timeout)

    if add_etags and filename is not None:
        from warnings import warn

        try:
            rv.set_etag(
                '%s-%s-%s' %
                (os.path.getmtime(filename), os.path.getsize(filename),
                 adler32(
                     filename.encode('utf-8') if isinstance(
                         filename, text_type) else filename) & 0xffffffff))
        except OSError:
            warn(
                'Access %s failed, maybe it does not exist, so ignore etags in '
                'headers' % filename,
                stacklevel=2)

    if conditional:
        if callable(getattr(Range, 'to_content_range_header', None)):
            # Werkzeug supports Range Requests
            # Remove this test when support for Werkzeug <0.12 is dropped
            try:
                rv = rv.make_conditional(request,
                                         accept_ranges=True,
                                         complete_length=fsize)
            except RequestedRangeNotSatisfiable:
                file.close()
                raise
        else:
            rv = rv.make_conditional(request)
        # make sure we don't send x-sendfile for servers that
        # ignore the 304 status code for x-sendfile.
        if rv.status_code == 304:
            rv.headers.pop('x-sendfile', None)
    return rv
def i_have_the_url_to_the_contact_page(step):
    world.contact_url = '/contact'
    referrer = ('Referer', 'some/url')
    world.header = Headers([referrer])
Пример #41
0
    def report_download(self, data, token):
        """This function is used by 'qwebactionmanager.js' in order to trigger the download of
        a pdf/controller report.

        :param data: a javascript array JSON.stringified containg report internal url ([0]) and
        type [1]
        :returns: Response with a filetoken cookie and an attachment header
        """
        requestcontent = json.loads(data)
        url, type = requestcontent[0], requestcontent[1]
        try:
            if type == 'qweb-pdf':
                reportname = url.split('/report/pdf/')[1].split('?')[0]

                docids = None
                if '/' in reportname:
                    reportname, docids = reportname.split('/')

                if docids:
                    # Generic report:
                    response = self.report_routes(reportname,
                                                  docids=docids,
                                                  converter='pdf')
                else:
                    # Particular report:
                    data = url_decode(
                        url.split('?')
                        [1]).items()  # decoding the args represented in JSON
                    response = self.report_routes(reportname,
                                                  converter='pdf',
                                                  **dict(data))

                report = request.env['report']._get_report_from_name(
                    reportname)
                filename = "%s.%s" % (report.name, "pdf")
                if docids:
                    ids = [int(x) for x in docids.split(",")]
                    obj = request.env[report.model].browse(ids)
                    if report.print_report_name and not len(obj) > 1:
                        filename = safe_eval(report.print_report_name, {
                            'object': obj,
                            'time': time
                        })
                response.headers.add('Content-Disposition',
                                     content_disposition(filename))
                response.set_cookie('fileToken', token)
                return response
            elif type == 'controller':
                reqheaders = Headers(request.httprequest.headers)
                response = Client(request.httprequest.app,
                                  BaseResponse).get(url,
                                                    headers=reqheaders,
                                                    follow_redirects=True)
                response.set_cookie('fileToken', token)
                return response
            else:
                return
        except Exception, e:
            se = _serialize_exception(e)
            error = {'code': 200, 'message': u'系统错误', 'data': se}
            return request.make_response(html_escape(json.dumps(error)))
Пример #42
0
    def handle_error(self, e):
        """Error handler for the API transforms a raised exception into a Flask
        response, with the appropriate HTTP status code and body.

        :param e: the raised Exception object
        :type e: Exception

        """
        got_request_exception.send(current_app._get_current_object(),
                                   exception=e)

        if not isinstance(e,
                          HTTPException) and current_app.propagate_exceptions:
            exc_type, exc_value, tb = sys.exc_info()
            if exc_value is e:
                raise
            else:
                raise e

        headers = Headers()
        if isinstance(e, HTTPException):
            code = e.code
            default_data = {
                'message': getattr(e, 'description', http_status_message(code))
            }
            headers = e.get_response().headers
        else:
            code = 500
            default_data = {
                'message': http_status_message(code),
            }

        # Werkzeug exceptions generate a content-length header which is added
        # to the response in addition to the actual content-length header
        # https://github.com/flask-restful/flask-restful/issues/534
        remove_headers = ('Content-Length', )

        for header in remove_headers:
            headers.pop(header, None)

        data = getattr(e, 'data', default_data)

        if code >= 500:
            exc_info = sys.exc_info()
            if exc_info[1] is None:
                exc_info = None
            current_app.log_exception(exc_info)

        help_on_404 = current_app.config.get("ERROR_404_HELP", True)
        if code == 404 and help_on_404:
            rules = dict([(re.sub('(<.*>)', '', rule.rule), rule.rule)
                          for rule in current_app.url_map.iter_rules()])
            close_matches = difflib.get_close_matches(request.path,
                                                      rules.keys())
            if close_matches:
                # If we already have a message, add punctuation and continue it.
                if "message" in data:
                    data["message"] = data["message"].rstrip('.') + '. '
                else:
                    data["message"] = ""

                data['message'] += 'You have requested this URI [' + request.path + \
                                   '] but did you mean ' + \
                                   ' or '.join((
                                       rules[match] for match in close_matches)
                                   ) + ' ?'

        error_cls_name = type(e).__name__
        if error_cls_name in self.errors:
            custom_data = self.errors.get(error_cls_name, {})
            code = custom_data.get('status', 500)
            data.update(custom_data)

        if code == 406 and self.default_mediatype is None:
            # if we are handling NotAcceptable (406), make sure that
            # make_response uses a representation we support as the
            # default mediatype (so that make_response doesn't throw
            # another NotAcceptable error).
            supported_mediatypes = list(self.representations.keys())
            fallback_mediatype = supported_mediatypes[
                0] if supported_mediatypes else "text/plain"
            resp = self.make_response(data,
                                      code,
                                      headers,
                                      fallback_mediatype=fallback_mediatype)
        else:
            resp = self.make_response(data, code, headers)

        if code == 401:
            resp = self.unauthorized(resp)
        return resp
Пример #43
0
def write_medium_index_excel(Q, now_year, Q_monthes, location_id, douban_data,
                             youli_data, wuxian_data, zhihu_data, weipiao_data,
                             one_data, xueqiu_data, huxiu_data, ledongli_data,
                             kecheng_data, xiecheng_data, momo_data, lama_data,
                             nice_data, meijie_data, other_data, total_money,
                             total_medium_money2, total_now_Q_money_check,
                             total_first_month_money, total_second_month_money,
                             total_third_month_money,
                             total_now_Q_money_zhixing):
    response = Response()
    response.status_code = 200
    output = StringIO.StringIO()
    workbook = xlsxwriter.Workbook(output)
    worksheet = workbook.add_worksheet()
    align_center = workbook.add_format({
        'align': 'center',
        'valign': 'vcenter',
        'border': 1
    })
    title = [
        u'投放媒体', u'状态', u'合同号', u'代理名称', u'项目名称', u'行业', u'直客销售', u'渠道销售',
        u'合同金额', u'媒体金额', u'本季度确认额', u'本季度执行额', u'上季度执行额', u'下季度执行额'
    ]
    title += [str(k) + u'月执行额' for k in Q_monthes]
    title += [u'80%预估', u'50%以上预估', u'50%以下预估', u'类型', u'执行', u'开始时间', u'结束时间']
    for k in range(len(title)):
        worksheet.write(0, 0 + k, title[k], align_center)
    # 设置宽度
    for k in range(33):
        worksheet.set_column(k, 0, 20)
    # 根据媒体展示详情
    th = 1
    th = new_insert_order_table(worksheet, align_center, douban_data, th,
                                u'豆瓣')
    th = new_insert_order_table(worksheet, align_center, youli_data, th,
                                u'优力互动')
    th = new_insert_order_table(worksheet, align_center, wuxian_data, th,
                                u'无线互联')
    th = new_insert_order_table(worksheet, align_center, zhihu_data, th, u'知乎')
    th = new_insert_order_table(worksheet, align_center, weipiao_data, th,
                                u'微票儿')
    th = new_insert_order_table(worksheet, align_center, one_data, th, u'ONE')
    th = new_insert_order_table(worksheet, align_center, xueqiu_data, th,
                                u'雪球')
    th = new_insert_order_table(worksheet, align_center, huxiu_data, th, u'虎嗅')
    th = new_insert_order_table(worksheet, align_center, ledongli_data, th,
                                u'乐动力')
    th = new_insert_order_table(worksheet, align_center, kecheng_data, th,
                                u'课程格子')
    th = new_insert_order_table(worksheet, align_center, xiecheng_data, th,
                                u'携程')
    th = new_insert_order_table(worksheet, align_center, momo_data, th, u'陌陌')
    th = new_insert_order_table(worksheet, align_center, lama_data, th, u'辣妈帮')
    th = new_insert_order_table(worksheet, align_center, nice_data, th,
                                u'nice')
    th = new_insert_order_table(worksheet, align_center, other_data, th,
                                u'其他媒体')
    th = new_insert_order_table(worksheet, align_center, meijie_data, th,
                                u'媒介下单')

    # 展示总计信息
    total_title = [u"投放媒体", u'合同金额', u"媒体金额", u"本季度确认额", u"本季度执行额"]
    total_title += [str(k) + u'月执行额' for k in Q_monthes]
    for k in range(len(total_title)):
        worksheet.write(0, 25 + k, total_title[k], align_center)
    th = 1
    th = new_insert_total_table(worksheet, align_center, douban_data, th,
                                u'豆瓣')
    th = new_insert_total_table(worksheet, align_center, youli_data, th,
                                u'优力互动')
    th = new_insert_total_table(worksheet, align_center, wuxian_data, th,
                                u'无线互联')
    th = new_insert_total_table(worksheet, align_center, zhihu_data, th, u'知乎')
    th = new_insert_total_table(worksheet, align_center, weipiao_data, th,
                                u'微票儿')
    th = new_insert_total_table(worksheet, align_center, one_data, th, u'ONE')
    th = new_insert_total_table(worksheet, align_center, xueqiu_data, th,
                                u'雪球')
    th = new_insert_total_table(worksheet, align_center, huxiu_data, th, u'虎嗅')
    th = new_insert_total_table(worksheet, align_center, ledongli_data, th,
                                u'乐动力')
    th = new_insert_total_table(worksheet, align_center, kecheng_data, th,
                                u'课程格子')
    th = new_insert_total_table(worksheet, align_center, xiecheng_data, th,
                                u'携程')
    th = new_insert_total_table(worksheet, align_center, momo_data, th, u'陌陌')
    th = new_insert_total_table(worksheet, align_center, lama_data, th, u'辣妈帮')
    th = new_insert_total_table(worksheet, align_center, nice_data, th,
                                u'nice')
    th = new_insert_total_table(worksheet, align_center, other_data, th,
                                u'其他媒体')
    # 合计展示
    worksheet.write(th, 25, u'总计', align_center)
    worksheet.write(th, 26, total_money, align_center)
    worksheet.write(th, 27, total_medium_money2, align_center)
    worksheet.write(th, 28, total_now_Q_money_check, align_center)
    worksheet.write(th, 29, total_now_Q_money_zhixing, align_center)
    worksheet.write(th, 30, total_first_month_money, align_center)
    worksheet.write(th, 31, total_second_month_money, align_center)
    worksheet.write(th, 32, total_third_month_money, align_center)
    th += 1
    th = new_insert_total_table(worksheet, align_center, meijie_data, th,
                                u'其中媒介下单')
    workbook.close()
    response.data = output.getvalue()
    filename = ("%s-%s-%s-%s.xls" % (u"MediumWeekly", str(now_year), str(Q),
                                     TEAM_LOCATION_CN[location_id]))
    mimetype_tuple = mimetypes.guess_type(filename)
    response_headers = Headers({
        'Pragma':
        "public",
        'Expires':
        '0',
        'Cache-Control':
        'must-revalidate, post-check=0, pre-check=0',
        'Cache-Control':
        'private',
        'Content-Type':
        mimetype_tuple[0],
        'Content-Disposition':
        'attachment; filename=\"%s\";' % filename,
        'Content-Transfer-Encoding':
        'binary',
        'Content-Length':
        len(response.data)
    })
    response.headers = response_headers
    response.set_cookie('fileDownload', 'true', path='/')
    return response
Пример #44
0
def collect_task_headers():
    """Get headers required for appengine background task run."""
    headers = {}
    if hasattr(request, "headers"):
        headers = {k: v for k, v in request.headers if k not in BANNED_HEADERS}
    return Headers(headers)
Пример #45
0
def send_file(filename_or_fp,
              mimetype=None,
              as_attachment=False,
              attachment_filename=None,
              add_etags=True,
              cache_timeout=None,
              conditional=False):
    """Sends the contents of a file to the client.  This will use the
    most efficient method available and configured.  By default it will
    try to use the WSGI server's file_wrapper support.  Alternatively
    you can set the application's :attr:`~Flask.use_x_sendfile` attribute
    to ``True`` to directly emit an `X-Sendfile` header.  This however
    requires support of the underlying webserver for `X-Sendfile`.

    By default it will try to guess the mimetype for you, but you can
    also explicitly provide one.  For extra security you probably want
    to send certain files as attachment (HTML for instance).  The mimetype
    guessing requires a `filename` or an `attachment_filename` to be
    provided.

    Please never pass filenames to this function from user sources without
    checking them first.  Something like this is usually sufficient to
    avoid security problems::

        if '..' in filename or filename.startswith('/'):
            abort(404)

    .. versionadded:: 0.2

    .. versionadded:: 0.5
       The `add_etags`, `cache_timeout` and `conditional` parameters were
       added.  The default behavior is now to attach etags.

    .. versionchanged:: 0.7
       mimetype guessing and etag support for file objects was
       deprecated because it was unreliable.  Pass a filename if you are
       able to, otherwise attach an etag yourself.  This functionality
       will be removed in Flask 1.0

    .. versionchanged:: 0.9
       cache_timeout pulls its default from application config, when None.

    :param filename_or_fp: the filename of the file to send.  This is
                           relative to the :attr:`~Flask.root_path` if a
                           relative path is specified.
                           Alternatively a file object might be provided
                           in which case `X-Sendfile` might not work and
                           fall back to the traditional method.  Make sure
                           that the file pointer is positioned at the start
                           of data to send before calling :func:`send_file`.
    :param mimetype: the mimetype of the file if provided, otherwise
                     auto detection happens.
    :param as_attachment: set to `True` if you want to send this file with
                          a ``Content-Disposition: attachment`` header.
    :param attachment_filename: the filename for the attachment if it
                                differs from the file's filename.
    :param add_etags: set to `False` to disable attaching of etags.
    :param conditional: set to `True` to enable conditional responses.

    :param cache_timeout: the timeout in seconds for the headers. When `None`
                          (default), this value is set by
                          :meth:`~Flask.get_send_file_max_age` of
                          :data:`~flask.current_app`.
    """
    mtime = None
    if isinstance(filename_or_fp, string_types):
        filename = filename_or_fp
        file = None
    else:
        from warnings import warn
        file = filename_or_fp
        filename = getattr(file, 'name', None)

        # XXX: this behavior is now deprecated because it was unreliable.
        # removed in Flask 1.0
        if not attachment_filename and not mimetype \
           and isinstance(filename, string_types):
            warn(DeprecationWarning(
                'The filename support for file objects '
                'passed to send_file is now deprecated.  Pass an '
                'attach_filename if you want mimetypes to be guessed.'),
                 stacklevel=2)
        if add_etags:
            warn(DeprecationWarning(
                'In future flask releases etags will no '
                'longer be generated for file objects passed to the send_file '
                'function because this behavior was unreliable.  Pass '
                'filenames instead if possible, otherwise attach an etag '
                'yourself based on another value'),
                 stacklevel=2)

    if filename is not None:
        if not os.path.isabs(filename):
            filename = os.path.join(current_app.root_path, filename)
    if mimetype is None and (filename or attachment_filename):
        mimetype = mimetypes.guess_type(filename or attachment_filename)[0]
    if mimetype is None:
        mimetype = 'application/octet-stream'

    headers = Headers()
    if as_attachment:
        if attachment_filename is None:
            if filename is None:
                raise TypeError('filename unavailable, required for '
                                'sending as attachment')
            attachment_filename = os.path.basename(filename)
        headers.add('Content-Disposition',
                    'attachment',
                    filename=attachment_filename)

    if current_app.use_x_sendfile and filename:
        if file is not None:
            file.close()
        headers['X-Sendfile'] = filename
        headers['Content-Length'] = os.path.getsize(filename)
        data = None
    else:
        if file is None:
            file = open(filename, 'rb')
            mtime = os.path.getmtime(filename)
            headers['Content-Length'] = os.path.getsize(filename)
        data = wrap_file(request.environ, file)

    rv = current_app.response_class(data,
                                    mimetype=mimetype,
                                    headers=headers,
                                    direct_passthrough=True)

    # if we know the file modification date, we can store it as the
    # the time of the last modification.
    if mtime is not None:
        rv.last_modified = int(mtime)

    rv.cache_control.public = True
    if cache_timeout is None:
        cache_timeout = current_app.get_send_file_max_age(filename)
    if cache_timeout is not None:
        rv.cache_control.max_age = cache_timeout
        rv.expires = int(time() + cache_timeout)

    if add_etags and filename is not None:
        rv.set_etag('flask-%s-%s-%s' %
                    (os.path.getmtime(filename), os.path.getsize(filename),
                     adler32(
                         filename.encode('utf-8') if isinstance(
                             filename, text_type) else filename) & 0xffffffff))
        if conditional:
            rv = rv.make_conditional(request)
            # make sure we don't send x-sendfile for servers that
            # ignore the 304 status code for x-sendfile.
            if rv.status_code == 304:
                rv.headers.pop('x-sendfile', None)
    return rv
Пример #46
0
    def __init__(self,
                 path='/',
                 base_url=None,
                 query_string=None,
                 method='GET',
                 input_stream=None,
                 content_type=None,
                 content_length=None,
                 errors_stream=None,
                 multithread=False,
                 multiprocess=False,
                 run_once=False,
                 headers=None,
                 data=None,
                 environ_base=None,
                 environ_overrides=None,
                 charset='utf-8'):
        path_s = make_literal_wrapper(path)
        if query_string is None and path_s('?') in path:
            path, query_string = path.split(path_s('?'), 1)
        self.charset = charset
        self.path = iri_to_uri(path)
        if base_url is not None:
            base_url = url_fix(iri_to_uri(base_url, charset), charset)
        self.base_url = base_url
        if isinstance(query_string, (bytes, text_type)):
            self.query_string = query_string
        else:
            if query_string is None:
                query_string = MultiDict()
            elif not isinstance(query_string, MultiDict):
                query_string = MultiDict(query_string)
            self.args = query_string
        self.method = method
        if headers is None:
            headers = Headers()
        elif not isinstance(headers, Headers):
            headers = Headers(headers)
        self.headers = headers
        if content_type is not None:
            self.content_type = content_type
        if errors_stream is None:
            errors_stream = sys.stderr
        self.errors_stream = errors_stream
        self.multithread = multithread
        self.multiprocess = multiprocess
        self.run_once = run_once
        self.environ_base = environ_base
        self.environ_overrides = environ_overrides
        self.input_stream = input_stream
        self.content_length = content_length
        self.closed = False

        if data:
            if input_stream is not None:
                raise TypeError('can\'t provide input stream and data')
            if isinstance(data, text_type):
                data = data.encode(self.charset)
            if isinstance(data, bytes):
                self.input_stream = BytesIO(data)
                if self.content_length is None:
                    self.content_length = len(data)
            else:
                for key, value in _iter_data(data):
                    if isinstance(value, (tuple, dict)) or \
                       hasattr(value, 'read'):
                        self._add_file_from_data(key, value)
                    else:
                        self.form.setlistdefault(key).append(value)
Пример #47
0
    output = StringIO.StringIO()
    workbook.save(output)
    response.data = output.getvalue()

    mimetype_tuple = mimetypes.guess_type(filename)

    #HTTP headers for forcing file download
    response_headers = Headers({
        'Pragma':
        "public",
        'Expires':
        '0',
        'Cache-Control':
        'must-revalidate, post-check=0, pre-check=0',
        'Cache-Control':
        'private',
        'Content-Type':
        mimetype_tuple[0] or 'application/vnd.ms-excel',
        'Content-Disposition':
        'attachment; filename=\"%s\";' % filename,
        'Content-Transfer-Encoding':
        'binary',
        'Content-Length':
        len(response.data),
    })

    if not mimetype_tuple[1] is None:
        response.update({'Content-Encoding': mimetype_tuple[1]})

    response.headers = response_headers

    #as per jquery.fileDownload.js requirements
Пример #48
0
def write_client_excel(huabei_agent_salers_orders,
                       huabei_direct_salers_orders,
                       huanan_agent_salers_orders,
                       huanan_direct_salers_orders,
                       huadong_agent_salers_orders,
                       huadong_direct_salers_orders,
                       now_year,
                       Q,
                       Q_monthes,
                       otype='client'):
    if otype == 'douban':
        filename = ("%s-%s.xls" %
                    (u"DoubanWeekly",
                     datetime.datetime.now().strftime('%Y%m%d%H%M%S')))
    else:
        filename = (
            "%s-%s.xls" %
            (u"InadWeekly", datetime.datetime.now().strftime('%Y%m%d%H%M%S')))
    response = Response()
    response.status_code = 200
    output = StringIO.StringIO()
    workbook = xlsxwriter.Workbook(output)
    worksheet = workbook.add_worksheet()
    Q_format = workbook.add_format({
        'align': 'left',
        'valign': 'vcenter',
        'fg_color': '#D7E4BC',
        'border': 1
    })
    worksheet.merge_range(0, 0, 1, 8, Q, Q_format)
    # 画出华北区渠道销售
    worksheet, th = _insert_excel(workbook,
                                  worksheet,
                                  huabei_agent_salers_orders,
                                  'agent',
                                  u'华北区',
                                  now_year,
                                  Q,
                                  Q_monthes,
                                  otype,
                                  th=2)
    # 画出华北区直客销售
    worksheet, th = _insert_excel(workbook, worksheet,
                                  huabei_direct_salers_orders, 'direct',
                                  u'华北区', now_year, Q, Q_monthes, otype, th)
    huabei_orders = huabei_agent_salers_orders + huabei_direct_salers_orders
    # 画出华北区综合
    worksheet, th = _insert_excel_location_total(workbook, worksheet,
                                                 huabei_orders, otype, th)

    # 画出华南区渠道销售
    worksheet, th = _insert_excel(workbook, worksheet,
                                  huanan_agent_salers_orders, 'agent', u'华南区',
                                  now_year, Q, Q_monthes, otype, th)
    # 画出华南区直客销售
    worksheet, th = _insert_excel(workbook, worksheet,
                                  huanan_direct_salers_orders, 'direct',
                                  u'华南区', now_year, Q, Q_monthes, otype, th)
    huanan_orders = huanan_agent_salers_orders + huanan_direct_salers_orders
    # 画出华南区综合
    worksheet, th = _insert_excel_location_total(workbook, worksheet,
                                                 huanan_orders, otype, th)

    # 画出华东区渠道销售
    worksheet, th = _insert_excel(workbook, worksheet,
                                  huadong_agent_salers_orders, 'agent', u'华东区',
                                  now_year, Q, Q_monthes, otype, th)
    # 画出华南区直客销售
    worksheet, th = _insert_excel(workbook, worksheet,
                                  huadong_direct_salers_orders, 'direct',
                                  u'华东区', now_year, Q, Q_monthes, otype, th)
    huadong_orders = huadong_agent_salers_orders + huadong_direct_salers_orders
    # 画出华南区综合
    worksheet, th = _insert_excel_location_total(workbook, worksheet,
                                                 huadong_orders, otype, th)

    # 画出所有合同总和
    total_orders = huabei_orders + huanan_orders + huadong_orders
    worksheet, th = _insert_excel_total(workbook, worksheet, total_orders, th,
                                        Q_monthes, otype)

    workbook.close()
    response.data = output.getvalue()
    mimetype_tuple = mimetypes.guess_type(filename)
    response_headers = Headers({
        'Pragma':
        "public",
        'Expires':
        '0',
        'Cache-Control':
        'must-revalidate, post-check=0, pre-check=0',
        'Cache-Control':
        'private',
        'Content-Type':
        mimetype_tuple[0],
        'Content-Disposition':
        'attachment; filename=\"%s\";' % filename,
        'Content-Transfer-Encoding':
        'binary',
        'Content-Length':
        len(response.data)
    })
    response.headers = response_headers
    response.set_cookie('fileDownload', 'true', path='/')
    return response
Пример #49
0
    def get(self, scope_name):
        """
        Metalink redirect

        .. :quickref: MetaLinkRedirector; Metalink redirect.

        :param scope_name: data identifier (scope)/(name).
        :resheader Content-Type: application/metalink4+xml'.
        :status 200: OK.
        :status 401: Invalid Auth Token.
        :status 404: RSE Not Found.
        :status 404: DID Not Found.
        :status 406: Not Acceptable.
        :status 500: Internal Error.
        :returns: Metalink file
        """
        headers = Headers()
        headers.set('Access-Control-Allow-Origin',
                    request.environ.get('HTTP_ORIGIN'))
        headers.set('Access-Control-Allow-Headers',
                    request.environ.get('HTTP_ACCESS_CONTROL_REQUEST_HEADERS'))
        headers.set('Access-Control-Allow-Methods', '*')
        headers.set('Access-Control-Allow-Credentials', 'true')

        try:
            scope, name = parse_scope_name(
                scope_name, request.headers.get('X-Rucio-VO', default='def'))
        except ValueError as error:
            return generate_http_error_flask(400,
                                             'ValueError',
                                             error.args[0],
                                             headers=headers)
        except Exception as error:
            print(format_exc())
            return str(error), 500, headers

        dids, schemes, select = [{
            'scope': scope,
            'name': name
        }], ['http', 'https', 'root', 'gsiftp', 'srm', 'davs'], None

        # set the correct client IP
        client_ip = request.headers.get('X-Forwarded-For',
                                        default=request.remote_addr)

        client_location = {'ip': client_ip, 'fqdn': None, 'site': None}

        if request.query_string:
            query_string = request.query_string.decode(encoding='utf-8')
            params = parse_qs(query_string)
            if 'schemes' in params:
                schemes = params['schemes']
            if 'select' in params:
                select = params['select'][0]
            if 'sort' in params:
                select = params['sort'][0]

            if 'ip' in params:
                client_location['ip'] = params['ip'][0]
            if 'fqdn' in params:
                client_location['fqdn'] = params['fqdn'][0]
            if 'site' in params:
                client_location['site'] = params['site'][0]

        # get vo if given
        vo = request.headers.get('X-Rucio-VO', default='def')

        try:
            replicas_iter = list_replicas(dids=dids,
                                          schemes=schemes,
                                          client_location=client_location,
                                          vo=vo)
            try:
                first = next(replicas_iter)
            except StopIteration:
                return 'no redirection possible - cannot find the DID', 404

            def generate():
                # first, set the appropriate content type, and stream the header
                yield '<?xml version="1.0" encoding="UTF-8"?>\n<metalink xmlns="urn:ietf:params:xml:ns:metalink">\n'

                # iteratively stream the XML per file
                for rfile in itertools.chain((first, ), replicas_iter):
                    replicas = []
                    dictreplica = {}
                    for rse in rfile['rses']:
                        for replica in rfile['rses'][rse]:
                            replicas.append(replica)
                            dictreplica[replica] = rse

                    # stream metadata
                    yield ' <file name="' + rfile['name'] + '">\n'
                    yield '  <identity>' + rfile['scope'] + ':' + rfile[
                        'name'] + '</identity>\n'

                    if rfile['adler32'] is not None:
                        yield '  <hash type="adler32">' + rfile[
                            'adler32'] + '</hash>\n'
                    if rfile['md5'] is not None:
                        yield '  <hash type="md5">' + rfile['md5'] + '</hash>\n'

                    yield '  <size>' + str(rfile['bytes']) + '</size>\n'

                    yield '  <glfn name="/atlas/rucio/%s:%s">' % (
                        rfile['scope'], rfile['name'])
                    yield '</glfn>\n'

                    # sort the actual replicas if necessary
                    if select == 'geoip':
                        replicas = sort_geoip(dictreplica,
                                              client_location['ip'],
                                              ignore_error=True)
                    elif select == 'closeness':
                        replicas = sort_closeness(dictreplica, client_location)
                    elif select == 'dynamic':
                        replicas = sort_dynamic(dictreplica, client_location)
                    elif select == 'ranking':
                        replicas = sort_ranking(dictreplica, client_location)
                    else:
                        replicas = sort_random(dictreplica)

                    # stream URLs
                    idx = 1
                    for replica in replicas:
                        yield '  <url location="' + str(
                            dictreplica[replica]) + '" priority="' + str(
                                idx) + '">' + replica + '</url>\n'
                        idx += 1

                    yield ' </file>\n'

                # don't forget to send the metalink footer
                yield '</metalink>\n'

            return try_stream(generate(),
                              content_type='application/metalink4+xml')
        except DataIdentifierNotFound as error:
            return generate_http_error_flask(404,
                                             'DataIdentifierNotFound',
                                             error.args[0],
                                             headers=headers)
        except ReplicaNotFound as error:
            return generate_http_error_flask(404,
                                             'ReplicaNotFound',
                                             error.args[0],
                                             headers=headers)
        except RucioException as error:
            return generate_http_error_flask(500,
                                             error.__class__.__name__,
                                             error.args[0],
                                             headers=headers)
        except Exception as error:
            print(format_exc())
            return str(error), 500, headers
Пример #50
0
def web(chatbotname, messenger):
    platform = messenger
    # Messenger web - facebook - telegram - kik
    if request.method == 'GET' and messenger != 'facebook':
        abort(404)

    config = app.config["CHATBOTS"]
    if chatbotname not in config:
        abort(404)

    # Facebook Challenge
    if request.method == 'GET' and messenger == 'facebook':
        hub_mode = request.args.get('hub.mode', '')
        hub_verify_token = request.args.get('hub.verify_token', '')
        hub_challenge = request.args.get('hub.challenge', '')
        if hub_mode == 'subscribe' and hub_verify_token == config[chatbotname][
                "facebook"]["HUB_VERIFY_TOKEN"]:
            return hub_challenge
        else:
            abort(403)
    #

    wat = watson(config[chatbotname]["watson"]["username"],
                 config[chatbotname]["watson"]["password"],
                 config[chatbotname]["watson"]["workspace_id"])

    if messenger == 'web':
        if request.form.get("question") == '':
            m = None
        else:
            m = request.form.get("question")

        chat_id = request.form.get("chat_id")

        messages = []
        watson_responses = get_watson_response(wat, platform, chatbotname,
                                               chat_id, m)
        for watson_response in watson_responses:
            messages = messages + watson_response["output"]["text"]

        for k in range(0, len(messages)):
            messages[k] = get_external_data(messages[k])

        message = {"message": messages}

        json_response = json.dumps(message)

        h = Headers()
        h.add("Access-Control-Allow-Origin", "*")

        return Response(json_response, mimetype='application/json', headers=h)
    elif messenger == 'facebook':
        if request.method == 'POST':
            msg = request.json
            with open("log/Output.txt", "a") as text_file:
                text_file.write("\n\n")
                text_file.write(str(msg))
            if msg['object'] == 'page':
                for entries in msg['entry']:
                    for message in entries['messaging']:
                        needs_answer = False
                        if "message" in message:
                            senderId = message['sender']['id']
                            if "text" in message["message"]:
                                m = message["message"]["text"]
                                needs_answer = True
                            elif "sticker_id" in message["message"]:
                                m = "sticker_id {}".format(
                                    message["message"]["sticker_id"])
                                needs_answer = True
                        elif "read" in message:
                            senderId = message['sender']['id']
                            m = "[read]"
                            #needs_answer = True
                        elif "postback" in message:
                            if message["postback"].get(
                                    "payload") == "Get Started":
                                senderId = message['sender']['id']
                                m = None
                                needs_answer = True
                        if needs_answer:
                            if m == '/start':
                                m = None
                            if m == '/configure':
                                facebookConfigureBot(chatbotname)
                            watson_responses = get_watson_response(
                                wat, platform, chatbotname, senderId, m)
                            recipientId = senderId
                            for watson_response in watson_responses:
                                for watson_message in watson_response[
                                        "output"]["text"]:
                                    img_url = extract_image(watson_message)
                                    voice_url = extract_voice(watson_message)
                                    audio_url = extract_audio(watson_message)
                                    if img_url:
                                        facebookSendFile(
                                            recipientId, img_url, 'image',
                                            chatbotname)
                                    elif voice_url:
                                        facebookSendFile(
                                            recipientId, voice_url, 'voice',
                                            chatbotname)
                                    elif audio_url:
                                        facebookSendFile(
                                            recipientId, audio_url, 'audio',
                                            chatbotname)
                                    else:
                                        watson_message = get_external_data(
                                            watson_message)
                                        facebookSendTextMessage(
                                            recipientId,
                                            markdown_facebook(watson_message),
                                            chatbotname)
        return jsonify({})
    elif messenger == 'telegram':
        msg = request.json
        with open("log/OutputTelegram.txt", "a") as text_file:
            text_file.write("\n\n")
            text_file.write(str(msg))
        if "message" not in msg:
            return jsonify({})
        if "text" not in msg["message"] and "voice" not in msg["message"]:
            return jsonify({})

        answer = {
            'method': "sendMessage",
            'chat_id': msg["message"]["chat"]["id"],
            'text': "*Hi there!*",
            'parse_mode': 'Markdown',
            'disable_web_page_preview': True
        }

        if "voice" in msg["message"]:
            file_id = msg["message"]["voice"]["file_id"]
            mime_type = msg["message"]["voice"]["mime_type"]
            duration = msg["message"]["voice"]["duration"]
            if duration > 15:
                answer["text"] = "Audio muy largo. Duración máxima 15 segundos"
                return jsonify(answer)
            fileData = {"file_id": file_id}
            fileJson = telegramCallSendAPI('getFile',
                                           chatbotname,
                                           data=fileData)
            try:
                fileJson = fileJson.json()
            except:
                return jsonify({})
            with open("log/OutputTelegram.txt", "a") as text_file:
                text_file.write("\n\n")
                text_file.write(str(fileJson))
            if "result" in fileJson and "file_path" in fileJson["result"]:
                file_path = fileJson["result"]["file_path"]
                answer["text"] = file_path
                token = app.config["CHATBOTS"][chatbotname]["telegram"][
                    "token"]
                url = "https://api.telegram.org/file/bot{}/{}".format(
                    token, file_path)
                #r = requests.get(url)
                local_filename = "voice/{}".format(file_id)
                r = requests.get(url, stream=True)
                with open(local_filename, 'wb') as f:
                    for chunk in r.iter_content(chunk_size=1024):
                        if chunk:  # filter out keep-alive new chunks
                            f.write(chunk)
                            #f.flush() commented by recommendation from J.F.Sebastian
                username = app.config["CHATBOTS"][chatbotname]["watson-stt"][
                    "username"]
                password = app.config["CHATBOTS"][chatbotname]["watson-stt"][
                    "password"]
                api_url = "https://stream.watsonplatform.net/speech-to-text/api"
                if 'VCAP_SERVICES' in os.environ:
                    vcap = json.loads(os.getenv('VCAP_SERVICES'))
                    print('Found VCAP_SERVICES')
                    if 'speech_to_text' in vcap:
                        creds = vcap['speech_to_text'][0]['credentials']
                        username = creds['username']
                        password = creds['password']
                        api_url = creds['url']
                headers = {
                    'Content-Type': mime_type,
                    #'Transfer-Encoding': 'chunked'
                }
                url = "{}/v1/recognize?model=es-ES_BroadbandModel".format(
                    api_url)
                files = {'upload_file': open(local_filename, 'rb')}
                r = requests.post(url,
                                  headers=headers,
                                  files=files,
                                  auth=(username, password))
                try:
                    sttJson = r.json()
                except:
                    return jsonify({})
                with open("log/OutputTelegram.txt", "a") as text_file:
                    text_file.write("\n\n")
                    text_file.write(str(sttJson))
                if "results" not in sttJson:
                    answer["text"] = str(sttJson)
                    return jsonify(answer)
                if len(sttJson["results"]) == 0:
                    answer["text"] = "Error procesando audio"
                    return jsonify(answer)
                transcript = sttJson["results"][0]["alternatives"][0][
                    "transcript"]
                msg["message"]["text"] = transcript
                # return jsonify(answer)
        # return jsonify({})

        if msg["message"]["text"] == '/start':
            msg["message"]["text"] = None
        chat_id = msg["message"]["chat"]["id"]
        watson_responses = get_watson_response(wat, platform, chatbotname,
                                               chat_id, msg["message"]["text"])
        messages = []
        for watson_response in watson_responses:
            messages = messages + watson_response["output"]["text"]
            for message in messages:
                img_url = extract_image(message)
                voice_url = extract_voice(message)
                audio_url = extract_audio(message)
                if img_url:
                    if img_url.endswith("giphy.gif"):
                        telegramSendFile(chat_id, img_url, "video",
                                         chatbotname)
                    else:
                        telegramSendFile(chat_id, img_url, "image",
                                         chatbotname)
                elif voice_url:
                    telegramSendFile(chat_id, voice_url, "voice", chatbotname)
                elif audio_url:
                    telegramSendFile(chat_id, audio_url, "audio", chatbotname)
                else:
                    message = get_external_data(message)
                    telegramSendTextMessage(chat_id,
                                            markdown_telegram(message),
                                            chatbotname)
        # answer["text"] = markdown_telegram("\n\n".join(messages))
        # return jsonify(answer)
        return jsonify({})
Пример #51
0
 def fixing_start_response(status, headers, exc_info=None):
     self.fix_headers(environ, Headers.linked(headers), status)
     return start_response(status, headers, exc_info)
    def handle_error(self, e):
        '''
        Error handler for the API transforms a raised exception into a Flask response,
        with the appropriate HTTP status code and body.

        :param Exception e: the raised Exception object

        '''
        got_request_exception.send(current_app._get_current_object(),
                                   exception=e)

        if not isinstance(e,
                          HTTPException) and current_app.propagate_exceptions:
            exc_type, exc_value, tb = sys.exc_info()
            if exc_value is e:
                raise
            else:
                raise e

        include_message_in_response = current_app.config.get(
            "ERROR_INCLUDE_MESSAGE", True)
        default_data = {}

        headers = Headers()

        for typecheck, handler in six.iteritems(
                self._own_and_child_error_handlers):
            if isinstance(e, typecheck):
                result = handler(e)
                default_data, code, headers = unpack(
                    result, HTTPStatus.INTERNAL_SERVER_ERROR)
                break
        else:
            if isinstance(e, HTTPException):
                code = HTTPStatus(e.code)
                if include_message_in_response:
                    default_data = {
                        'message': getattr(e, 'description', code.phrase)
                    }
                headers = e.get_response().headers
            elif self._default_error_handler:
                result = self._default_error_handler(e)
                default_data, code, headers = unpack(
                    result, HTTPStatus.INTERNAL_SERVER_ERROR)
            else:
                code = HTTPStatus.INTERNAL_SERVER_ERROR
                if include_message_in_response:
                    default_data = {
                        'message': code.phrase,
                    }

        if include_message_in_response:
            default_data['message'] = default_data.get('message', str(e))

        data = getattr(e, 'data', default_data)
        fallback_mediatype = None

        if code >= HTTPStatus.INTERNAL_SERVER_ERROR:
            exc_info = sys.exc_info()
            if exc_info[1] is None:
                exc_info = None
            current_app.log_exception(exc_info)

        elif code == HTTPStatus.NOT_FOUND and current_app.config.get("ERROR_404_HELP", True) \
                and include_message_in_response:
            data['message'] = self._help_on_404(data.get('message', None))

        elif code == HTTPStatus.NOT_ACCEPTABLE and self.default_mediatype is None:
            # if we are handling NotAcceptable (406), make sure that
            # make_response uses a representation we support as the
            # default mediatype (so that make_response doesn't throw
            # another NotAcceptable error).
            supported_mediatypes = list(self.representations.keys())
            fallback_mediatype = supported_mediatypes[
                0] if supported_mediatypes else "text/plain"

        # Remove blacklisted headers
        for header in HEADERS_BLACKLIST:
            headers.pop(header, None)

        resp = self.make_response(data,
                                  code,
                                  headers,
                                  fallback_mediatype=fallback_mediatype)

        if code == HTTPStatus.UNAUTHORIZED:
            resp = self.unauthorized(resp)
        return resp
Пример #53
0
def variants(institute_id, case_name):
    """Display a list of SNV variants."""
    page = int(request.form.get('page', 1))

    institute_obj, case_obj = institute_and_case(store, institute_id, case_name)
    variant_type = request.args.get('variant_type', 'clinical')

    # Update filter settings if Clinical Filter was requested

    default_panels = []
    for panel in case_obj['panels']:
        if panel.get('is_default'):
            default_panels.append(panel['panel_name'])

    request.form.get('gene_panels')
    if bool(request.form.get('clinical_filter')):
        clinical_filter = MultiDict({
            'variant_type': 'clinical',
            'region_annotations': ['exonic','splicing'],
            'functional_annotations': SEVERE_SO_TERMS,
            'clinsig': [4,5],
            'clinsig_confident_always_returned': True,
            'gnomad_frequency': str(institute_obj['frequency_cutoff']),
            'variant_type': 'clinical',
            'gene_panels': default_panels
             })

    if(request.method == "POST"):
        if bool(request.form.get('clinical_filter')):
            form = FiltersForm(clinical_filter)
            form.csrf_token = request.args.get('csrf_token')
        else:
            form = FiltersForm(request.form)
    else:
        form = FiltersForm(request.args)

    # populate available panel choices
    available_panels = case_obj.get('panels', []) + [
        {'panel_name': 'hpo', 'display_name': 'HPO'}]

    panel_choices = [(panel['panel_name'], panel['display_name'])
                     for panel in available_panels]

    form.gene_panels.choices = panel_choices

    # upload gene panel if symbol file exists
    if (request.files):
        file = request.files[form.symbol_file.name]

    if request.files and file and file.filename != '':
        log.debug("Upload file request files: {0}".format(request.files.to_dict()))
        try:
            stream = io.StringIO(file.stream.read().decode('utf-8'), newline=None)
        except UnicodeDecodeError as error:
            flash("Only text files are supported!", 'warning')
            return redirect(request.referrer)

        hgnc_symbols_set = set(form.hgnc_symbols.data)
        log.debug("Symbols prior to upload: {0}".format(hgnc_symbols_set))
        new_hgnc_symbols = controllers.upload_panel(store, institute_id, case_name, stream)
        hgnc_symbols_set.update(new_hgnc_symbols)
        form.hgnc_symbols.data = hgnc_symbols_set
        # reset gene panels
        form.gene_panels.data = ''

    # update status of case if vistited for the first time
    if case_obj['status'] == 'inactive' and not current_user.is_admin:
        flash('You just activated this case!', 'info')
        user_obj = store.user(current_user.email)
        case_link = url_for('cases.case', institute_id=institute_obj['_id'],
                            case_name=case_obj['display_name'])
        store.update_status(institute_obj, case_obj, user_obj, 'active', case_link)

    # check if supplied gene symbols exist
    hgnc_symbols = []
    non_clinical_symbols = []
    not_found_symbols = []
    not_found_ids = []
    if (form.hgnc_symbols.data) and len(form.hgnc_symbols.data) > 0:
        is_clinical = form.data.get('variant_type', 'clinical') == 'clinical'
        clinical_symbols = store.clinical_symbols(case_obj) if is_clinical else None
        for hgnc_symbol in form.hgnc_symbols.data:
            if hgnc_symbol.isdigit():
                hgnc_gene = store.hgnc_gene(int(hgnc_symbol))
                if hgnc_gene is None:
                    not_found_ids.append(hgnc_symbol)
                else:
                    hgnc_symbols.append(hgnc_gene['hgnc_symbol'])
            elif sum(1 for i in store.hgnc_genes(hgnc_symbol)) == 0:
                  not_found_symbols.append(hgnc_symbol)
            elif is_clinical and (hgnc_symbol not in clinical_symbols):
                 non_clinical_symbols.append(hgnc_symbol)
            else:
                hgnc_symbols.append(hgnc_symbol)

    if (not_found_ids):
        flash("HGNC id not found: {}".format(", ".join(not_found_ids)), 'warning')
    if (not_found_symbols):
        flash("HGNC symbol not found: {}".format(", ".join(not_found_symbols)), 'warning')
    if (non_clinical_symbols):
        flash("Gene not included in clinical list: {}".format(", ".join(non_clinical_symbols)), 'warning')
    form.hgnc_symbols.data = hgnc_symbols

    # handle HPO gene list separately
    if 'hpo' in form.data['gene_panels']:
        hpo_symbols = list(set(term_obj['hgnc_symbol'] for term_obj in
                               case_obj['dynamic_gene_list']))

        current_symbols = set(hgnc_symbols)
        current_symbols.update(hpo_symbols)
        form.hgnc_symbols.data = list(current_symbols)

    variants_query = store.variants(case_obj['_id'], query=form.data)
    data = {}

    if request.form.get('export'):
        document_header = controllers.variants_export_header(case_obj)
        export_lines = []
        if form.data['chrom'] == 'MT':
            # Return all MT variants
            export_lines = controllers.variant_export_lines(store, case_obj, variants_query)
        else:
            # Return max 500 variants
            export_lines = controllers.variant_export_lines(store, case_obj, variants_query.limit(500))

        def generate(header, lines):
            yield header + '\n'
            for line in lines:
                yield line + '\n'

        headers = Headers()
        headers.add('Content-Disposition','attachment', filename=str(case_obj['display_name'])+'-filtered_variants.csv')

        # return a csv with the exported variants
        return Response(generate(",".join(document_header), export_lines), mimetype='text/csv',
                        headers=headers)

    data = controllers.variants(store, institute_obj, case_obj, variants_query, page)

    return dict(institute=institute_obj, case=case_obj, form=form,
                    severe_so_terms=SEVERE_SO_TERMS, page=page, **data)
Пример #54
0
    def get(self, scope_name):
        """
        Header Redirect

        .. :quickref: HeaderRedirector; Header redirect.

        :param scope_name: data identifier (scope)/(name).
        :resheader Content-Type: application/metalink+xml'.
        :status 303: Redirect.
        :status 401: Invalid Auth Token.
        :status 404: RSE Not Found.
        :status 404: DID Not Found.
        :status 500: Internal Error.
        """
        headers = Headers()
        headers.set('Access-Control-Allow-Origin',
                    request.environ.get('HTTP_ORIGIN'))
        headers.set('Access-Control-Allow-Headers',
                    request.environ.get('HTTP_ACCESS_CONTROL_REQUEST_HEADERS'))
        headers.set('Access-Control-Allow-Methods', '*')
        headers.set('Access-Control-Allow-Credentials', 'true')

        try:
            scope, name = parse_scope_name(
                scope_name, request.headers.get('X-Rucio-VO', default='def'))
        except ValueError as error:
            return generate_http_error_flask(400,
                                             'ValueError',
                                             error.args[0],
                                             headers=headers)
        except Exception as error:
            print(format_exc())
            return str(error), 500, headers

        try:

            # use the default HTTP protocols if no scheme is given
            select, rse, site, schemes = 'random', None, None, [
                'davs', 'http', 'https'
            ]

            client_ip = request.headers.get('X-Forwarded-For',
                                            default=request.remote_addr)

            client_location = {'ip': client_ip, 'fqdn': None, 'site': None}

            if request.query_string:
                query_string = request.query_string.decode(encoding='utf-8')
                params = parse_qs(query_string)
                if 'select' in params:
                    select = params['select'][0]
                if 'sort' in params:
                    select = params['sort'][0]
                if 'rse' in params:
                    rse = params['rse'][0]
                if 'site' in params:
                    site = params['site'][0]
                if 'schemes' in params:
                    schemes = params['schemes'][0]
                else:
                    schemes = ['davs', 'https', 's3']

                if 'ip' in params:
                    client_location['ip'] = params['ip'][0]
                if 'fqdn' in params:
                    client_location['fqdn'] = params['fqdn'][0]
                if 'site' in params:
                    client_location['site'] = params['site'][0]

            # correctly forward the schemes and select to potential metalink followups
            cleaned_url = request.environ.get('REQUEST_URI').split('?')[0]
            if isinstance(schemes, list):
                headers.set(
                    'Link',
                    '<%s/metalink?schemes=%s&select=%s>; rel=describedby; type="application/metalink+xml"'
                    % (cleaned_url, ','.join(schemes), select))
            else:
                headers.set(
                    'Link',
                    '<%s/metalink?schemes=%s&select=%s>; rel=describedby; type="application/metalink+xml"'
                    % (cleaned_url, schemes, select))
                schemes = [schemes]  # list_replicas needs a list

            # get vo if given
            vo = request.headers.get('X-Rucio-VO', default='def')

            replicas = [
                r for r in list_replicas(dids=[{
                    'scope': scope,
                    'name': name,
                    'type': 'FILE'
                }],
                                         schemes=schemes,
                                         client_location=client_location,
                                         vo=vo)
            ]

            selected_url = None
            for r in replicas:
                if r['rses']:
                    dictreplica = {}

                    if rse:
                        if rse in r['rses'] and r['rses'][rse]:
                            selected_url = r['rses'][rse][0]
                        else:
                            return 'no redirection possible - no valid RSE for HTTP redirection found', 404, headers
                    else:

                        for rep in r['rses']:
                            for replica in r['rses'][rep]:
                                # since this is HTTP-only redirection, and to ensure compatibility with as many http clients as possible
                                # forcibly replacement davs and s3 URLs to https
                                replica = replica.replace(
                                    'davs://',
                                    'https://').replace('s3://', 'https://')
                                dictreplica[replica] = rep

                        if not dictreplica:
                            return 'no redirection possible - no valid RSE for HTTP redirection found', 404, headers

                        elif site:
                            rep = site_selector(dictreplica, site, vo)
                            if rep:
                                selected_url = rep[0]
                            else:
                                return 'no redirection possible - no valid RSE for HTTP redirection found', 404, headers
                        else:
                            if select == 'geoip':
                                rep = sort_geoip(dictreplica,
                                                 client_location['ip'])
                            elif select == 'closeness':
                                rep = sort_closeness(dictreplica,
                                                     client_location)
                            elif select == 'dynamic':
                                rep = sort_dynamic(dictreplica,
                                                   client_location)
                            elif select == 'ranking':
                                rep = sort_ranking(dictreplica,
                                                   client_location)
                            else:
                                rep = sort_random(dictreplica)

                            selected_url = rep[0]

            if selected_url:
                response = redirect(selected_url, code=303)
                response.headers.extend(headers)
                return response

            return 'no redirection possible - file does not exist', 404, headers
        except ReplicaNotFound as error:
            return generate_http_error_flask(404,
                                             'ReplicaNotFound',
                                             error.args[0],
                                             headers=headers)
        except RucioException as error:
            return generate_http_error_flask(500,
                                             error.__class__.__name__,
                                             error.args[0],
                                             headers=headers)
        except Exception as error:
            print(format_exc())
            return str(error), 500, headers
Пример #55
0
    def _parse_v2_payload_format_lambda_output(lambda_output, binary_types,
                                               flask_request):
        """
        Parses the output from the Lambda Container

        :param str lambda_output: Output from Lambda Invoke
        :return: Tuple(int, dict, str, bool)
        """
        # pylint: disable-msg=too-many-statements
        try:
            json_output = json.loads(lambda_output)
        except ValueError as ex:
            raise LambdaResponseParseException(
                "Lambda response must be valid json") from ex

        # lambda can return any valid json response in payload format version 2.0.
        # response can be a simple type like string, or integer
        # https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html#http-api-develop-integrations-lambda.response
        if isinstance(json_output, dict):
            body = json_output.get(
                "body") if "statusCode" in json_output else json.dumps(
                    json_output)
        else:
            body = json_output
            json_output = {}

        if body is None:
            LOG.warning("Lambda returned empty body!")

        status_code = json_output.get("statusCode") or 200
        headers = Headers(json_output.get("headers") or {})

        is_base_64_encoded = json_output.get("isBase64Encoded") or False

        try:
            status_code = int(status_code)
            if status_code <= 0:
                raise ValueError
        except ValueError as ex:
            raise LambdaResponseParseException(
                "statusCode must be a positive int") from ex

        try:
            if body:
                body = str(body)
        except ValueError as ex:
            raise LambdaResponseParseException(
                f"Non null response bodies should be able to convert to string: {body}"
            ) from ex

        # API Gateway only accepts statusCode, body, headers, and isBase64Encoded in
        # a response shape.
        # Don't check the response keys when inferring a response, see
        # https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html#http-api-develop-integrations-lambda.v2.
        invalid_keys = LocalApigwService._invalid_apig_response_keys(
            json_output)
        if "statusCode" in json_output and invalid_keys:
            raise LambdaResponseParseException(
                f"Invalid API Gateway Response Keys: {invalid_keys} in {json_output}"
            )

        # If the customer doesn't define Content-Type default to application/json
        if "Content-Type" not in headers:
            LOG.info(
                "No Content-Type given. Defaulting to 'application/json'.")
            headers["Content-Type"] = "application/json"

        try:
            if LocalApigwService._should_base64_decode_body(
                    binary_types, flask_request, headers, is_base_64_encoded):
                body = base64.b64decode(body)
        except ValueError as ex:
            LambdaResponseParseException(str(ex))

        return status_code, headers, body
Пример #56
0
def proxy_request(host, file=""):
    hostname, port = parse_host_port(host)

    if "proxy" in hostname:
        abort(403)

    response = requests.get(
        "https://proxy-filter.herokuapp.com/is_blacklisted",
        params={'hostname': hostname})
    json_response = response.content.decode()
    response_dictionary = json.loads(json_response)

    success = response_dictionary['success']
    message = response_dictionary['message']

    if success == 0:
        abort(403)

    else:

        # Whitelist a few headers to pass on
        request_headers = {}
        for h in ["Cookie", "Referer", "X-Csrf-Token"]:
            if h in request.headers:
                request_headers[h] = request.headers[h]

        if request.query_string:
            path = "/%s?%s" % (file, request.query_string)

        else:
            path = "/" + file

        if request.method == "POST" or request.method == "PUT":
            form_data = list(iterform(request.form))
            form_data = urllib.urlencode(form_data)
            request_headers["Content-Length"] = len(form_data)
        else:
            form_data = None

        conn = http.client.HTTPConnection(hostname, port)

        conn.request(request.method,
                     path,
                     body=form_data,
                     headers=request_headers)

        resp = conn.getresponse()

        # Clean up response headers for forwarding
        d = {}
        response_headers = Headers()
        for key, value in resp.getheaders():
            d[key.lower()] = value
            if key in ["content-length", "connection", "content-type"]:
                continue

            if key == "set-cookie":
                cookies = value.split(",")
                [response_headers.add(key, c) for c in cookies]
            else:
                response_headers.add(key, value)

        # If this is a redirect, munge the Location URL
        if "location" in response_headers:
            redirect = response_headers["location"]

            response = requests.get(redirect)
            return response.content

        # Rewrite URLs in the content to point to our URL schemt.method == " instead.
        # Ugly, but seems to mostly work.
        root = url_for(".proxy_request", host=host)
        contents = resp.read()

        # Restructing Contents.
        if d["content-type"].find("application/json") >= 0:
            # JSON format contents will be modified here.
            jc = json.loads(contents)
            if jc.has_key("nodes"):
                del jc["nodes"]
            contents = json.dumps(jc)

        else:
            # Generic HTTP.
            for regex in REGEXES:
                contents = regex.sub(r'\1%s' % root, contents)

        flask_response = Response(response=contents,
                                  status=resp.status,
                                  headers=response_headers,
                                  content_type=resp.getheader('content-type'))
        return flask_response.data
Пример #57
0
def verify_i18n(app):
    not_translated = "code hello i18n"
    translated_fr = "code bonjour"

    for accepted in ("unknown", "en_US"):
        headers = Headers([("Accept-Language", accepted)])
        with app.test_request_context(headers=headers):
            assert not hasattr(request, "babel_locale")
            assert not_translated == gettext(not_translated)
            assert hasattr(request, "babel_locale")
            assert (render_template_string("""
            {{ gettext('code hello i18n') }}
            """).strip() == not_translated)

    for lang in ("fr", "fr-FR"):
        headers = Headers([("Accept-Language", lang)])
        with app.test_request_context(headers=headers):
            assert not hasattr(request, "babel_locale")
            assert translated_fr == gettext(not_translated)
            assert hasattr(request, "babel_locale")
            assert (render_template_string("""
            {{ gettext('code hello i18n') }}
            """).strip() == translated_fr)

    # https://github.com/freedomofpress/securedrop/issues/2379
    headers = Headers([("Accept-Language",
                        "en-US;q=0.6,fr_FR;q=0.4,nb_NO;q=0.2")])
    with app.test_request_context(headers=headers):
        assert not hasattr(request, "babel_locale")
        assert not_translated == gettext(not_translated)

    translated_cn = "code chinese"

    for lang in ("zh-CN", "zh-Hans-CN"):
        headers = Headers([("Accept-Language", lang)])
        with app.test_request_context(headers=headers):
            assert not hasattr(request, "babel_locale")
            assert translated_cn == gettext(not_translated)
            assert hasattr(request, "babel_locale")
            assert (render_template_string("""
            {{ gettext('code hello i18n') }}
            """).strip() == translated_cn)

    translated_ar = "code arabic"

    for lang in ("ar", "ar-kw"):
        headers = Headers([("Accept-Language", lang)])
        with app.test_request_context(headers=headers):
            assert not hasattr(request, "babel_locale")
            assert translated_ar == gettext(not_translated)
            assert hasattr(request, "babel_locale")
            assert (render_template_string("""
            {{ gettext('code hello i18n') }}
            """).strip() == translated_ar)

    with app.test_client() as c:

        # a request without Accept-Language or "l" argument gets the
        # default locale
        page = c.get("/login")
        assert session.get("locale") == "en_US"
        assert not_translated == gettext(not_translated)
        assert b"?l=fr_FR" in page.data
        assert b"?l=en_US" not in page.data

        # the session locale should change when the "l" request
        # argument is present and valid
        page = c.get("/login?l=fr_FR",
                     headers=Headers([("Accept-Language", "en_US")]))
        assert session.get("locale") == "fr_FR"
        assert translated_fr == gettext(not_translated)
        assert b"?l=fr_FR" not in page.data
        assert b"?l=en_US" in page.data

        # confirm that the chosen locale, now in the session, is used
        # despite not matching the client's Accept-Language header
        c.get("/", headers=Headers([("Accept-Language", "en_US")]))
        assert session.get("locale") == "fr_FR"
        assert translated_fr == gettext(not_translated)

        # the session locale should not change if an empty "l" request
        # argument is sent
        c.get("/?l=")
        assert session.get("locale") == "fr_FR"
        assert translated_fr == gettext(not_translated)

        # the session locale should not change if no "l" request
        # argument is sent
        c.get("/")
        assert session.get("locale") == "fr_FR"
        assert translated_fr == gettext(not_translated)

        # sending an invalid locale identifier should not change the
        # session locale
        c.get("/?l=YY_ZZ")
        assert session.get("locale") == "fr_FR"
        assert translated_fr == gettext(not_translated)

        # requesting a valid locale via the request argument "l"
        # should change the session locale
        c.get("/?l=en_US", headers=Headers([("Accept-Language", "fr_FR")]))
        assert session.get("locale") == "en_US"
        assert not_translated == gettext(not_translated)

        # again, the session locale should stick even if not included
        # in the client's Accept-Language header
        c.get("/", headers=Headers([("Accept-Language", "fr_FR")]))
        assert session.get("locale") == "en_US"
        assert not_translated == gettext(not_translated)

    with app.test_request_context():
        assert "" == render_template("locales.html")

    with app.test_client() as c:
        c.get("/")
        locales = render_template("locales.html")
        assert "?l=fr_FR" in locales
        assert "?l=en_US" not in locales

        # Test that A[lang,hreflang] attributes (if present) will validate as
        # BCP47/RFC5646 language tags from `i18n.RequestLocaleInfo.language_tag`.
        if 'lang="' in locales:
            assert 'lang="en-US"' in locales
            assert 'lang="fr-FR"' in locales
        if 'hreflang="' in locales:
            assert 'hreflang="en-US"' in locales
            assert 'hreflang="fr-FR"' in locales

        c.get("/?l=ar")
        base = render_template("base.html")
        assert 'dir="rtl"' in base
Пример #58
0
def sv_variants(institute_id, case_name):
    """Display a list of structural variants."""
    page = int(request.form.get('page', 1))

    variant_type = request.args.get('variant_type', 'clinical')

    institute_obj, case_obj = institute_and_case(store, institute_id, case_name)

    form = SvFiltersForm(request.form)

    default_panels = []
    for panel in case_obj['panels']:
        if (panel.get('is_default') and panel['is_default'] is True) or ('default_panels' in case_obj and panel['panel_id'] in case_obj['default_panels']):
            default_panels.append(panel['panel_name'])

    request.form.get('gene_panels')
    if bool(request.form.get('clinical_filter')):
        clinical_filter = MultiDict({
            'variant_type': 'clinical',
            'region_annotations': ['exonic','splicing'],
            'functional_annotations': SEVERE_SO_TERMS,
            'thousand_genomes_frequency': str(institute_obj['frequency_cutoff']),
            'variant_type': 'clinical',
            'clingen_ngi': 10,
            'swegen': 10,
            'size': 100,
            'gene_panels': default_panels
             })

    if(request.method == "POST"):
        if bool(request.form.get('clinical_filter')):
            form = SvFiltersForm(clinical_filter)
            form.csrf_token = request.args.get('csrf_token')
        else:
            form = SvFiltersForm(request.form)
    else:
        form = SvFiltersForm(request.args)

    available_panels = case_obj.get('panels', []) + [
        {'panel_name': 'hpo', 'display_name': 'HPO'}]

    panel_choices = [(panel['panel_name'], panel['display_name'])
                     for panel in available_panels]
    form.gene_panels.choices = panel_choices

    # check if supplied gene symbols exist
    hgnc_symbols = []
    non_clinical_symbols = []
    not_found_symbols = []
    not_found_ids = []
    if (form.hgnc_symbols.data) and len(form.hgnc_symbols.data) > 0:
        is_clinical = form.data.get('variant_type', 'clinical') == 'clinical'
        clinical_symbols = store.clinical_symbols(case_obj) if is_clinical else None
        for hgnc_symbol in form.hgnc_symbols.data:
            if hgnc_symbol.isdigit():
                hgnc_gene = store.hgnc_gene(int(hgnc_symbol))
                if hgnc_gene is None:
                    not_found_ids.append(hgnc_symbol)
                else:
                    hgnc_symbols.append(hgnc_gene['hgnc_symbol'])
            elif sum(1 for i in store.hgnc_genes(hgnc_symbol)) == 0:
                  not_found_symbols.append(hgnc_symbol)
            elif is_clinical and (hgnc_symbol not in clinical_symbols):
                 non_clinical_symbols.append(hgnc_symbol)
            else:
                hgnc_symbols.append(hgnc_symbol)

    if (not_found_ids):
        flash("HGNC id not found: {}".format(", ".join(not_found_ids)), 'warning')
    if (not_found_symbols):
        flash("HGNC symbol not found: {}".format(", ".join(not_found_symbols)), 'warning')
    if (non_clinical_symbols):
        flash("Gene not included in clinical list: {}".format(", ".join(non_clinical_symbols)), 'warning')
    form.hgnc_symbols.data = hgnc_symbols


    # handle HPO gene list separately
    if 'hpo' in form.data['gene_panels']:
        hpo_symbols = list(set(term_obj['hgnc_symbol'] for term_obj in
                               case_obj['dynamic_gene_list']))

        current_symbols = set(hgnc_symbols)
        current_symbols.update(hpo_symbols)
        form.hgnc_symbols.data = list(current_symbols)


    # update status of case if vistited for the first time
    if case_obj['status'] == 'inactive' and not current_user.is_admin:
        flash('You just activated this case!', 'info')
        user_obj = store.user(current_user.email)
        case_link = url_for('cases.case', institute_id=institute_obj['_id'],
                            case_name=case_obj['display_name'])
        store.update_status(institute_obj, case_obj, user_obj, 'active', case_link)

    variants_query = store.variants(case_obj['_id'], category='sv',
                                    query=form.data)
    data = {}
    # if variants should be exported
    if request.form.get('export'):
        document_header = controllers.variants_export_header(case_obj)
        export_lines = []
        # Return max 500 variants
        export_lines = controllers.variant_export_lines(store, case_obj, variants_query.limit(500))

        def generate(header, lines):
            yield header + '\n'
            for line in lines:
                yield line + '\n'

        headers = Headers()
        headers.add('Content-Disposition','attachment', filename=str(case_obj['display_name'])+'-filtered_sv-variants.csv')
        return Response(generate(",".join(document_header), export_lines), mimetype='text/csv', headers=headers) # return a csv with the exported variants

    else:
        data = controllers.sv_variants(store, institute_obj, case_obj,
                                       variants_query, page)

    return dict(institute=institute_obj, case=case_obj, variant_type=variant_type,
                form=form, severe_so_terms=SEVERE_SO_TERMS, page=page, **data)
Пример #59
0
 async def send_push_promise(self, path: str) -> None:
     headers = Headers()
     for name in SERVER_PUSH_HEADERS_TO_COPY:
         for value in self.headers.getlist(name):
             headers.add(name, value)
     await self._send_push_promise(path, headers)
Пример #60
0
    def _request_handler(self, **kwargs):
        """
        We handle all requests to the host:port. The general flow of handling a request is as follows

        * Fetch request from the Flask Global state. This is where Flask places the request and is per thread so
          multiple requests are still handled correctly
        * Find the Lambda function to invoke by doing a look up based on the request.endpoint and method
        * If we don't find the function, we will throw a 502 (just like the 404 and 405 responses we get
          from Flask.
        * Since we found a Lambda function to invoke, we construct the Lambda Event from the request
        * Then Invoke the Lambda function (docker container)
        * We then transform the response or errors we get from the Invoke and return the data back to
          the caller

        Parameters
        ----------
        kwargs dict
            Keyword Args that are passed to the function from Flask. This happens when we have path parameters

        Returns
        -------
        Response object
        """

        route = self._get_current_route(request)
        cors_headers = Cors.cors_to_headers(self.api.cors)

        method, endpoint = self.get_request_methods_endpoints(request)
        if method == "OPTIONS" and self.api.cors:
            headers = Headers(cors_headers)
            return self.service_response("", headers, 200)

        try:
            # the Lambda Event 2.0 is only used for the HTTP API gateway with defined payload format version equal 2.0
            # or none, as the default value to be used is 2.0
            # https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-integrations.html#apis-apiid-integrations-prop-createintegrationinput-payloadformatversion
            if route.event_type == Route.HTTP and route.payload_format_version in [
                    None, "2.0"
            ]:
                route_key = self._v2_route_key(method, endpoint,
                                               route.is_default_route)
                event = self._construct_v_2_0_event_http(
                    request,
                    self.port,
                    self.api.binary_media_types,
                    self.api.stage_name,
                    self.api.stage_variables,
                    route_key,
                )
            else:
                event = self._construct_v_1_0_event(
                    request, self.port, self.api.binary_media_types,
                    self.api.stage_name, self.api.stage_variables)
        except UnicodeDecodeError:
            return ServiceErrorResponses.lambda_failure_response()

        stdout_stream = io.BytesIO()
        stdout_stream_writer = StreamWriter(stdout_stream, self.is_debugging)

        try:
            self.lambda_runner.invoke(route.function_name,
                                      event,
                                      stdout=stdout_stream_writer,
                                      stderr=self.stderr)
        except FunctionNotFound:
            return ServiceErrorResponses.lambda_not_found_response()

        lambda_response, lambda_logs, _ = LambdaOutputParser.get_lambda_output(
            stdout_stream)

        if self.stderr and lambda_logs:
            # Write the logs to stderr if available.
            self.stderr.write(lambda_logs)

        try:
            if route.event_type == Route.HTTP and (
                    not route.payload_format_version
                    or route.payload_format_version == "2.0"):
                (status_code, headers,
                 body) = self._parse_v2_payload_format_lambda_output(
                     lambda_response, self.api.binary_media_types, request)
            else:
                (status_code, headers,
                 body) = self._parse_v1_payload_format_lambda_output(
                     lambda_response, self.api.binary_media_types, request)
        except LambdaResponseParseException as ex:
            LOG.error("Invalid lambda response received: %s", ex)
            return ServiceErrorResponses.lambda_failure_response()

        return self.service_response(body, headers, status_code)