async def instance_create_endpoint(request, instance_id):
    data = request.json
    if data is None:
        return response.HTTPResponse("Missing json payload.", status=400)
    if 'user' not in data.keys():
        return response.HTTPResponse("Missing 'user' json payload parameter.", status=400)
    if 'lifetime' not in data.keys():
        return response.HTTPResponse("Missing 'lifetime' json payload parameter.", status=400)
    ssh_keys = await get_ssh_key_ids()
    base_image = await get_base_images()
    async with httpx.AsyncClient() as client:
        r = await client.post(
            "https://api.digitalocean.com/v2/droplets",
            headers=DIGITALOCEAN_COMMON_HEADERS,
            json={
                "name": "neos-server-{}".format(instance_id),
                "region": "sfo3",
                "size": "s-1vcpu-1gb",
                "image": base_image['id'],
                "ipv6": True,
                "monitoring": True,
                "tags": ["neos", f"instance_id:{instance_id}", f"lifetime:{data['lifetime']}", f"user:{data['user']}"],
                "ssh_keys": ssh_keys,
                "user_data": generate_cloud_init()
            }
        )
        if r.is_error:
            logger.info("request={}".format(r.request.__dict__))
            logger.error("response={}".format(r.json()))
            return response.json({"status": "error", "message": r.reason_phrase}, status=500)
        else:
            return response.json({"status": "created", "instance_id": instance_id}, status=201)
Beispiel #2
0
async def handle_logos(request, cover=None, logo=None, path=None):
    try:
        log.debug(f'[{request.ip}] {request.method} {request.url}')
        if logo:
            orig_url = f'{IMAGENIO_URL}/channelLogo/{logo}'
        elif path and cover:
            orig_url = (f'{IMAGENIO_URL}/covers/programmeImages'
                        f'/portrait/290x429/{path}/{cover}')
        else:
            return response.json({'status': f'{request.url} not found'}, 404)

        if request.method == 'HEAD':
            return response.HTTPResponse(content_type='image/jpeg', status=200)

        global SESSION_LOGOS
        if not SESSION_LOGOS:
            headers = {'User-Agent': 'MICA-IP-STB'}
            SESSION_LOGOS = aiohttp.ClientSession(headers=headers)

        async with SESSION_LOGOS.get(orig_url) as r:
            if r.status == 200:
                logo_data = await r.read()
                headers = {}
                headers.setdefault('Content-Disposition',
                                   f'attachment; filename="{logo}"')
                return response.HTTPResponse(body=logo_data,
                                             content_type='image/jpeg',
                                             headers=headers,
                                             status=200)
            else:
                return response.json({'status': f'{orig_url} not found'}, 404)
    except asyncio.exceptions.CancelledError:
        pass
    def get(request, record_id):
        if str.isdigit(record_id) is False:
            return response.HTTPResponse(status=400)

        if int(record_id) not in timers_table:
            return response.HTTPResponse(body="ID not found", status=404)
        record_list = r.dump_fetch_history(record_id)
        output_json = json.dumps(record_list, indent=3)
        return text(output_json)
    def post(self, request):
        requested_interval = request.json.get('interval')
        requested_url = request.json.get('url')

        try:
            if validators.url(requested_url) is not True:
                return response.HTTPResponse(body="Malformatted URL",
                                             status=400)
        except TypeError:
            return response.HTTPResponse(body="URL is not a string",
                                         status=400)

        try:
            if requested_interval < 1:
                return response.HTTPResponse(body="Interval smaller than 1",
                                             status=400)
        except TypeError:
            return response.HTTPResponse(body="Interval cannot be a string",
                                         status=400)

        # remove trailing / from URL
        requested_url = re.sub(r"/+$", "", requested_url)

        # check if we have this url registered in redis
        redis_id = r.get_id_from_url(requested_url)
        if redis_id is None:
            redis_id = r.add_url(requested_url, requested_interval)
            worker_input = {'site': requested_url, 'interval':
                            requested_interval}
            rpt = multitimer.RepeatingTimer(interval=requested_interval,
                                            function=self.worker_func,
                                            kwargs=worker_input,
                                            count=-1, runonstart=False)
            rpt.start()
            timers_table[redis_id] = rpt
        else:
            redis_id = int(redis_id.decode("utf-8"))
            r.update_interval(redis_id, requested_interval)
            timers_table[redis_id].stop()
            worker_input = {'site': requested_url, 'interval':
                            requested_interval}
            rpt = multitimer.RepeatingTimer(interval=requested_interval,
                                            function=self.worker_func,
                                            kwargs=worker_input,
                                            count=-1,
                                            runonstart=False)
            rpt.start()
            timers_table[redis_id] = rpt

        return text("{\"id\": %s}" % redis_id)
Beispiel #5
0
async def tiles_png(request, image_id, z, x, y, format):
    """
    get tile image
    :param request:
    :param image_id: id of tiff image
    :param x: coordinate-x
    :param y: coordinate-y
    :param format: view format
    :return:
    """

    slide = get_slide(image_id, get_path(image_id, request))

    x = int(x)
    y = int(y)
    z = int(z)

    bio = BytesIO()
    tiles_image = ADeepZoomGenerator(slide).get_tile(z, (x, y))
    tiles_image.save(bio, 'png')
    image_bytes = bio.getvalue()

    headers = {}
    headers.setdefault(
        'Content-Disposition',
        'attachment; image_id="{}"'.format(os.path.basename(image_id)))

    return response.HTTPResponse(status=200,
                                 headers=headers,
                                 body_bytes=image_bytes,
                                 content_type='image/png')
Beispiel #6
0
async def cell_image_request(request, image_id, x, y, w, h, format):
    """
    get cell image
    :param request:
    :param image_id: id of tiff image
    :param x: coordinate-x
    :param y: coordinate-y
    :param w: image width
    :param h: image height
    :return:
    """
    print('==============> in')
    slide = get_slide(image_id, get_path(image_id, request))

    tile_image = slide.read_region((x, y), 0, (w, h))

    bio = BytesIO()

    tile_image.save(bio, 'png')
    image_bytes = bio.getvalue()

    headers = {}
    headers.setdefault(
        'Content-Disposition',
        'attachment; image_id="{}"'.format(os.path.basename(image_id)))

    return response.HTTPResponse(status=200,
                                 headers=headers,
                                 body_bytes=image_bytes,
                                 content_type='image/png')
async def delete_jogging_result(request, *args, **kwargs):
    user_from_token = retrieve_user(request, args, kwargs)
    if user_from_token is None:
        raise InvalidUsage("invalid parameter (maybe expired?)")

    try:
        jogging_id = int(request.path.split("/")[2])
    except ValueError as e:
        raise InvalidUsage(e)

    if jogging_id < 0:
        raise InvalidUsage("invalid id")

    jog = JoggingResult.load_by_jogging_id(jogging_id)

    if jog is None:
        raise InvalidUsage("invalid id")

    user_id_from_token = retrieve_user(request, args, kwargs).user_id
    if user_id_from_token != jog.user_id:
        raise Forbidden("user can only access user jogs")

    jog.delete()

    return response.HTTPResponse(status=204)
Beispiel #8
0
 async def route_wrapper(self, route, req, context, request_args, request_kw,
                         *decorator_args, **decorator_kw):
     _ = decorator_kw.pop('with_context')  # ignore this.
     _options = decorator_kw
     options = get_cors_options(context.app, _options)
     if options.get('automatic_options', True) and req.method == 'OPTIONS':
         resp = response.HTTPResponse()
     else:
         resp = route(req, *request_args, **request_kw)
         while isawaitable(resp):
             resp = await resp
         # resp can be `None` or `[]` if using Websockets
         if not resp:
             return None
     try:
         request_context = context.request[id(req)]
     except (AttributeError, LookupError):
         if SANIC_19_9_0 <= SANIC_VERSION:
             request_context = req.ctx
         else:
             request_context = None
     set_cors_headers(req, resp, request_context, options)
     if request_context is not None:
         setattr(request_context, SANIC_CORS_EVALUATED, "1")
     else:
         context.log(logging.DEBUG, "Cannot access a sanic request "
                     "context. Has request started? Is request ended?")
     return resp
Beispiel #9
0
def unapplied_cors_request_middleware(req, context):
    if req.method == 'OPTIONS':
        try:
            path = req.path
        except AttributeError:
            path = req.url
        resources = context.resources
        log = context.log
        debug = partial(log, logging.DEBUG)
        for res_regex, res_options in resources:
            if res_options.get('automatic_options', True) and \
                    try_match(path, res_regex):
                debug("Request to '{:s}' matches CORS resource '{}'. "
                      "Using options: {}".format(
                        path, get_regexp_pattern(res_regex), res_options))
                resp = response.HTTPResponse()

                try:
                    request_context = context.request[id(req)]
                except (AttributeError, LookupError):
                    if SANIC_19_9_0 <= SANIC_VERSION:
                        request_context = req.ctx
                    else:
                        request_context = None
                        context.log(logging.DEBUG,
                                    "Cannot access a sanic request "
                                    "context. Has request started? Is request ended?")
                set_cors_headers(req, resp, request_context, res_options)
                if request_context is not None:
                    setattr(request_context, SANIC_CORS_EVALUATED, "1")
                return resp
        else:
            debug('No CORS rule matches')
Beispiel #10
0
    async def iframe(self, request):
        cached = request.headers.get('If-None-Match')
        if cached:
            resp = response.HTTPResponse(status=304)
            resp.headers["Content-Type"] = ""
            resp.headers.extend(cache_headers())
            return resp

        headers = (
            ("Content-Type", "text/html;charset=UTF-8"),
            ("ETag", self.iframe_html_hxd),
        )
        headers += cache_headers()
        return response.HTTPResponse(None,
                                     body_bytes=self.iframe_html,
                                     headers=headers)
Beispiel #11
0
async def get_courier(request: Request,
                      courier_id: int) -> response.HTTPResponse:
    courier_status = await app.db.courier_status(courier_id)
    if not courier_status:
        error_logger.warning("Courier id=%s not found", courier_id)
        return response.HTTPResponse(status=404)

    # TODO: move it to thread_pool_executor
    completed_orders_ids = {
        status.order_id
        for status in courier_status.statuses
        if status.completed_time is not None
    }

    json = courier_status.courier.external()

    if not completed_orders_ids:
        return response.json(json, indent=4)

    completed_orders = [
        order for order in courier_status.orders
        if order.order_id in completed_orders_ids
    ]
    completed_orders.sort(key=lambda order: order.completed_time)

    return response.json(json, indent=4)
Beispiel #12
0
async def label_image(request, image_id, format):
    """
    get tile image
    :param request:
    :param image_id: id of tiff image
    :param format: view format
    :return:
    """

    slide = get_slide(image_id, get_path(image_id, request))
    bio = BytesIO()
    label_image = slide.label_image
    # 如果标签存在则保存,否则返回一个空字节
    if label_image:
        label_image.save(bio, 'png')
        image_bytes = bio.getvalue()
    else:
        image_bytes = b''

    headers = {}
    headers.setdefault(
        'Content-Disposition',
        'attachment; image_id="{}"'.format(os.path.basename(image_id)))

    return response.HTTPResponse(status=200,
                                 headers=headers,
                                 body_bytes=image_bytes,
                                 content_type='image/png')
Beispiel #13
0
async def pray(request):
    if not res['token']:
        return response.HTTPResponse(status=400)
    prayer = db.prayer.insert_one({
        "user_id": request.form['user_id'],
        "when": datetime.utcnow(),
        "text": request.form['text']
    })
Beispiel #14
0
 async def get(self, request, key, suffix):
     item = self.callback(key)
     if suffix == ".json":
         headers = {}
         content_type = "application/json"
         data = item.json
         return response.HTTPResponse(data,
                                      content_type=content_type,
                                      headers=headers)
Beispiel #15
0
 async def get(self, request, suffix):
     data = self.callback()
     if suffix == ".json":
         headers = {}
         content_type = "application/json"
         representation = json
         return response.HTTPResponse(representation.dumps(data),
                                      content_type=content_type,
                                      headers=headers)
    def delete(request, record_id):
        if int(record_id) in timers_table:
            timers_table[int(record_id)].stop()
            del timers_table[int(record_id)]

        redis_id = r.delete_id(record_id)
        if redis_id is None:
            return response.HTTPResponse(body="ID not found", status=404)

        return text("{\"id\": %s}" % redis_id)
Beispiel #17
0
def file(bytes, mime_type, image_id):
    """http 文件response"""
    headers = {}
    headers.setdefault('Content-Disposition',
                       'attachment; image_id="{}"'.format(image_id))

    return response.HTTPResponse(status=200,
                                 headers=headers,
                                 content_type=mime_type,
                                 body_bytes=bytes)
Beispiel #18
0
 def wrapper(cls, f, ctx, req, e):
     opts = ctx.options
     log = ctx.log
     # get response from the original handler
     if (req is not None and SANIC_19_12_0 <= SANIC_VERSION
             and isinstance(e, MethodNotSupported)
             and req.method == "OPTIONS"
             and opts.get('automatic_options', True)):
         # A very specific set of requirments to trigger this kind of
         # automatic-options resp
         resp = response.HTTPResponse()
     else:
         do_await = iscoroutinefunction(f)
         resp = f(req, e)
         # async Exceptions may be awaitable and should be returned
         if isawaitable(resp) or do_await:
             log(
                 logging.DEBUG,
                 "Found an async Exception handler response. "
                 "Cannot apply CORS to it. Passing it on.")
             return resp
     # SanicExceptions are equiv to Flask Aborts,
     # always apply CORS to them.
     if (req is not None and resp is not None) and \
             (isinstance(e, exceptions.SanicException) or
              opts.get('intercept_exceptions', True)):
         try:
             cls._apply_cors_to_exception(ctx, req, resp)
         except AttributeError:
             # not sure why certain exceptions doesn't have
             # an accompanying request
             pass
     if req is None:
         return resp
     # These exceptions have normal CORS middleware applied automatically.
     # So set a flag to skip our manual application of the middleware.
     try:
         request_context = ctx.request[id(req)]
     except (LookupError, AttributeError):
         # On Sanic 19.12.0, a NotFound error can be thrown _before_
         # the request_context is set up. This is a fallback routine:
         if SANIC_19_12_0 <= SANIC_VERSION and \
                 isinstance(e, (NotFound, MethodNotSupported)):
             # On sanic 19.9.0+ request is a dict, so we can add our
             # flag directly to it.
             request_context = req.ctx
         else:
             log(
                 logging.DEBUG,
                 "Cannot find the request context. Is request started? "
                 "Is request already finished?")
             request_context = None
     if request_context is not None:
         setattr(request_context, SANIC_CORS_SKIP_RESPONSE_MIDDLEWARE, "1")
     return resp
Beispiel #19
0
    async def bulk_process_notification(cls, request: request.Request,
                                        topic: enum.Enum):
        """Process the received notification.

        - Check if the related topic is supported.
        - Pass the notification info to the dispatchers.

        Parameters
        ----------
        request: sanic.request.Request
            The challenge request received from Twitch
        topic: enum.Enum
            Topic whose notification is being processed

        Returns
        -------

        response.HTTPResponse
            status code: 202 if the request has correctly been processed
            status code: 400 otherwise
        """
        if topic not in NOTIFICATION_TYPE_BY_TOPIC:
            log.error(
                f'Invalid topic "{topic.name}", the notification has been ignored'
            )
            return

        try:
            params = {
                param: request.args.get(param)
                for param in NOTIFICATION_TYPE_BY_TOPIC[topic].valid_params
            }
            data = request.json['data'][0] if request.json['data'] else {}

            for instance in cls.__instances:
                await instance.process_notification(data, topic, params)

            return response.HTTPResponse(status=202)

        except KeyError:
            return response.HTTPResponse(status=400)
Beispiel #20
0
    async def inner(request: request.Request, *args, **kwargs):
        notification_id = request.headers.get('Twitch-Notification-ID')

        if notification_id in recent_notification_ids:
            log.warning(
                f'Received duplicate notification with ID {notification_id}, discarding.'
            )

            return response.HTTPResponse(status=200)

        recent_notification_ids.append(notification_id)
        return await route(request, *args, **kwargs)
Beispiel #21
0
    async def get(self, request, as_json):
        data = self.data_callback()
        if as_json:
            headers = {}
            if self.ds.cors:
                headers["Access-Control-Allow-Origin"] = "*"
            return response.HTTPResponse(
                json.dumps(data), content_type="application/json", headers=headers
            )

        else:
            return self.render(["show_json.html"], filename=self.filename, data=data)
Beispiel #22
0
def zip(musics, name='archive'):
    headers = {}
    headers['X-Archive-Files'] = 'zip'
    headers['Content-Disposition'] = 'attachment; filename={}'.format(name + '.zip')
    # see mod_zip documentation :p
    lines = [' '.join(['-',
                       str(m['size']),
                       quote("/sendfile" + m['path'][len(m['folder']):]),
                       os.path.join(m['artist'], m['album'], os.path.basename(m['path']))])
             for m in musics]
    body = '\n'.join(lines)
    debug(body)
    return response.HTTPResponse(headers=headers, body=body)
Beispiel #23
0
def JSONResponse(
    body,
    status=200,
    headers=None,
    content_type="application/json",
    **kwargs,
):
    return response.HTTPResponse(
        json.dumps(body, **kwargs, cls=Encoder),
        headers=headers,
        status=status,
        content_type=content_type,
    )
Beispiel #24
0
async def complete(request: Request) -> response.HTTPResponse:
    try:
        complete = CompleteModel(**request.json)
    except ValidationError as e:
        error_logger.warning(e.json(indent=4))
        return response.HTTPResponse(status=400)

    courier_status = await app.db.courier_status(complete.courier_id)

    if courier_status is None:
        error_logger.warning("Courier id=%s not found", complete.courier_id)
        return response.HTTPResponse(status=400)

    has_the_courier_order = any(order.order_id == complete.order_id
                                for order in courier_status.orders)
    if not has_the_courier_order:
        error_logger.warning("Courier id=%s has no order id=%s",
                             complete.courier_id, complete.order_id)
        return response.HTTPResponse(status=400)

    await app.db.complete_order(complete.order_id, complete.complete_time)

    return response.json({"order_id": complete.order_id})
Beispiel #25
0
    async def get(self, request, as_format):
        databases = []
        for key, info in sorted(self.ds.inspect().items()):
            tables = [t for t in info["tables"].values() if not t["hidden"]]
            hidden_tables = [t for t in info["tables"].values() if t["hidden"]]
            database = {
                "name":
                key,
                "hash":
                info["hash"],
                "path":
                "{}-{}".format(key, info["hash"][:HASH_LENGTH]),
                "tables_truncated":
                sorted(tables, key=lambda t: t["count"], reverse=True)[:5],
                "tables_count":
                len(tables),
                "tables_more":
                len(tables) > 5,
                "table_rows_sum":
                sum(t["count"] for t in tables),
                "hidden_table_rows_sum":
                sum(t["count"] for t in hidden_tables),
                "hidden_tables_count":
                len(hidden_tables),
                "views_count":
                len(info["views"]),
            }
            databases.append(database)
        if as_format:
            headers = {}
            if self.ds.cors:
                headers["Access-Control-Allow-Origin"] = "*"
            return response.HTTPResponse(
                json.dumps({db["name"]: db
                            for db in databases},
                           cls=CustomJSONEncoder),
                content_type="application/json",
                headers=headers,
            )

        else:
            return self.render(
                ["index.html"],
                databases=databases,
                metadata=self.ds.metadata,
                datasette_version=__version__,
                extra_css_urls=self.ds.extra_css_urls(),
                extra_js_urls=self.ds.extra_js_urls(),
            )
Beispiel #26
0
    def accept_subscription(request: request.Request, topic: enum.Enum):
        """Handle Twitch challenge requests.

        Accept Twitch subscriptions by responding the request with the provided challenge string.

        Parameters
        ----------
        request: sanic.request.Request
            The challenge request received from Twitch
        topic: enum.Enum
            The topic being subscribed to

        Returns
        -------

        response.HTTPResponse
            status code: 200 if the request has correctly been processed
            status code: 400 otherwise
        """
        try:
            mode = request.args['hub.mode'][0]

            if mode == 'subscribe' or mode == 'unsubscribe':
                return response.HTTPResponse(
                    body=request.args['hub.challenge'][0], status=200)

            elif mode == 'denied':
                reason = request.args.get('hub.reason', 'no reason')
                log.warning(
                    f'{topic.name} webhook subscribe request denied ({request.args}) , reason: {reason}.'
                )

            return response.HTTPResponse(status=200)

        except KeyError:
            return response.HTTPResponse(status=400)
Beispiel #27
0
 async def route_wrapper(self, route, req, context, request_args,
                         request_kw, *decorator_args, **decorator_kw):
     _ = decorator_kw.pop('with_context')  # ignore this.
     _options = decorator_kw
     options = get_cors_options(context.app, _options)
     if options.get('automatic_options') and req.method == 'OPTIONS':
         resp = response.HTTPResponse()
     else:
         resp = route(req, *request_args, **request_kw)
         if resp is not None:
             while isawaitable(resp):
                 resp = await resp
     if resp is not None:
         request_context = context.request[id(req)]
         set_cors_headers(req, resp, context, options)
         request_context[SANIC_CORS_EVALUATED] = "1"
     return resp
Beispiel #28
0
async def update_user(request, *args, **kwargs):
    if request.json is None:
        raise InvalidUsage("invalid payload (empty payload not allowed)")
    try:
        requested_user_id = int(request.path.split("/")[2])
    except ValueError as e:
        raise InvalidUsage(e)

    user_from_token = retrieve_user(request, args, kwargs)
    if user_from_token is None:
        raise InvalidUsage("invalid parameter (maybe expired?)")

    if (
        "admin" not in user_from_token.scopes
        and "manager" not in user_from_token.scopes
    ):
        if requested_user_id != user_from_token.user_id:
            raise Forbidden(f"user can only update self")

    user = User.get_by_user_id(requested_user_id)
    if not user:
        raise InvalidUsage("invalid parameter")

    if (
        "manager" in user_from_token.scopes
        and "admin" not in user_from_token.scopes
        and ("manager" in user.scopes or "admin" in user.scopes)
    ):
        if requested_user_id != user_from_token.user_id:
            raise Forbidden(f"manager can only update manager")

    if "password" in request.json:
        password = request.json["password"]
        if not password_validator(password):
            raise InvalidUsage("password does not match minimum requirements")

        user.update_password(encrypt(password))
    if "email" in request.json:
        user.update_email(request.json["email"])
    if "name" in request.json:
        user.update_name(request.json["name"])

    user.save(modifying_user_id=user_from_token.user_id)

    return response.HTTPResponse(status=204)
Beispiel #29
0
async def download_main_file(request, user):
    obj = Object(app.client.energy_db.objects)

    res, err = await obj.select({'_id': ObjectId(request.json['object_id'])},
                                {request.json['object_key']: True})
    if err:
        raise ObjectException(err)

    return response.HTTPResponse(
        status=200,
        headers={
            "Content-Disposition":
            'attachment; filename="{0}"'.format(
                res[0][request.json['object_key']]['filename'])
        },
        content_type=res[0][request.json['object_key']]['type'],
        body_bytes=res[0][request.json['object_key']]['content'],
    )
Beispiel #30
0
async def mark_as_uploaded(request, asset_id):
    if (request.json != {'Status': 'uploaded'}):
        return response.json(
            {
                'message':
                'Expected JSON with the contents: {"Status": "uploaded"}.'
            },
            status=400)

    in_cache = await is_asset_in_cache(asset_id)
    if not in_cache:
        return response.json({'message': 'Asset ID not found.'}, status=404)

    app.cache[asset_id] = 'UPLOADED'
    await app.redis.execute('set', asset_id, 'UPLOADED')
    logging.info('Cache state: {}.'.format(app.cache))

    return response.HTTPResponse(status=200)