Skip to content

Commit 1380d39

Browse files
committed
Merge with dev
2 parents e7f8641 + 9257915 commit 1380d39

File tree

9 files changed

+135
-29
lines changed

9 files changed

+135
-29
lines changed

alembic/versions/ad13850a7245_ui_flip_project_icon.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,10 @@ def upgrade():
3030

3131
update_dataset_sql = """
3232
UPDATE cognition.project
33-
SET icon = 'IconBolt';
33+
SET icon = 'IconBolt';"""
34+
connection.execute(update_dataset_sql)
35+
36+
update_dataset_sql = """
3437
UPDATE public.user
3538
SET use_new_cognition_ui = FALSE; """
3639
connection.execute(update_dataset_sql)

controller/misc/manager.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,21 @@
11
from typing import Any, Dict, List
22
from fast_api.types import ServiceVersionResult
3-
from submodules.model.global_objects import customer_button
3+
from submodules.model.global_objects import (
4+
customer_button,
5+
admin_queries as admin_queries_db_go,
6+
)
47
from datetime import datetime
58
import os
69
from controller.auth import kratos
710
from submodules.model.util import sql_alchemy_to_dict
811
from submodules.model import enums
912
import requests
1013
from urllib.parse import urlparse, urlencode, parse_qsl, parse_qs
14+
from util.tmp_export_file_cleanup import add_cleanup_task
15+
from uuid import uuid4
16+
import pandas as pd
17+
from submodules.model.util import ensure_sql_text
18+
from submodules.model.business_objects import general
1119

1220
import base64
1321

@@ -169,3 +177,16 @@ def __patch_url(url: str, **kwargs):
169177
._replace(query=urlencode(dict(parse_qsl(urlparse(url).query), **kwargs)))
170178
.geturl()
171179
)
180+
181+
182+
def create_admin_query_excel(
183+
query: enums.AdminQueries, parameters: Dict[str, Any]
184+
) -> str:
185+
186+
q = admin_queries_db_go.get_result_admin_query(query, parameters, as_query=True)
187+
188+
df = pd.read_sql(ensure_sql_text(q), con=general.get_bind())
189+
tmp_filename = f"tmp/feedback_{uuid4()}.xlsx"
190+
df.to_excel(tmp_filename, index=False)
191+
add_cleanup_task(tmp_filename, 5)
192+
return tmp_filename

controller/user/manager.py

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
from typing import Dict, Optional
1+
from typing import Dict, Optional, Any
22
from submodules.model import User, daemon, enums
33
from submodules.model.business_objects import user, general
44
from controller.auth import kratos
55
from submodules.model.exceptions import EntityNotFoundException
66
from controller.organization import manager as organization_manager
77
from datetime import datetime, timedelta
88
from util.decorator import param_throttle
9+
from submodules.model.util import is_string_true_value
910

1011

1112
def get_user(user_id: str) -> User:
@@ -70,20 +71,13 @@ def update_user_role(user_id: str, role: str) -> User:
7071
return user_item
7172

7273

73-
def update_user_language_display(user_id: str, language_display: str) -> User:
74+
def update_user_field(user_id: str, field: str, value: Any) -> User:
7475
user_item = user.get(user_id)
7576
if not user_item:
7677
raise ValueError("User not found")
77-
user_item.language_display = language_display
78-
general.commit()
79-
return user_item
80-
81-
82-
def set_use_new_ui(user_id: str, value: bool) -> User:
83-
user_item = user.get(user_id)
84-
if not user_item:
85-
raise ValueError("User not found")
86-
user_item.use_new_cognition_ui = value
78+
if field == "use_new_cognition_ui":
79+
value = is_string_true_value(value)
80+
setattr(user_item, field, value)
8781
general.commit()
8882
return user_item
8983

fast_api/models.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,5 +508,9 @@ class CheckInviteUsersBody(BaseModel):
508508
emails: List[StrictStr]
509509

510510

511+
class AdminQueryFilterBody(BaseModel):
512+
parameters: Optional[Dict[str, Any]] = None
513+
514+
511515
class RecordDeletion(BaseModel):
512516
record_ids: List[str]

fast_api/routes/misc.py

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from exceptions.exceptions import AuthManagerError
22
from fastapi import APIRouter, Body, Request, status
3-
from fastapi.responses import PlainTextResponse
3+
from fastapi.responses import PlainTextResponse, FileResponse
44
from fast_api.models import (
55
CancelTaskBody,
66
CheckInviteUsersBody,
@@ -9,6 +9,7 @@
99
ModelProviderDownloadModelBody,
1010
CreateCustomerButton,
1111
UpdateCustomerButton,
12+
AdminQueryFilterBody,
1213
)
1314
from fast_api.routes.client_response import (
1415
pack_json_result,
@@ -22,12 +23,16 @@
2223
from controller.model_provider import manager as model_provider_manager
2324
from controller.task_master import manager as task_master_manager
2425
from submodules.model import enums
25-
from submodules.model.global_objects import customer_button as customer_button_db_go
26+
from submodules.model.global_objects import (
27+
customer_button as customer_button_db_go,
28+
admin_queries as admin_queries_db_go,
29+
)
2630
from submodules.model.util import sql_alchemy_to_dict
2731
from submodules.model.enums import (
2832
try_parse_enum_value,
2933
CustomerButtonType,
3034
CustomerButtonLocation,
35+
AdminQueries,
3136
)
3237
from submodules.model.business_objects import task_queue as task_queue_bo
3338

@@ -296,3 +301,33 @@ def check_valid_emails(request: Request, body: CheckInviteUsersBody = Body(...))
296301
raise AuthManagerError("Full admin access required")
297302
data = auth.check_valid_emails(body.emails)
298303
return pack_json_result(data)
304+
305+
306+
# post to allow for a body to be sent
307+
@router.post("/admin-query/{query}")
308+
def get_admin_queries(
309+
request: Request, query: AdminQueries, body: AdminQueryFilterBody = Body(...)
310+
):
311+
auth.check_admin_access(request.state.info)
312+
if not auth.check_is_full_admin(request):
313+
raise AuthManagerError("Full admin access required")
314+
data = admin_queries_db_go.get_result_admin_query(query, body.parameters)
315+
return pack_json_result(data)
316+
317+
318+
@router.post("/admin-query/{query}/download")
319+
def get_admin_query_excel(
320+
request: Request, query: AdminQueries, body: AdminQueryFilterBody = Body(...)
321+
):
322+
auth.check_admin_access(request.state.info)
323+
if not auth.check_is_full_admin(request):
324+
raise AuthManagerError("Full admin access required")
325+
326+
file_path = manager.create_admin_query_excel(query, body.parameters)
327+
328+
if file_path is None:
329+
return GENERIC_FAILURE_RESPONSE
330+
return FileResponse(
331+
file_path,
332+
media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
333+
)

fast_api/routes/organization.py

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -247,19 +247,11 @@ def archive_admin_message(
247247
return get_silent_success()
248248

249249

250-
# in use cognition-ui (08.01.25)
251-
@router.put("/set-language-display/{language}")
252-
def set_language_display(request: Request, language: str):
253-
user_id = auth_manager.get_user_id_by_info(request.state.info)
254-
user_manager.update_user_language_display(user_id, language)
255-
return get_silent_success()
256-
257-
258250
# in use cognition-ui (23.06.25)
259-
@router.put("/set-use-new-ui/{value}")
260-
def set_use_new_ui(request: Request, value: bool):
251+
@router.put("/update-user-field/{field}/{value}")
252+
def set_language_display(request: Request, field: str, value: str):
261253
user_id = auth_manager.get_user_id_by_info(request.state.info)
262-
user_manager.set_use_new_ui(user_id, value)
254+
user_manager.update_user_field(user_id, field, value)
263255
return get_silent_success()
264256

265257

util/clean_up.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from submodules.model.business_objects import upload_task
2-
import os, shutil
2+
import os
3+
import shutil
34

45

56
def clean_up_database() -> None:

util/tmp_export_file_cleanup.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
from datetime import datetime, timedelta
2+
from submodules.model.daemon import run_without_db_token
3+
import glob
4+
import os
5+
import traceback
6+
import time
7+
8+
__cleanup_tasks = None
9+
10+
11+
def add_cleanup_task(tmp_filename: str, minutes: int) -> None:
12+
global __cleanup_tasks
13+
if __cleanup_tasks is None:
14+
add_existing_feedback_and_consumption_files_to_cleanup(tmp_filename)
15+
run_without_db_token(start_cleanup)
16+
else:
17+
__cleanup_tasks[tmp_filename] = datetime.now() + timedelta(minutes=minutes)
18+
19+
20+
TMP_PATTERN = [
21+
"tmp/feedback_*.xlsx",
22+
"tmp/consumption_*.zip",
23+
"tmp/consumption_detailed_*.zip",
24+
"tmp/consumption_summary_*.xlsx",
25+
]
26+
27+
28+
def add_existing_feedback_and_consumption_files_to_cleanup(tmp_filename: str) -> None:
29+
# failsafe for shutdown before deletion time ran out
30+
# should only be called for feedback_cleanup_tasks = None
31+
global __cleanup_tasks
32+
if __cleanup_tasks is not None:
33+
raise ValueError("someone didn't read the comment")
34+
__cleanup_tasks = {}
35+
for pattern in TMP_PATTERN:
36+
for filename in glob.glob(pattern):
37+
minutes = 1 # after a restart they most likely are not valid anymore so we delete them sooner
38+
if filename == tmp_filename:
39+
minutes = 60
40+
__cleanup_tasks[filename] = datetime.now() + timedelta(minutes=minutes)
41+
42+
43+
def start_cleanup() -> None:
44+
global __cleanup_tasks
45+
while __cleanup_tasks is not None and len(__cleanup_tasks) > 0:
46+
try:
47+
for filename, delete_time in list(__cleanup_tasks.items()):
48+
if datetime.now() > delete_time:
49+
if os.path.isfile(filename):
50+
os.remove(filename)
51+
del __cleanup_tasks[filename]
52+
except Exception:
53+
print("Error in cleanup task", flush=True)
54+
print(traceback.format_exc(), flush=True)
55+
finally:
56+
time.sleep(60)

0 commit comments

Comments
 (0)