basis/components/web/utils/__init__.py
apeters 1d204f26b8 pre-Korves.Net
Signed-off-by: apeters <apeters@korves.net>
2025-05-21 08:05:07 +00:00

97 lines
3.1 KiB
Python

from .locking import *
from .quart import *
from .wrappers import *
from .notifications import *
from config import defaults
from components.database import IN_MEMORY_DB
from components.models.tables import TableSearch, BaseModel
from components.users import search as search_users
def table_search_helper(
body, session_key_identifier, default_sort_attr, default_sort_reverse: bool = False
):
search_model = TableSearch.parse_obj(body or {})
search_model_post = search_model.dict(exclude_unset=True)
# Post wins over session wins over default
page = search_model_post.get(
"page", session.get(f"{session_key_identifier}_page", search_model.page)
)
page_size = search_model_post.get(
"page_size",
session.get(f"{session_key_identifier}_page_size", search_model.page_size),
)
filters = search_model_post.get(
"filters",
session.get(f"{session_key_identifier}_filters", search_model.filters),
)
sorting = search_model_post.get(
"sorting",
session.get(
f"{session_key_identifier}_sorting",
(default_sort_attr, default_sort_reverse),
),
)
sort_attr, sort_reverse = sorting
session.update(
{
f"{session_key_identifier}_page": page,
f"{session_key_identifier}_page_size": page_size,
f"{session_key_identifier}_sorting": sorting,
f"{session_key_identifier}_filters": filters,
}
)
return search_model, page, page_size, sort_attr, sort_reverse, filters
def parse_form_to_dict(key, value):
keys = key.split(".")
nested_dict = {}
current_level = nested_dict
for key in keys[:-1]:
current_level = current_level.setdefault(key, {})
current_level[keys[-1]] = value
return nested_dict
async def ws_htmx(
channel, strategy: str, data, if_path: str = "", exclude_self: bool = False
):
if channel.startswith("_") and channel in [f"_{acl}" for acl in defaults.USER_ACLS]:
matched_users = [
m.login
for m in await search_users(name="")
if channel.removeprefix("_") in m.acl
]
if matched_users:
for user in matched_users:
await ws_htmx(user, strategy, data, if_path, exclude_self)
for ws, ws_data in IN_MEMORY_DB["WS_CONNECTIONS"].get(channel, {}).items():
if exclude_self and ws.cookies == request.cookies:
continue
if not if_path or ws_data.get("path", "").startswith(if_path):
await ws.send(f'<div id="ws-recv" hx-swap-oob="{strategy}">{data}</div>')
async def render_or_json(tpl, headers, **context):
if "application/json" in headers.get("Content-Type", ""):
def convert_to_dict(value):
return (
value.model_dump(mode="json") if isinstance(value, BaseModel) else value
)
converted_context = {
key: convert_to_dict(value) for key, value in context.items()
}
return next(filter(lambda x: x, converted_context.values()), dict())
return await render_template(tpl, **context)