示例#1
0
async def import_project(request: web.Request):
    # bumping this requests's max size
    # pylint: disable=protected-access
    exporter_settings = get_plugin_settings(request.app)
    assert (  # nosec
        exporter_settings is not None
    ), "this call was not expected with a disabled plugin"  # nosec

    request._client_max_size = exporter_settings.EXPORTER_MAX_UPLOAD_FILE_SIZE * ONE_GB

    post_contents = await request.post()
    log.info("POST body %s", post_contents)
    user_id = request[RQT_USERID_KEY]
    file_name_field: FileField = post_contents.get("fileName", None)

    if file_name_field is None:
        raise ExporterException("Expected a file as 'fileName' form parmeter")
    if not isinstance(file_name_field, FileField):
        raise ExporterException("Please select a file")

    temp_dir: str = await get_empty_tmp_dir()

    imported_project_uuid = await study_import(app=request.app,
                                               temp_dir=temp_dir,
                                               file_field=file_name_field,
                                               user_id=user_id)
    await remove_dir(directory=temp_dir)

    return dict(uuid=imported_project_uuid)
示例#2
0
    async def _command_proxy(
            self, path: str,
            request: web.Request) -> web.Response | web.StreamResponse:
        """Return a client request with proxy origin for Hass.io supervisor.

        This method is a coroutine.
        """
        read_timeout = _get_timeout(path)
        client_timeout = 10
        data = None
        headers = _init_header(request)
        if path == "snapshots/new/upload":
            # We need to reuse the full content type that includes the boundary
            headers["Content-Type"] = request._stored_content_type  # pylint: disable=protected-access

            # Snapshots are big, so we need to adjust the allowed size
            request._client_max_size = (  # pylint: disable=protected-access
                MAX_UPLOAD_SIZE)
            client_timeout = 300

        try:
            with async_timeout.timeout(client_timeout):
                data = await request.read()

            method = getattr(self._websession, request.method.lower())
            client = await method(
                f"http://{self._host}/{path}",
                data=data,
                headers=headers,
                timeout=read_timeout,
            )

            # Simple request
            if int(client.headers.get(CONTENT_LENGTH, 0)) < 4194000:
                # Return Response
                body = await client.read()
                return web.Response(content_type=client.content_type,
                                    status=client.status,
                                    body=body)

            # Stream response
            response = web.StreamResponse(status=client.status,
                                          headers=client.headers)
            response.content_type = client.content_type

            await response.prepare(request)
            async for data in client.content.iter_chunked(4096):
                await response.write(data)

            return response

        except aiohttp.ClientError as err:
            _LOGGER.error("Client error on api %s request %s", path, err)

        except asyncio.TimeoutError:
            _LOGGER.error("Client timeout error on API request %s", path)

        raise HTTPBadGateway()
示例#3
0
    async def post(self, request: web.Request) -> web.Response:
        """Handle upload."""
        if not request["hass_user"].is_admin:
            raise Unauthorized()

        # Increase max payload
        request._client_max_size = MAX_UPLOAD_SIZE  # pylint: disable=protected-access

        try:
            data = self.schema(dict(await request.post()))
        except vol.Invalid as err:
            LOGGER.error("Received invalid upload data: %s", err)
            raise web.HTTPBadRequest() from err

        try:
            item = MediaSourceItem.from_uri(self.hass,
                                            data["media_content_id"])
        except ValueError as err:
            LOGGER.error("Received invalid upload data: %s", err)
            raise web.HTTPBadRequest() from err

        try:
            source_dir_id, location = self.source.async_parse_identifier(item)
        except Unresolvable as err:
            LOGGER.error("Invalid local source ID")
            raise web.HTTPBadRequest() from err

        uploaded_file: FileField = data["file"]

        if not uploaded_file.content_type.startswith(
            ("image/", "video/", "audio/")):
            LOGGER.error("Content type not allowed")
            raise vol.Invalid("Only images and video are allowed")

        try:
            raise_if_invalid_filename(uploaded_file.filename)
        except ValueError as err:
            LOGGER.error("Invalid filename")
            raise web.HTTPBadRequest() from err

        try:
            await self.hass.async_add_executor_job(
                self._move_file,
                self.source.async_full_path(source_dir_id, location),
                uploaded_file,
            )
        except ValueError as err:
            LOGGER.error("Moving upload failed: %s", err)
            raise web.HTTPBadRequest() from err

        return self.json({
            "media_content_id":
            f"{data['media_content_id']}/{uploaded_file.filename}"
        })
示例#4
0
    async def _upload_file(self, request: web.Request) -> web.Response:
        """Handle uploaded file."""
        # Increase max payload
        request._client_max_size = MAX_SIZE  # pylint: disable=protected-access

        data = await request.post()
        file_field = data.get("file")

        if not isinstance(file_field, web.FileField):
            raise vol.Invalid("Expected a file")

        try:
            raise_if_invalid_filename(file_field.filename)
        except ValueError as err:
            raise web.HTTPBadRequest from err

        hass: HomeAssistant = request.app["hass"]
        file_id = ulid_hex()

        if DOMAIN not in hass.data:
            hass.data[DOMAIN] = await FileUploadData.create(hass)

        file_upload_data: FileUploadData = hass.data[DOMAIN]
        file_dir = file_upload_data.file_dir(file_id)

        def _sync_work() -> None:
            file_dir.mkdir()

            # MyPy forgets about the isinstance check because we're in a function scope
            assert isinstance(file_field, web.FileField)

            with (file_dir / file_field.filename).open("wb") as target_fileobj:
                shutil.copyfileobj(file_field.file, target_fileobj)

        await hass.async_add_executor_job(_sync_work)

        file_upload_data.files[file_id] = file_field.filename

        return self.json({"file_id": file_id})
示例#5
0
文件: api.py 项目: MatthiasLohr/core
    async def post(self, request: web.Request, config_entry_id: str,
                   node_id: str) -> web.Response:
        """Handle upload."""
        if not request["hass_user"].is_admin:
            raise Unauthorized()
        hass = request.app["hass"]
        if config_entry_id not in hass.data[DOMAIN]:
            raise web_exceptions.HTTPBadRequest

        entry = hass.config_entries.async_get_entry(config_entry_id)
        client: Client = hass.data[DOMAIN][config_entry_id][DATA_CLIENT]
        node = client.driver.controller.nodes.get(int(node_id))
        if not node:
            raise web_exceptions.HTTPNotFound

        # Increase max payload
        request._client_max_size = 1024 * 1024 * 10  # pylint: disable=protected-access

        data = await request.post()

        if "file" not in data or not isinstance(data["file"],
                                                web_request.FileField):
            raise web_exceptions.HTTPBadRequest

        uploaded_file: web_request.FileField = data["file"]

        try:
            await begin_firmware_update(
                entry.data[CONF_URL],
                node,
                uploaded_file.filename,
                await hass.async_add_executor_job(uploaded_file.file.read),
                async_get_clientsession(hass),
            )
        except BaseZwaveJSServerError as err:
            raise web_exceptions.HTTPBadRequest from err

        return self.json(None)
示例#6
0
    async def mainHandler(self, WebRequest: Request,
                          handler: Callable) -> Response or StreamResponse:
        if WebRequest.match_info.get("x", "") == "import":
            # import files can be giants
            WebRequest._client_max_size = -1

        # db is about to shutdown or its currently importing
        if not self.active:
            return self.response(status=400,
                                 body=json.dumps(
                                     dict(code=400,
                                          status="rejected",
                                          msg="DB is marked as disabled")))

        # is limited to certain ip's
        if self.PhaazeDBS.allowed_ips != []:
            if WebRequest.remote not in self.PhaazeDBS.allowed_ips:
                return self.response(status=400,
                                     body=json.dumps(
                                         dict(code=400,
                                              status="rejected",
                                              msg="ip not allowed")))

        # get process method, default is json
        WebRequest.db_method: str = await self.getMethod(WebRequest)

        try:
            Resp: Response = await handler(WebRequest)
            return Resp

        except HTTPException as Http_ex:
            return self.response(body=json.dumps(
                dict(msg=Http_ex.reason, status=Http_ex.status)),
                                 status=Http_ex.status)

        except Exception as e:
            self.PhaazeDBS.Logger.error(str(e))
            return self.response(status=500)