Skip to content

Commit a88c12c

Browse files
committed
Changed: handlers don't need to be instantiated
1 parent d622409 commit a88c12c

File tree

8 files changed

+222
-173
lines changed

8 files changed

+222
-173
lines changed

redbot/webui/__init__.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,16 @@ class RedWebUi:
5252
If descend is true, spider the links and present a summary.
5353
"""
5454

55+
handlers = [
56+
SaveHandler,
57+
LoadSavedTestHandler,
58+
ClientErrorHandler,
59+
RunTestHandler,
60+
RedirectHandler,
61+
ShowHandler,
62+
ErrorHandler, # Final fallback for 404/405
63+
]
64+
5565
def __init__(
5666
self,
5767
config: SectionProxy,
@@ -114,19 +124,9 @@ def __init__(
114124
self.link_generator: LinkGenerator = WebUiLinkGenerator(self)
115125

116126
# Dispatch through handler chain
117-
handlers = [
118-
SaveHandler(self),
119-
LoadSavedTestHandler(self),
120-
ClientErrorHandler(self),
121-
RunTestHandler(self),
122-
RedirectHandler(self),
123-
ShowHandler(self),
124-
ErrorHandler(self), # Final fallback for 404/405
125-
]
126-
127-
for handler in handlers:
128-
if handler.can_handle():
129-
handler.handle()
127+
for handler in self.handlers:
128+
if handler.can_handle(self):
129+
handler.handle(self)
130130
break
131131

132132
def error_response(

redbot/webui/handlers/base.py

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,8 @@ class RequestHandler(ABC):
2626
3. Generating URIs and HTML forms for accessing the handler
2727
"""
2828

29-
def __init__(self, ui: RedWebUiProtocol) -> None:
30-
self.ui = ui
31-
32-
def get_base_uri(self, absolute: bool = False) -> str:
29+
@classmethod
30+
def get_base_uri(cls, ui: RedWebUiProtocol, absolute: bool = False) -> str:
3331
"""
3432
Get the base URI for links.
3533
@@ -38,16 +36,17 @@ def get_base_uri(self, absolute: bool = False) -> str:
3836
3937
The returned string is always terminated by '/'.
4038
"""
41-
ui_uri = self.ui.config.get("ui_uri", "")
39+
ui_uri = ui.config.get("ui_uri", "")
4240
if not ui_uri.endswith("/"):
4341
ui_uri += "/"
4442

4543
if absolute:
4644
return ui_uri
4745
return urlparse(ui_uri).path
4846

47+
@classmethod
4948
@abstractmethod
50-
def can_handle(self) -> bool:
49+
def can_handle(cls, ui: RedWebUiProtocol) -> bool:
5150
"""
5251
Determine if this handler should process the request.
5352
@@ -57,35 +56,39 @@ def can_handle(self) -> bool:
5756
True if this handler should process the request, False otherwise
5857
"""
5958

59+
@classmethod
6060
@abstractmethod
61-
def handle(self) -> None:
61+
def handle(cls, ui: RedWebUiProtocol) -> None:
6262
"""
6363
Handle the request and generate a response.
6464
6565
This method is responsible for:
6666
- Processing the request
6767
- Generating appropriate response headers and body
68-
- Calling self.ui.exchange.response_start(), self.ui.output(), and
69-
self.ui.exchange.response_done()
68+
- Calling ui.exchange.response_start(), ui.output(), and
69+
ui.exchange.response_done()
7070
"""
7171

72+
@classmethod
7273
@abstractmethod
73-
def render_link(self, **kwargs: Any) -> str:
74+
def render_link(cls, ui: RedWebUiProtocol, **kwargs: Any) -> str:
7475
"""
7576
Generate a URI for this handler.
7677
7778
This method generates a relative URI for the handler, including any
7879
parameters required. It uses the `ui_uri` from the configuration.
7980
8081
Args:
82+
ui: The WebUI instance
8183
**kwargs: Arguments for the link (handler-specific)
8284
8385
Returns:
8486
The generated URI string
8587
"""
8688
raise NotImplementedError
8789

88-
def render_form(self, **kwargs: Any) -> str:
90+
@classmethod
91+
def render_form(cls, ui: RedWebUiProtocol, **kwargs: Any) -> str:
8992
"""
9093
Generate an HTML form for accessing this handler.
9194
@@ -94,6 +97,7 @@ def render_form(self, **kwargs: Any) -> str:
9497
return a complete HTML <form> element.
9598
9699
Args:
100+
ui: The WebUI instance
97101
**kwargs: Handler-specific parameters for the form
98102
99103
Returns:

redbot/webui/handlers/client_error.py

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from typing import TYPE_CHECKING
99

1010
from redbot.webui.handlers.base import RequestHandler
11+
from redbot.type import RedWebUiProtocol
1112

1213
if TYPE_CHECKING:
1314
from redbot.webui import RedWebUi
@@ -22,54 +23,59 @@ class ClientErrorHandler(RequestHandler):
2223
response.
2324
"""
2425

25-
def can_handle(self) -> bool:
26+
@classmethod
27+
def can_handle(cls, ui: RedWebUiProtocol) -> bool:
2628
"""
2729
Determine if this handler should process the request.
2830
2931
Handles POST requests with 'client_error' in query string.
3032
"""
3133
return (
32-
self.ui.method == "POST"
33-
and len(self.ui.path) > 0
34-
and self.ui.path[0] == "client_error"
34+
ui.method == "POST"
35+
and len(ui.path) > 0
36+
and ui.path[0] == "client_error"
3537
)
3638

37-
def handle(self) -> None:
39+
@classmethod
40+
def handle(cls, ui: RedWebUiProtocol) -> None:
3841
"""
3942
Handle the client error by logging it.
4043
4144
Extracts the error message from the request body, sanitizes it,
4245
and logs it to the console. Returns a 204 No Content response.
4346
"""
4447
# Extract and sanitize the error message
45-
body = self.ui.req_body.decode("ascii", "replace")[:255].replace("\n", "")
48+
body = ui.req_body.decode("ascii", "replace")[:255].replace("\n", "")
4649
body_safe = "".join([x for x in body if x in string.printable])
4750

4851
# Log the error
49-
self.ui.error_log(f"Client JS -> {body_safe}")
52+
ui.error_log(f"Client JS -> {body_safe}")
5053

5154
# Return 204 No Content
52-
self.ui.exchange.response_start(
55+
ui.exchange.response_start(
5356
b"204",
5457
b"No Content",
5558
[],
5659
)
57-
self.ui.exchange.response_done([])
60+
ui.exchange.response_done([])
5861

59-
def render_link(self, absolute: bool = False, **kwargs: str) -> str:
62+
@classmethod
63+
def render_link(cls, ui: RedWebUiProtocol, absolute: bool = False, **kwargs: str) -> str:
6064
"""
6165
Generate a URI for reporting client errors.
6266
6367
Args:
68+
ui: The WebUI instance
6469
absolute: If True, return absolute URI
6570
**kwargs: Not used for this handler
6671
6772
Returns:
6873
URI for the client error endpoint
6974
"""
70-
return f"{self.get_base_uri(absolute)}client_error"
75+
return f"{cls.get_base_uri(ui, absolute)}client_error"
7176

72-
def render_form(self, **kwargs: str) -> str:
77+
@classmethod
78+
def render_form(cls, ui: RedWebUiProtocol, **kwargs: str) -> str:
7379
"""
7480
Client error reporting doesn't use forms.
7581

redbot/webui/handlers/error.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from typing import TYPE_CHECKING
88

99
from redbot.webui.handlers.base import RequestHandler
10+
from redbot.type import RedWebUiProtocol
1011

1112
if TYPE_CHECKING:
1213
from redbot.webui import RedWebUi
@@ -20,7 +21,8 @@ class ErrorHandler(RequestHandler):
2021
and returns appropriate error responses.
2122
"""
2223

23-
def can_handle(self) -> bool:
24+
@classmethod
25+
def can_handle(cls, ui: RedWebUiProtocol) -> bool:
2426
"""
2527
Determine if this handler should process the request.
2628
@@ -29,7 +31,8 @@ def can_handle(self) -> bool:
2931
"""
3032
return True # Always matches as the final fallback
3133

32-
def handle(self) -> None:
34+
@classmethod
35+
def handle(cls, ui: RedWebUiProtocol) -> None:
3336
"""
3437
Handle the error by returning 405 or 404 as appropriate.
3538
@@ -38,13 +41,14 @@ def handle(self) -> None:
3841
"""
3942
# Get the HTTP method from the request
4043
# For now, we'll treat everything as 404 since we're the final fallback
41-
self.ui.error_response(
44+
ui.error_response(
4245
b"404",
4346
b"Not Found",
4447
"The requested resource was not found",
4548
)
4649

47-
def render_link(self, **kwargs: str) -> str:
50+
@classmethod
51+
def render_link(cls, ui: RedWebUiProtocol, **kwargs: str) -> str:
4852
"""
4953
Error handler doesn't generate links.
5054
@@ -53,7 +57,8 @@ def render_link(self, **kwargs: str) -> str:
5357
"""
5458
return ""
5559

56-
def render_form(self, **kwargs: str) -> str:
60+
@classmethod
61+
def render_form(cls, ui: RedWebUiProtocol, **kwargs: str) -> str:
5762
"""
5863
Error handler doesn't generate forms.
5964

0 commit comments

Comments
 (0)