async def test_get_content_path(container_requester): async with container_requester as requester: response, status = await requester( "POST", "/db/guillotina/", data=json.dumps({"@type": "Item", "title": "Item1", "id": "item1"}) ) assert status == 201 root = await get_root(db=requester.db) tm = requester.db.get_transaction_manager() txn = await tm.begin() container = await root.async_get("guillotina") obj = await container.async_get("item1") assert utils.get_content_path(container) == "/" assert utils.get_content_path(obj) == "/item1" await tm.abort(txn=txn)
def wrap_component(request, js_component, path_to_content, type='json'): get_context = "" if path_to_content: path_to_content = (path_to_content.startswith('/') and "/~" + path_to_content) or path_to_content get_context = """let response = await fetch('{path_to_content}'); let context = await response.{type}(); """.format(path_to_content=path_to_content, type=type) else: context = request.query.get('context', {}) get_context = """let context = {context}""".format(context=context) return """<!DOCTYPE html> <html lang="en"> <script type="module"> import Component from '/~{component}'; import Main from '/~/abfab/main.svelte.js'; {get_context} const component = new Main({{ target: document.body, props: {{context, component: Component}}, }}); export default component; </script> </html> """.format(component=get_content_path(js_component), get_context=get_context)
async def get_content_basic(context, request): return { "type_name": context.type_name, "path": get_content_path(context), "view": context.view, "data": context.data, }
async def check_content_moved(event): request = event.request try: get_current_container() except ContainerNotFound: return storage = utils.get_storage() if storage is None: return tail, _, view = '/'.join(event.tail).partition('/@') if view: view = '@' + view path = os.path.join( get_content_path(request.resource), tail) query = Query.from_(aliases_table).select( aliases_table.zoid ).where( (aliases_table.path == sqlq(path)) | (aliases_table.path == sqlq(path) + '/' + sqlq(view)) ) async with storage.pool.acquire() as conn: results = await conn.fetch(str(query)) if len(results) > 0: ob = await get_object_by_oid(results[0]['zoid']) url = get_object_url(ob) if view: url += '/' + view raise HTTPMovedPermanently(url)
async def test_contentapi_create(db, guillotina_main): async with ContentAPI(guillotina_main.root['db']) as api: container = await api.create({'@type': 'Container', 'id': 'foobar'}) await api.use_container(container) await api.create({'@type': 'Item', 'id': 'foobar'}, in_=container) item = await api.get('foobar', in_=container) assert get_content_path(item) == '/foobar'
async def get_path_query(self, resource, index_name=None, response=noop_response): if isinstance(resource, str): path = resource depth = path.count('/') + 1 else: path = get_content_path(resource) depth = get_content_depth(resource) depth += 1 response.write(b'Removing all children of %s' % path.encode('utf-8')) request = None if index_name is None: request = get_current_request() index_name = await self.get_index_name(request.container) path_query = { 'query': { 'bool': { 'must': [ ] } } } if path != '/': path_query['query']['bool']['must'].append({ 'term': {'path': path} }) path_query['query']['bool']['must'].append({ 'range': {'depth': {'gte': depth}} }) return path_query
async def test_contentapi_create(db, guillotina_main): async with ContentAPI(guillotina_main.root["db"]) as api: container = await api.create({"@type": "Container", "id": "foobar"}) await api.use_container(container) await api.create({"@type": "Item", "id": "foobar"}, in_=container) item = await api.get("foobar", in_=container) assert get_content_path(item) == "/foobar"
def get_full_content_path(request, ob): path = '/' if hasattr(request, '_db_id'): path += request._db_id + '/' if hasattr(request, 'container'): path += request.container.__name__ + '/' return '{}{}'.format(path, get_content_path(ob)).replace('//', '/').rstrip('/') # noqa
async def _test_new_deletes_are_performed_during_migration(es_requester): async with es_requester as requester: await add_content(requester) container, request, txn, tm = await setup_txn_on_container(requester) search = getUtility(ICatalogUtility) migrator = Migrator(search, container, force=True, request=request) await migrator.setup_next_index() await migrator.copy_to_next_index() await search.refresh(container, migrator.work_index_name) await search.refresh(container) num_docs = await search.get_doc_count(container, migrator.work_index_name) current_docs = await search.get_doc_count(container) assert num_docs == current_docs keys = await container.async_keys() key = random.choice(keys) ob = await container.async_get(key) keys = await ob.async_keys() key = random.choice(keys) ob = await ob.async_get(key) await search.remove(container, [( ob._p_oid, ob.type_name, get_content_path(ob) )], request=request) await search.refresh(container, migrator.work_index_name) await search.refresh(container) num_docs = await search.get_doc_count(container, migrator.work_index_name) current_count = await search.get_doc_count(container) assert num_docs == current_count
async def get_by_path( self, container, path, depth=-1, query=None, doc_type=None, size=10, scroll=None, index=None): if query is None: query = {} if not isinstance(path, str): path = get_content_path(path) if path is not None and path != '/': path_query = { 'query': { 'bool': { 'must': [{ 'match': {'path': path} }] } } } if depth > -1: query['query']['bool']['must'].append({ 'range': {'depth': {'gte': depth}} }) query = merge_dicts(query, path_query) # We need the local roles return await self.query(container, query, doc_type, size=size, scroll=scroll, index=index)
async def get_path_query(self, resource, response=noop_response): if isinstance(resource, str): path = resource depth = path.count('/') + 1 else: path = get_content_path(resource) depth = get_content_depth(resource) depth += 1 path_query = { 'query': { 'bool': { 'must': [ ] } } } if path != '/': path_query['query']['bool']['must'].append({ 'term': {'path': path} }) path_query['query']['bool']['must'].append({ 'range': {'depth': {'gte': depth}} }) return path_query
async def search(self, container: IContainer, query: ParsedQueryInfo): # type: ignore sql, arguments = self.build_query(container, query, ['id', 'zoid', 'json']) txn = get_transaction() if txn is None: raise TransactionNotFound() conn = await txn.get_connection() results = [] try: context_url = get_object_url(container) except RequestNotFound: context_url = get_content_path(container) logger.debug(f'Running search:\n{sql}\n{arguments}') for record in await conn.fetch(sql, *arguments): data = json.loads(record['json']) result = self.load_meatdata(query, data) result['@name'] = record['id'] result['@uid'] = record['zoid'] result['@id'] = data['@absolute_url'] = context_url + data['path'] results.append(result) # also do count... total = len(results) if total >= query['size'] or query['_from'] != 0: sql, arguments = self.build_count_query(container, query) logger.debug(f'Running search:\n{sql}\n{arguments}') records = await conn.fetch(sql, *arguments) total = records[0]['count'] return {'member': results, 'items_count': total}
async def get_file(context, request): if context.id.endswith(".svelte") and 'raw' not in request.query: js = await get_object_by_path(get_content_path(context) + '.js') if "text/html" in request.headers["ACCEPT"]: return wrap_component(request, js, None) else: return await view_source(js, request) return await view_source(context, request)
async def unindex_all_children(self, container, resource, index_name=None, response=noop_response): content_path = get_content_path(resource) response.write(b'Removing all children of %s' % content_path.encode('utf-8')) # use future here because this can potentially take some # time to clean up indexes, etc asyncio.ensure_future( self.call_unindex_all_children(container, index_name, content_path))
async def update_by_query(self, query, context=None, indexes=None): if indexes is None: request = get_current_request() indexes = await self.get_current_indexes(request.container) if context is not None: for index in await get_content_sub_indexes( request.container, get_content_path(context)): indexes.append(index['index']) return await self._update_by_query(query, ','.join(indexes))
async def test_get_content_path(container_requester): async with container_requester as requester: response, status = await requester('POST', '/db/guillotina/', data=json.dumps({ "@type": "Item", "title": "Item1", "id": "item1" })) assert status == 201 request = get_mocked_request(requester.db) root = await get_root(request) txn = await request._tm.begin(request) container = await root.async_get('guillotina') obj = await container.async_get('item1') assert utils.get_content_path(container) == '/' assert utils.get_content_path(obj) == '/item1' await request._tm.abort(txn=txn)
async def search_get(context, request): q = request.query.get('q') search = query_utility(ICatalogUtility) if search is None: return {'items_count': 0, 'member': []} return await search.get_by_path(container=request.container, path=get_content_path(context), query=q)
async def update_by_query(self, query, context=None, indexes=None): if indexes is None: container = get_current_container() indexes = await self.get_current_indexes(container) if context is not None: for index in await get_content_sub_indexes( container, get_content_path(context)): indexes.append(index["index"]) return await self._update_by_query(query, ",".join(indexes))
async def test_get_content_path(container_requester): async with container_requester as requester: response, status = await requester( 'POST', '/db/guillotina/', data=json.dumps({ "@type": "Item", "title": "Item1", "id": "item1" })) assert status == 201 request = get_mocked_request(requester.db) root = await get_root(request) txn = await request._tm.begin(request) container = await root.async_get('guillotina') obj = await container.async_get('item1') assert utils.get_content_path(container) == '/' assert utils.get_content_path(obj) == '/item1' await request._tm.abort(txn=txn)
def get_full_content_path(request, ob): path = "/" if hasattr(request, "_db_id"): path += request._db_id + "/" if hasattr(request, "container"): path += request.container.__name__ + "/" if IApplication.providedBy(ob): return path return ("{}{}".format(path, get_content_path(ob)).replace("//", "/").rstrip("/"))
def __call__(self): """ access_users and access_roles """ return { 'path': get_content_path(self.content), 'depth': get_content_depth(self.content), 'parent_uuid': getattr( getattr(self.content, '__parent__', None), 'uuid', None), 'access_users': get_principals_with_access_content(self.content), 'access_roles': get_roles_with_access_content(self.content), 'type_name': self.content.type_name }
async def get_tree(context, request, depth=3): children = [] depth = depth - 1 async for _, obj in context.async_items(): data = {"type": obj.type_name, "path": get_content_path(obj)} if obj.type_name == 'Directory': if depth > 0: data["children"] = await get_tree(obj, request, depth) else: data["not_loaded"] = True children.append(data) return children
async def _query(self, context: IResource, query: ParsedQueryInfo, unrestricted: bool = False): sql, arguments = self.build_query(context, query, ["id", "zoid", "json"], unrestricted=unrestricted) txn = get_current_transaction() conn = await txn.get_connection() results = [] fullobjects = query["fullobjects"] container = find_container(context) if container is None: raise ContainerNotFound() try: context_url = get_object_url(container) request = get_current_request() except RequestNotFound: context_url = get_content_path(container) request = None logger.debug(f"Running search:\n{sql}\n{arguments}") async with txn.lock: records = await conn.fetch(sql, *arguments) for record in records: data = json.loads(record["json"]) if fullobjects and request is not None and txn is not None: # Get Object obj = await txn.get(data["uuid"]) # Serialize object view = DefaultGET(obj, request) result = await view() else: result = self.load_meatdata(query, data) result["@name"] = record["id"] result["@uid"] = record["zoid"] result["@id"] = data[ "@absolute_url"] = context_url + data["path"] results.append(result) # also do count... total = len(results) if total >= query["size"] or query["_from"] != 0: sql, arguments = self.build_count_query(context, query, unrestricted=unrestricted) logger.debug(f"Running search:\n{sql}\n{arguments}") async with txn.lock: records = await conn.fetch(sql, *arguments) total = records[0]["count"] return {"items": results, "items_total": total}
def __call__(self): """ access_users and access_roles """ return { "path": get_content_path(self.content), "depth": get_content_depth(self.content), "parent_uuid": getattr(getattr(self.content, "__parent__", None), "uuid", None), "access_users": get_principals_with_access_content(self.content), "access_roles": get_roles_with_access_content(self.content), "type_name": self.content.type_name, "tid": self.content.__serial__, "modification_date": json_compatible(self.content.modification_date), }
async def get_all_files(context, request): children = [] async for _, obj in context.async_items(): children.append({ "type": obj.type_name, "url": get_object_url(obj), "path": get_content_path(obj) }) if obj.type_name == 'Directory': sub = await get_all_files(obj, request) children += sub return children
async def get_inherited_aliases(ob) -> list: storage = get_storage() if storage is None: return [] ob_path = get_content_path(ob) data = [] context = ob.__parent__ while context is not None and not IContainer.providedBy(context): context_path = get_content_path(context) for alias in await get_aliases(context): if not alias["moved"]: continue path = alias["path"] current_sub_path = ob_path[len(context_path):] # noqa path = os.path.join(path, current_sub_path.strip("/")) alias["context_path"] = context_path alias["path"] = path data.append(alias) context = context.__parent__ return data
async def search_get(context, request): q = request.query.get('q') search = query_utility(ICatalogUtility) if search is None: return { 'items_count': 0, 'member': [] } return await search.get_by_path( container=request.container, path=get_content_path(context), query=q)
async def object_moved(ob, event): parent_path = get_content_path(event.old_parent) old_path = os.path.join(parent_path, event.old_name) storage = utils.get_storage() container = find_container(ob) execute.after_request( utils.add_aliases, ob, [old_path], moved=True, container=container, storage=storage) cache = get_utility(ICacheUtility) execute.after_request( cache.send_invalidation, ['{}-id'.format(ob.__uuid__), '{}-links'.format(ob.__uuid__), '{}-links-to'.format(ob.__uuid__)])
def remove_object(obj, event): uid = getattr(obj, 'uuid', None) if uid is None: return portal_type = getattr(obj, 'portal_type', None) if portal_type is None or ISite.providedBy(obj): return content_path = get_content_path(obj) hook = get_hook() if hook is None: return hook.remove.append((uid, portal_type, content_path)) if uid in hook.index: del hook.index[uid]
def remove_object(obj, event): uid = getattr(obj, 'uuid', None) if uid is None: return type_name = getattr(obj, 'type_name', None) if type_name is None or IContainer.providedBy(obj): return content_path = get_content_path(obj) hook = get_hook() if hook is None: return hook.remove.append((uid, type_name, content_path)) if uid in hook.index: del hook.index[uid]
async def add_object_task(callable=None, ob=None, *args, _request=None, _retries=3, **kwargs): superfunc = _run_object_task if inspect.isasyncgenfunction(callable): # async generators need to be yielded from superfunc = _yield_object_task return await add_task(superfunc, get_dotted_name(callable), get_content_path(ob), *args, _request=_request, _retries=_retries, **kwargs)
def remove_object(obj, event): uid = getattr(obj, 'uuid', None) if uid is None: return type_name = getattr(obj, 'type_name', None) if type_name is None or IContainer.providedBy(obj): return content_path = get_content_path(obj) fut = get_future() if fut is None: return fut.remove.append((uid, type_name, content_path)) if uid in fut.index: del fut.index[uid] if uid in fut.update: del fut.update[uid]
def get_path(ob): return get_content_path(ob)
def generate_key(request, context): return '{}{}/{}::{}'.format( request._container_id, get_content_path(context), context._p_oid, uuid.uuid4().hex)