From 5f21c3a56d871101c169226e1b9d39e634b771d1 Mon Sep 17 00:00:00 2001 From: allegroai <> Date: Mon, 18 Apr 2022 16:34:18 +0300 Subject: [PATCH] Add support for searching hidden projects and tasks --- apiserver/apimodels/projects.py | 1 + apiserver/schema/services/projects.conf | 18 +++++++++-- apiserver/schema/services/tasks.conf | 18 +++++++++-- apiserver/services/projects.py | 40 +++++++++++++++++-------- apiserver/services/tasks.py | 13 ++++++++ 5 files changed, 74 insertions(+), 16 deletions(-) diff --git a/apiserver/apimodels/projects.py b/apiserver/apimodels/projects.py index 447daa5..6db26de 100644 --- a/apiserver/apimodels/projects.py +++ b/apiserver/apimodels/projects.py @@ -65,3 +65,4 @@ class ProjectsGetRequest(models.Base): active_users = fields.ListField(str) check_own_contents = fields.BoolField(default=False) shallow_search = fields.BoolField(default=False) + search_hidden = fields.BoolField(default=False) diff --git a/apiserver/schema/services/projects.conf b/apiserver/schema/services/projects.conf index 0f47fdd..cdaad68 100644 --- a/apiserver/schema/services/projects.conf +++ b/apiserver/schema/services/projects.conf @@ -455,7 +455,14 @@ get_all { } } } - "2.15": ${get_all."2.13"} { + "2.14": ${get_all."2.13"} { + request.properties.search_hidden { + description: "If set to 'true' then hidden projects are included in the search results" + type: boolean + default: false + } + } + "2.15": ${get_all."2.14"} { request { properties { scroll_id { @@ -536,7 +543,14 @@ get_all_ex { } } } - "2.15": ${get_all_ex."2.13"} { + "2.14": ${get_all_ex."2.13"} { + request.properties.search_hidden { + description: "If set to 'true' then hidden projects are included in the search results" + type: boolean + default: false + } + } + "2.15": ${get_all_ex."2.14"} { request { properties { scroll_id { diff --git a/apiserver/schema/services/tasks.conf b/apiserver/schema/services/tasks.conf index 453bf5f..8721707 100644 --- a/apiserver/schema/services/tasks.conf +++ b/apiserver/schema/services/tasks.conf @@ -685,7 +685,14 @@ get_all_ex { } } } - "2.15": ${get_all_ex."2.13"} { + "2.14": ${get_all_ex."2.13"} { + request.properties.search_hidden { + description: "If set to 'true' then hidden tasks are included in the search results" + type: boolean + default: false + } + } + "2.15": ${get_all_ex."2.14"} { request { properties { scroll_id { @@ -822,7 +829,14 @@ get_all { } } } - "2.15": ${get_all."2.1"} { + "2.14": ${get_all."2.1"} { + request.properties.search_hidden { + description: "If set to 'true' then hidden tasks are included in the search results" + type: boolean + default: false + } + } + "2.15": ${get_all."2.14"} { request { properties { scroll_id { diff --git a/apiserver/services/projects.py b/apiserver/services/projects.py index c2b72cc..c22247d 100644 --- a/apiserver/services/projects.py +++ b/apiserver/services/projects.py @@ -26,6 +26,7 @@ from apiserver.bll.project.project_cleanup import ( validate_project_delete, ) from apiserver.database.errors import translate_errors_context +from apiserver.database.model import EntityVisibility from apiserver.database.model.project import Project from apiserver.database.utils import ( parse_from_call, @@ -73,6 +74,16 @@ def get_by_id(call): call.result.data = {"project": project_dict} +def _hidden_query(search_hidden: bool, ids: Sequence) -> Q: + """ + 1. Add only non-hidden tasks search condition (unless specifically specified differently) + """ + if search_hidden or ids: + return Q() + + return Q(system_tags__ne=EntityVisibility.hidden.value) + + def _adjust_search_parameters(data: dict, shallow_search: bool): """ 1. Make sure that there is no external query on path @@ -91,12 +102,14 @@ def _adjust_search_parameters(data: dict, shallow_search: bool): @endpoint("projects.get_all_ex", request_data_model=ProjectsGetRequest) def get_all_ex(call: APICall, company_id: str, request: ProjectsGetRequest): - conform_tag_fields(call, call.data) - allow_public = not request.non_public data = call.data + conform_tag_fields(call, data) + allow_public = not request.non_public requested_ids = data.get("id") + _adjust_search_parameters( + data, shallow_search=request.shallow_search, + ) with TimingContext("mongo", "projects_get_all"): - data = call.data if request.active_users: ids = project_bll.get_projects_with_active_user( company=company_id, @@ -105,16 +118,14 @@ def get_all_ex(call: APICall, company_id: str, request: ProjectsGetRequest): allow_public=allow_public, ) if not ids: - call.result.data = {"projects": []} - return + return {"projects": []} data["id"] = ids - _adjust_search_parameters(data, shallow_search=request.shallow_search) - ret_params = {} - projects = Project.get_many_with_join( + projects: Sequence[dict] = Project.get_many_with_join( company=company_id, query_dict=data, + query=_hidden_query(search_hidden=request.search_hidden, ids=requested_ids), allow_public=allow_public, ret_params=ret_params, ) @@ -143,6 +154,7 @@ def get_all_ex(call: APICall, company_id: str, request: ProjectsGetRequest): project_ids=list(project_ids), specific_state=request.stats_for_state, include_children=request.stats_with_children, + return_hidden_children=request.search_hidden, filter_=request.include_stats_filter, ) @@ -155,20 +167,24 @@ def get_all_ex(call: APICall, company_id: str, request: ProjectsGetRequest): @endpoint("projects.get_all") def get_all(call: APICall): - conform_tag_fields(call, call.data) data = call.data - _adjust_search_parameters(data, shallow_search=data.get("shallow_search", False)) - with translate_errors_context(), TimingContext("mongo", "projects_get_all"): + conform_tag_fields(call, data) + _adjust_search_parameters( + data, shallow_search=data.get("shallow_search", False), + ) + with TimingContext("mongo", "projects_get_all"): ret_params = {} projects = Project.get_many( company=call.identity.company, query_dict=data, + query=_hidden_query( + search_hidden=data.get("search_hidden"), ids=data.get("id") + ), parameters=data, allow_public=True, ret_params=ret_params, ) conform_output_tags(call, projects) - call.result.data = {"projects": projects, **ret_params} diff --git a/apiserver/services/tasks.py b/apiserver/services/tasks.py index a3ecfd5..5f5dbd2 100644 --- a/apiserver/services/tasks.py +++ b/apiserver/services/tasks.py @@ -98,6 +98,7 @@ from apiserver.bll.task.task_operations import ( from apiserver.bll.task.utils import update_task, get_task_for_update, deleted_prefix from apiserver.bll.util import SetFieldsResolver, run_batch_operation from apiserver.database.errors import translate_errors_context +from apiserver.database.model import EntityVisibility from apiserver.database.model.task.output import Output from apiserver.database.model.task.task import ( Task, @@ -213,6 +214,16 @@ def _process_include_subprojects(call_data: dict): call_data["project"] = project_ids_with_children(project_ids) +def _hidden_query(data: dict) -> Q: + """ + 1. Add only non-hidden tasks search condition (unless specifically specified differently) + """ + if data.get("search_hidden") or data.get("id"): + return Q() + + return Q(system_tags__ne=EntityVisibility.hidden.value) + + @endpoint("tasks.get_all_ex", required_fields=[]) def get_all_ex(call: APICall, company_id, _): conform_tag_fields(call, call.data) @@ -225,6 +236,7 @@ def get_all_ex(call: APICall, company_id, _): tasks = Task.get_many_with_join( company=company_id, query_dict=call_data, + query=_hidden_query(call_data), allow_public=True, ret_params=ret_params, ) @@ -259,6 +271,7 @@ def get_all(call: APICall, company_id, _): company=company_id, parameters=call_data, query_dict=call_data, + query=_hidden_query(call_data), allow_public=True, ret_params=ret_params, )