2
2
import asyncio
3
3
import logging
4
4
from typing import Any
5
+ from urllib .parse import parse_qsl
5
6
6
7
from channels .generic .websocket import AsyncJsonWebsocketConsumer
8
+ from django .urls import path
7
9
from idom .core .dispatcher import dispatch_single_view
8
10
from idom .core .layout import Layout , LayoutEvent
9
11
10
- from .view_loader import ALL_VIEWS
12
+ from .app_components import get_component , has_component
13
+ from .app_settings import IDOM_WEBSOCKET_URL
11
14
12
15
13
16
logger = logging .getLogger (__name__ )
14
17
15
18
19
+ def django_idom_websocket_consumer_url (* args , ** kwargs ):
20
+ """Return a URL resolver for :class:`IdomAsyncWebSocketConsumer`
21
+
22
+ While this is relatively uncommon in most Django apps, because the URL of the
23
+ websocket must be defined by the setting ``IDOM_WEBSOCKET_URL``. There's no need
24
+ to allow users to configure the URL themselves
25
+ """
26
+ return path (
27
+ IDOM_WEBSOCKET_URL + "<view_id>/" ,
28
+ IdomAsyncWebSocketConsumer .as_asgi (),
29
+ * args ,
30
+ ** kwargs ,
31
+ )
32
+
33
+
16
34
class IdomAsyncWebSocketConsumer (AsyncJsonWebsocketConsumer ):
17
35
"""Communicates with the browser to perform actions on-demand."""
18
36
@@ -34,23 +52,21 @@ async def receive_json(self, content: Any, **kwargs: Any) -> None:
34
52
await self ._idom_recv_queue .put (LayoutEvent (** content ))
35
53
36
54
async def _run_dispatch_loop (self ):
37
- # get the URL parameters and grab the view ID
38
- view_id = ...
39
- # get component ags from the URL params too
40
- component_args = ...
55
+ view_id = self .scope ["url_route" ]["kwargs" ]["view_id" ]
41
56
42
- if view_id not in ALL_VIEWS :
43
- logger .warning (f"Uknown IDOM view ID { view_id } " )
57
+ if not has_component ( view_id ) :
58
+ logger .warning (f"Uknown IDOM view ID { view_id !r } " )
44
59
return
45
60
46
- component_constructor = ALL_VIEWS [view_id ]
61
+ component_constructor = get_component (view_id )
62
+ component_kwargs = dict (parse_qsl (self .scope ["query_string" ]))
47
63
48
64
try :
49
- component_instance = component_constructor (* component_args )
65
+ component_instance = component_constructor (** component_kwargs )
50
66
except Exception :
51
67
logger .exception (
52
68
f"Failed to construct component { component_constructor } "
53
- f"with parameters { component_args } "
69
+ f"with parameters { component_kwargs } "
54
70
)
55
71
return
56
72
0 commit comments