-
-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathcomponents.py
83 lines (67 loc) · 2.68 KB
/
components.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
from functools import wraps
from typing import Callable, Union
import idom
from django.urls import path, re_path
from idom.core.proto import ComponentType, VdomDict
from idom.core.vdom import make_vdom_constructor
from idom.html import div
from conreq import AuthLevel
from conreq.utils.environment import get_base_url
from conreq.utils.views import authenticated as authenticated_view
BASE_URL = get_base_url(append_slash=False, prepend_slash=False)
if BASE_URL:
BASE_URL = BASE_URL + "/"
iframe = make_vdom_constructor("iframe")
def authenticated(
fallback: Union[ComponentType, VdomDict] = None,
auth_level: AuthLevel = AuthLevel.user,
) -> ComponentType:
"""Decorates an IDOM component."""
def decorator(component):
@wraps(component)
def _wrapped_func(websocket, *args, **kwargs):
if auth_level == AuthLevel.user:
return (
component(websocket, *args, **kwargs)
if websocket.scope["user"].is_authenticated
else fallback or div()
)
if auth_level == AuthLevel.admin:
return (
component(websocket, *args, **kwargs)
if websocket.scope["user"].is_staff
else fallback or div()
)
return component(websocket, *args, **kwargs)
return _wrapped_func
return decorator
# TODO: Use Django resolve and raise an exception if registering something that already exists
def view_to_component(
url_pattern: str = None,
name: str = None,
use_regex: bool = False,
auth_level: AuthLevel = AuthLevel.user,
) -> ComponentType:
"""Converts a Django view function/class into an IDOM component
by turning it into an idom component in an iframe."""
def decorator(func: Callable):
# pylint: disable=import-outside-toplevel
from conreq.urls import urlpatterns
from conreq.utils.profiling import profiled_view
# Register a new URL path
view = profiled_view(authenticated_view(func, auth_level))
dotted_path = f"{func.__module__}.{func.__name__}".replace("<", "").replace(
">", ""
)
view_name = name or dotted_path
src_url = url_pattern or f"{BASE_URL}iframe/{dotted_path}"
if use_regex:
urlpatterns.append(re_path(src_url, view, name=view_name))
else:
urlpatterns.append(path(src_url, view, name=view_name))
# Create an iframe with src=...
@idom.component
def idom_component(*args, **kwargs):
return iframe({"src": f"/{src_url}", "loading": "lazy"})
return idom_component
return decorator