Пример #1
0
    async def __call__(self):
        registry = await get_registry()
        settings = registry.for_interface(IImagingSettings)
        scale_name = self.request.matchdict["scale"]
        allowed_sizes = settings["allowed_sizes"]
        if scale_name not in allowed_sizes:
            raise HTTPNotFound(
                content={"reason": f"{scale_name} is not supported"})

        file = self.field.get(self.field.context or self.context)
        if file is None:
            raise HTTPNotFound(
                content={
                    "message": "File or custom filename required to download"
                })

        if hasattr(
                file, "previews"
        ) and file.previews is not None and scale_name in file.previews:
            new_field = CloudPreviewImageFileField(
                __name__=scale_name, file=file).bind(self.behavior
                                                     or self.context)
            adapter = get_multi_adapter(
                (self.context, self.request, new_field), IFileManager)
            return await adapter.download()
        else:
            return HTTPNoContent()
Пример #2
0
async def cancel_task(context, request):
    task_prefix = get_task_id_prefix()
    if not request.matchdict["task_id"].startswith(task_prefix):
        return HTTPNotFound(content={"reason": "Task not found"})
    task = TaskState(request.matchdict["task_id"])
    try:
        return await task.cancel()
    except TaskNotFoundException:
        return HTTPNotFound(content={"reason": "Task not found"})
Пример #3
0
async def info_task(context, request):
    task_prefix = get_task_id_prefix()
    if not request.matchdict['task_id'].startswith(task_prefix):
        return HTTPNotFound(content={'reason': 'Task not found'})
    try:
        task = TaskState(request.matchdict['task_id'])
        return await task.get_state()
    except TaskNotFoundException:
        return HTTPNotFound(content={'reason': 'Task not found'})
Пример #4
0
    async def preflight(self):
        """We need to check if there is cors enabled and is valid."""
        headers = {}

        renderer = app_settings['cors_renderer'](self.request)
        settings = await renderer.get_settings()

        if not settings:
            return {}

        origin = self.request.headers.get('Origin', None)
        if not origin:
            raise HTTPNotFound(content={
                'message': 'Origin this header is mandatory'
            })

        requested_method = self.getRequestMethod()
        if not requested_method:
            raise HTTPNotFound(content={
                'text': 'Access-Control-Request-Method this header is mandatory'
            })

        requested_headers = (
            self.request.headers.get('Access-Control-Request-Headers', ()))

        if requested_headers:
            requested_headers = map(str.strip, requested_headers.split(', '))

        requested_method = requested_method.upper()
        allowed_methods = settings['allow_methods']
        if requested_method not in allowed_methods:
            raise HTTPMethodNotAllowed(
                requested_method, allowed_methods,
                content={
                    'message': 'Access-Control-Request-Method Method not allowed'
                })

        supported_headers = settings['allow_headers']
        if '*' not in supported_headers and requested_headers:
            supported_headers = [s.lower() for s in supported_headers]
            for h in requested_headers:
                if not h.lower() in supported_headers:
                    raise HTTPUnauthorized(content={
                        'text': 'Access-Control-Request-Headers Header %s not allowed' % h
                    })

        supported_headers = [] if supported_headers is None else supported_headers
        requested_headers = [] if requested_headers is None else requested_headers

        supported_headers = set(supported_headers) | set(requested_headers)

        headers['Access-Control-Allow-Headers'] = ','.join(supported_headers)
        headers['Access-Control-Allow-Methods'] = ','.join(settings['allow_methods'])
        headers['Access-Control-Max-Age'] = str(settings['max_age'])
        return headers
Пример #5
0
async def get_field_value(context, request):
    field_name = request.matchdict["dotted_name"]

    if "." in field_name:
        # behavior field lookup
        iface_dotted = ".".join(field_name.split(".")[:-1])
        field_name = field_name.split(".")[-1]

        try:
            schema = resolve_dotted_name(iface_dotted)
        except ModuleNotFoundError:
            return HTTPNotFound(
                content={"reason": f"Could resolve: {iface_dotted}"})
        try:
            field = schema[field_name]
        except KeyError:
            return HTTPNotFound(content={"reason": f"No field: {field_name}"})

        try:
            behavior = await get_behavior(context, schema)
        except AttributeError:
            return HTTPNotFound(
                content={"reason": f"Could not load behavior: {iface_dotted}"})
        if behavior is None:
            return HTTPNotFound(
                content={"reason": f"Not valid behavior: {iface_dotted}"})
        field = field.bind(behavior)
        field_context = behavior
    else:
        # main object field
        factory = get_cached_factory(context.type_name)
        schema = factory.schema
        try:
            field = schema[field_name]
        except KeyError:
            return HTTPNotFound(content={"reason": f"No field: {field_name}"})
        field = field.bind(context)
        field_context = context

    # check permission
    read_permissions = merged_tagged_value_dict(schema, read_permission.key)
    serializer = get_multi_adapter((context, request),
                                   IResourceSerializeToJson)

    if not serializer.check_permission(read_permissions.get(field_name)):
        return HTTPUnauthorized(
            content={"reason": "You are not authorized to render this field"})

    field_renderer = query_multi_adapter((context, request, field),
                                         IFieldValueRenderer)
    if field_renderer is None:
        return await serializer.serialize_field(field_context, field)
    else:
        return await field_renderer()
Пример #6
0
async def resolve_uid(context, request):
    uid = request.matchdict['uid']
    ob = await get_object_by_oid(uid)
    if ob is None:
        return HTTPNotFound(content={'reason': f'Could not find uid: {uid}'})
    interaction = IInteraction(request)
    if interaction.check_permission('guillotina.AccessContent', ob):
        return HTTPMovedPermanently(get_object_url(ob, request))
    else:
        # if a user doesn't have access to it, they shouldn't know anything about it
        return HTTPNotFound(content={'reason': f'Could not find uid: {uid}'})
Пример #7
0
async def resolve_uid(context, request):
    uid = request.matchdict["uid"]
    try:
        ob = await get_object_by_uid(uid)
    except KeyError:
        return HTTPNotFound(content={"reason": f"Could not find uid: {uid}"})
    policy = get_security_policy()
    if policy.check_permission("guillotina.AccessContent", ob):
        return HTTPMovedPermanently(get_object_url(ob, request))
    else:
        # if a user doesn't have access to it, they shouldn't know anything about it
        return HTTPNotFound(content={"reason": f"Could not find uid: {uid}"})
Пример #8
0
async def info_task(context, request):
    task_prefix = get_task_id_prefix()
    if not request.matchdict["task_id"].startswith(task_prefix):
        return HTTPNotFound(content={"reason": "Task not found"})
    try:
        task = TaskState(request.matchdict["task_id"])
        state = await task.get_state()
        if not can_debug_amqp(context):
            state.pop("job_data", None)
        return state
    except TaskNotFoundException:
        return HTTPNotFound(content={"reason": "Task not found"})
Пример #9
0
    async def prepare(self):
        # we want have the field
        name = self.request.matchdict["field_name"]
        fti = query_utility(IFactory, name=self.context.type_name)
        schema = fti.schema
        field = None
        self.behavior = None
        if name in schema:
            field = schema[name]

        else:
            # TODO : We need to optimize and move to content.py iterSchema
            for behavior_schema in fti.behaviors or ():
                if name in behavior_schema:
                    field = behavior_schema[name]
                    self.behavior = behavior_schema(self.context)
                    break
            for behavior_name in self.context.__behaviors__ or ():
                behavior_schema = BEHAVIOR_CACHE[behavior_name]
                if name in behavior_schema:
                    field = behavior_schema[name]
                    self.behavior = behavior_schema(self.context)
                    break

        # Check that its a File Field
        if field is None:
            raise HTTPNotFound(content={"reason": "No valid name"})

        if self.behavior is not None:
            ctx = self.behavior
        else:
            ctx = self.context

        if self.behavior is not None and IAsyncBehavior.implementedBy(
                self.behavior.__class__):
            # providedBy not working here?
            await self.behavior.load()

        if IDict.providedBy(field) and ICloudFileField.providedBy(
                field.value_type):
            key = self.request.matchdict.get("file_key")
            if key is not None:
                self.field = CloudFileField(__name__=name).bind(
                    DictFieldProxy(key, ctx, name))
        elif ICloudFileField.providedBy(field):
            self.field = field.bind(ctx)

        if self.field is None:
            raise HTTPNotFound(content={"reason": "No valid name"})

        return self
Пример #10
0
    async def preflight(self):
        """We need to check if there is cors enabled and is valid."""
        headers = {}

        renderer = app_settings["cors_renderer"](self.request)
        settings = await renderer.get_settings()

        if not settings:
            return {}

        origin = self.request.headers.get("Origin", None)
        if not origin:
            raise HTTPNotFound(content={"message": "Origin this header is mandatory"})

        requested_method = self.getRequestMethod()
        if not requested_method:
            raise HTTPNotFound(content={"text": "Access-Control-Request-Method this header is mandatory"})

        requested_headers = self.request.headers.get("Access-Control-Request-Headers", ())

        if requested_headers:
            requested_headers = map(str.strip, requested_headers.split(", "))

        requested_method = requested_method.upper()
        allowed_methods = settings["allow_methods"]
        if requested_method not in allowed_methods:
            raise HTTPMethodNotAllowed(
                requested_method,
                allowed_methods,
                content={"message": "Access-Control-Request-Method Method not allowed"},
            )

        supported_headers = settings["allow_headers"]
        if "*" not in supported_headers and requested_headers:
            supported_headers = [s.lower() for s in supported_headers]
            for h in requested_headers:
                if not h.lower() in supported_headers:
                    raise HTTPUnauthorized(
                        content={"text": "Access-Control-Request-Headers Header %s not allowed" % h}
                    )

        supported_headers = [] if supported_headers is None else supported_headers
        requested_headers = [] if requested_headers is None else requested_headers

        supported_headers = set(supported_headers) | set(requested_headers)

        headers["Access-Control-Allow-Headers"] = ",".join(supported_headers)
        headers["Access-Control-Allow-Methods"] = ",".join(settings["allow_methods"])
        headers["Access-Control-Max-Age"] = str(settings["max_age"])
        return headers
Пример #11
0
    async def __call__(self):
        registry = await get_registry()
        settings = registry.for_interface(IImagingSettings)
        scale_name = self.request.matchdict["scale"]
        allowed_sizes = settings["allowed_sizes"]
        if scale_name not in allowed_sizes:
            raise HTTPNotFound(
                content={"reason": f"{scale_name} is not supported"})
        file = self.field.get(self.field.context or self.context)
        if file is None:
            raise HTTPNotFound(
                content={
                    "message": "File or custom filename required to download"
                })

        adapter = get_multi_adapter((self.context, self.request, self.field),
                                    IFileManager)
        data = b""
        async for chunk in adapter.iter_data():
            data += chunk

        width, _, height = allowed_sizes[scale_name].partition(":")

        result, format_, size = scaleImage(
            data,
            int(width),
            int(height),
            quality=settings["quality"],
            direction="thumbnail",
        )

        cors_renderer = app_settings["cors_renderer"](self.request)
        headers = await cors_renderer.get_headers()
        headers.update({
            "CONTENT-DISPOSITION":
            'attachment; filename="{}"'.format(file.filename)
        })

        download_resp = Response(
            status=200,
            headers=headers,
            content_type=f"image/{format_}",
            content_length=len(result),
        )
        await download_resp.prepare(self.request)

        await download_resp.write(result)
        await download_resp.write(eof=True)
        return download_resp
Пример #12
0
async def get_block_schema(context, request):
    key = request.matchdict["key"]
    vocabulary_registry = getVocabularyRegistry()
    try:
        vocab = vocabulary_registry.get(context, key)
    except VocabularyRegistryError:
        return HTTPNotFound()

    title_filter = request.query.get("title")
    if title_filter:
        title_filter = title_filter.lower()
    token_filter = request.query.get("token")
    if token_filter:
        token_filter = token_filter.lower()

    result = {}
    result["@id"] = join(IAbsoluteURL(context)(), "@vocabularies", key)
    result["items"] = []
    for term in vocab.keys():
        if token_filter and token_filter not in str(term).lower():
            continue
        new_title = vocab.getTerm(term)
        if title_filter and title_filter not in str(new_title).lower():
            continue
        result["items"].append({"title": new_title, "token": term})
    result["items_total"] = len(result["items"])
    return result
Пример #13
0
 async def __call__(self):
     if app_settings.get("graphql", {}).get("enable_playground") is True:
         return Response(
             content=PLAYGROUND_HTML,
             headers={"content-type": "text/html"},
         )
     raise HTTPNotFound()
Пример #14
0
    async def download(self,
                       disposition=None,
                       filename=None,
                       content_type=None,
                       size=None,
                       **kwargs):
        if disposition is None:
            disposition = self.request.query.get('disposition', 'attachment')

        file = self.field.get(self.field.context or self.context)
        if file is None and filename is None:
            raise HTTPNotFound(
                content={
                    'message': 'File or custom filename required to download'
                })
        cors_renderer = app_settings['cors_renderer'](self.request)
        headers = await cors_renderer.get_headers()
        headers.update({
            'CONTENT-DISPOSITION':
            '{}; filename="{}"'.format(disposition, filename or file.filename)
        })

        download_resp = StreamResponse(headers=headers)
        download_resp.content_type = content_type or file.guess_content_type()
        if size or file.size:
            download_resp.content_length = size or file.size

        await download_resp.prepare(self.request)

        async for chunk in self.file_storage_manager.iter_data(**kwargs):
            await download_resp.write(chunk)
            await download_resp.drain()
        await download_resp.write_eof()
        return download_resp
Пример #15
0
    async def prepare_download(self, disposition=None, filename=None,
                               content_type=None, size=None, **kwargs):
        if disposition is None:
            disposition = self.request.query.get('disposition', 'attachment')

        try:
            file = self.field.get(self.field.context or self.context)
        except AttributeError:
            file = None

        if file is None and filename is None:
            raise HTTPNotFound(content={
                'message': 'File or custom filename required to download'
            })
        cors_renderer = app_settings['cors_renderer'](self.request)
        headers = await cors_renderer.get_headers()
        headers.update({
            'Content-Disposition': '{}; filename="{}"'.format(
                disposition, filename or file.filename)
        })

        download_resp = StreamResponse(headers=headers)
        download_resp.content_type = content_type or file.guess_content_type()
        if size or file.size:
            download_resp.content_length = size or file.size

        await download_resp.prepare(self.request)
        return download_resp
Пример #16
0
 async def head(self,
                disposition=None,
                filename=None,
                content_type=None,
                size=None,
                extra_headers=None,
                **kwargs):
     try:
         if hasattr(self.file_storage_manager, "exists"):
             # does not need to implement but can be a way to verify
             # file exists on cloud platform still
             if not await apply_coroutine(self.file_storage_manager.exists):
                 raise HTTPNotFound(
                     content={"message": "File object does not exist"})
         download_resp = await self.prepare_download(
             disposition, filename, content_type, size, extra_headers,
             **kwargs)
         await download_resp.write(eof=True)
     except (ConnectionRefusedError,
             ConnectionResetError):  # pragma: no cover
         logger.info(f"Head cancelled: {self.request}")
         # when supporting range headers, the browser will
         # cancel downloads. This is fine.
         raise HTTPClientClosedRequest()
     return download_resp
Пример #17
0
 async def prepare(self):
     # we want have the key of the registry
     self.key = self.request.matchdict['key']
     self.value = self.request.container_settings.get(self.key, _marker)
     if self.value is _marker:
         raise HTTPNotFound(
             content={'message': f'{self.key} not in settings'})
Пример #18
0
    async def __call__(self):
        data = await self.request.json()
        if '@type' not in data or data['@type'] not in app_settings[
                'container_types']:
            raise HTTPNotFound(
                content={
                    'message': 'can not create this type %s' % data['@type']
                })

        if 'id' not in data:
            raise HTTPPreconditionFailed(content={'message': 'We need an id'})

        if not data.get('title'):
            data['title'] = data['id']

        if 'description' not in data:
            data['description'] = ''

        value = await self.context.async_contains(data['id'])

        if value:
            # Already exist
            raise HTTPConflict(
                content={'message': 'Container with id already exists'})

        install_addons = data.pop('@addons', None) or []
        for addon in install_addons:
            # validate addon list
            if addon not in app_settings['available_addons']:
                return ErrorResponse(
                    'RequiredParam',
                    "Property '@addons' must refer to a valid addon",
                    status=412,
                    reason=error_reasons.INVALID_ID)

        owner_id = get_authenticated_user_id(self.request)

        container = await create_container(self.context,
                                           data.pop('id'),
                                           container_type=data.pop('@type'),
                                           owner_id=owner_id,
                                           **data)
        self.request._container_id = container.__name__
        self.request.container = container

        annotations_container = get_adapter(container, IAnnotations)
        self.request.container_settings = await annotations_container.async_get(
            REGISTRY_DATA_KEY)

        for addon in install_addons:
            await addons.install(container, addon)

        resp = {
            '@type': container.type_name,
            'id': container.id,
            'title': data['title']
        }
        headers = {'Location': posixpath.join(self.request.path, container.id)}

        return Response(content=resp, headers=headers)
Пример #19
0
 async def prepare(self):
     type_id = self.request.matchdict["type_id"]
     self.value = queryUtility(IResourceFactory, name=type_id)
     if self.value is None:
         raise HTTPNotFound(
             content={"reason": f"Could not find type {type_id}", "type": type_id}
         )
Пример #20
0
    async def __call__(self):
        data = await self.request.json()
        if "@type" not in data or data["@type"] not in app_settings[
                "container_types"]:
            raise HTTPNotFound(
                content={
                    "message": "can not create this type %s" % data["@type"]
                })

        if "id" not in data:
            raise HTTPPreconditionFailed(content={"message": "We need an id"})

        if not data.get("title"):
            data["title"] = data["id"]

        if "description" not in data:
            data["description"] = ""

        value = await self.context.async_contains(data["id"])

        if value:
            # Already exist
            raise HTTPConflict(
                content={"message": "Container with id already exists"})

        install_addons = data.pop("@addons", None) or []
        for addon in install_addons:
            # validate addon list
            if addon not in app_settings["available_addons"]:
                return ErrorResponse(
                    "RequiredParam",
                    "Property '@addons' must refer to a valid addon",
                    status=412,
                    reason=error_reasons.INVALID_ID,
                )

        owner_id = get_authenticated_user_id()

        container = await create_container(self.context,
                                           data.pop("id"),
                                           container_type=data.pop("@type"),
                                           owner_id=owner_id,
                                           **data)
        task_vars.container.set(container)

        annotations_container = get_adapter(container, IAnnotations)
        task_vars.registry.set(
            await annotations_container.async_get(REGISTRY_DATA_KEY))

        for addon in install_addons:
            await addons.install(container, addon)

        resp = {
            "@type": container.type_name,
            "id": container.id,
            "title": data["title"]
        }
        headers = {"Location": posixpath.join(self.request.path, container.id)}

        return Response(content=resp, headers=headers)
Пример #21
0
    async def __call__(self):
        data = await self.request.json()
        if '@type' not in data or data['@type'] not in app_settings[
                'container_types']:
            raise HTTPNotFound(
                content={
                    'message': 'can not create this type %s' % data['@type']
                })

        if 'id' not in data:
            raise HTTPPreconditionFailed(content={'message': 'We need an id'})

        if not data.get('title'):
            data['title'] = data['id']

        if 'description' not in data:
            data['description'] = ''

        value = await self.context.async_contains(data['id'])

        if value:
            # Already exist
            raise HTTPConflict(
                content={'message': 'Container with id already exists'})

        container = await create_content(data['@type'],
                                         id=data['id'],
                                         title=data['title'],
                                         description=data['description'])

        # Special case we don't want the parent pointer
        container.__name__ = data['id']

        await self.context.async_set(data['id'], container)
        await container.install()

        self.request._container_id = container.__name__
        self.request.container = container

        user = get_authenticated_user_id(self.request)

        # Local Roles assign owner as the creator user
        roleperm = IPrincipalRoleManager(container)
        roleperm.assign_role_to_principal('guillotina.Owner', user)

        await notify(
            ObjectAddedEvent(container,
                             self.context,
                             container.__name__,
                             payload=data))

        resp = {
            '@type': data['@type'],
            'id': data['id'],
            'title': data['title']
        }
        headers = {'Location': posixpath.join(self.request.path, data['id'])}

        return Response(content=resp, headers=headers)
Пример #22
0
 async def prepare(self):
     # we want have the key of the registry
     self.key = self.request.matchdict["key"]
     registry = await get_registry(self.context)
     self.value = registry.get(self.key, _marker)
     if self.value is _marker:
         raise HTTPNotFound(
             content={"message": f"{self.key} not in settings"})
Пример #23
0
 async def prepare(self):
     type_name = self.request.matchdict['type_name']
     self.value = query_utility(IResourceFactory, name=type_name)
     if self.value is None:
         raise HTTPNotFound(content={
             'reason': f'Could not find type {type_name}',
             'type_name': type_name
         })
Пример #24
0
async def get_block_schema(context, request):
    key = request.matchdict['key']
    if key not in app_settings['available_blocks'].keys():
        return HTTPNotFound()
    block = app_settings['available_blocks'][key]
    schema = resolve_dotted_name(block['schema'])
    serializer = get_multi_adapter((schema, request), ISchemaSerializeToJson)
    return await serializer()
Пример #25
0
async def storage_get(context, request):
    storage_id = request.matchdict["storage_id"]
    config = _get_storage_config(storage_id)
    if config is None:
        raise HTTPNotFound(content={"reason": f"Storage {storage_id}"})
    manager = config.get("type", config["storage"])
    factory = get_adapter(context, IDatabaseManager, name=manager, args=[config])
    return {"id": storage_id, "type": config["storage"], "databases": await factory.get_names()}
Пример #26
0
    async def __call__(self):
        settings = self.request.container_settings.for_interface(
            IImagingSettings)
        scale_name = self.request.matchdict['scale']
        allowed_sizes = settings['allowed_sizes']
        if scale_name not in allowed_sizes:
            raise HTTPNotFound(
                content={'reason': f'{scale_name} is not supported'})
        file = self.field.get(self.field.context or self.context)
        if file is None:
            raise HTTPNotFound(
                content={
                    'message': 'File or custom filename required to download'
                })

        adapter = get_multi_adapter((self.context, self.request, self.field),
                                    IFileManager)
        data = b''
        async for chunk in adapter.iter_data():
            data += chunk

        width, _, height = allowed_sizes[scale_name].partition(':')

        result, format_, size = scaleImage(data,
                                           int(width),
                                           int(height),
                                           quality=settings['quality'],
                                           direction='thumbnail')

        cors_renderer = app_settings['cors_renderer'](self.request)
        headers = await cors_renderer.get_headers()
        headers.update({
            'CONTENT-DISPOSITION':
            'attachment; filename="{}"'.format(file.filename)
        })

        download_resp = StreamResponse(headers=headers)
        download_resp.content_type = f'image/{format_}'
        if file.size:
            download_resp.content_length = len(result)

        await download_resp.prepare(self.request)
        await download_resp.write(result)
        await download_resp.drain()
        await download_resp.write_eof()
        return download_resp
Пример #27
0
async def delete_db(context, request):
    storage_id = request.matchdict["storage_id"]
    config = _get_storage_config(storage_id)
    if config is None:
        raise HTTPNotFound(content={"reason": f"Storage {storage_id}"})
    manager = config.get("type", config["storage"])
    factory = get_adapter(context, IDatabaseManager, name=manager, args=[config])
    assert request.matchdict["db_id"] in await factory.get_names()
    await factory.delete(request.matchdict["db_id"])
Пример #28
0
    async def iter_data(self, uri=None, headers=None):
        if uri is None:
            file = self.field.get(self.field.context or self.context)
            if not _is_uploaded_file(file):
                raise FileNotFoundException(
                    "Trying to iterate data with no file")
            else:
                uri = file.uri

        if headers is None:
            headers = {}

        util = get_utility(IGCloudBlobStore)
        url = "{}/{}/o/{}".format(OBJECT_BASE_URL, await
                                  util.get_bucket_name(), quote_plus(uri))
        headers["AUTHORIZATION"] = "Bearer {}".format(await
                                                      util.get_access_token())
        async with util.session.get(url,
                                    headers=headers,
                                    params={"alt": "media"},
                                    timeout=-1) as api_resp:
            if api_resp.status not in (200, 206):
                text = await api_resp.text()
                if api_resp.status == 404:
                    raise HTTPNotFound(
                        content={
                            "reason": "Google cloud file not found",
                            "response": text,
                        })
                elif api_resp.status == 401:
                    log.warning(
                        f"Invalid google cloud credentials error: {text}")
                    raise HTTPNotFound(
                        content={
                            "reason": "Google cloud invalid credentials",
                            "response": text,
                        })
                raise GoogleCloudException(f"{api_resp.status}: {text}")
            while True:
                chunk = await api_resp.content.read(1024 * 1024)
                if len(chunk) > 0:
                    yield chunk
                else:
                    break
Пример #29
0
    async def copy(self, to_storage_manager, to_dm):
        file = self.field.get(self.field.context or self.context)
        if not _is_uploaded_file(file):
            raise HTTPNotFound(
                content={"reason": "To copy a uri must be set on the object"})
        generator = get_multi_adapter((self.context, self.field),
                                      IFileNameGenerator)
        new_uri = await apply_coroutine(generator)

        util = get_utility(IGCloudBlobStore)
        bucket_name = await util.get_bucket_name()
        url = "{}/{}/o/{}/copyTo/b/{}/o/{}".format(
            OBJECT_BASE_URL,
            bucket_name,
            quote_plus(file.uri),
            bucket_name,
            quote_plus(new_uri),
        )
        async with util.session.post(
                url,
                headers={
                    "AUTHORIZATION":
                    "Bearer {}".format(await util.get_access_token()),
                    "Content-Type": "application/json",
                },
        ) as resp:
            if resp.status == 404:
                text = await resp.text()
                reason = (
                    f"Could not copy file: {file.uri} to {new_uri}:404: {text}"  # noqa
                )
                log.warning(reason)
                raise HTTPNotFound(content={"reason": reason})
            else:
                data = await resp.json()
                assert data["name"] == new_uri
                await to_dm.finish(
                    values={
                        "content_type": data["contentType"],
                        "size": int(data["size"]),
                        "uri": new_uri,
                        "filename": file.filename or "unknown",
                    })
Пример #30
0
    async def get_user(self) -> User:
        user_id: str = self.request.matchdict["user"]
        try:
            user = await navigate_to(self.context, "users/{}".format(user_id))
        except KeyError:
            user = None

        if user is None:
            raise HTTPNotFound(content={"reason": f"User {user_id} not found"})
        return user