-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathcontrollers.py
More file actions
147 lines (116 loc) · 4.79 KB
/
Copy pathcontrollers.py
File metadata and controls
147 lines (116 loc) · 4.79 KB
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
import os
from tornado.escape import url_unescape
from tornado.ioloop import IOLoop
from tornado.web import HTTPError
from tornado_prometheus import MetricsHandler
from digi_server.logger import get_logger
from utils.module_discovery import get_resource_path, import_modules, is_frozen
from utils.web.base_controller import BaseAPIController, BaseController
from utils.web.route import ApiRoute, ApiVersion, Route
IMPORTED_CONTROLLERS = {}
INDEX_HTML = "index.html"
def import_all_controllers():
get_logger().info("Importing controllers...")
import_modules("controllers", IMPORTED_CONTROLLERS, __name__)
# Log summary
get_logger().info(f"Imported {len(IMPORTED_CONTROLLERS)} controller modules")
get_logger().debug(f"Imported controllers: {list(IMPORTED_CONTROLLERS.keys())}")
class RootController(BaseController):
def get(self, _path):
if is_frozen():
full_path = get_resource_path(os.path.join("static", "ui-old", INDEX_HTML))
else:
file_path = os.path.join(
os.path.abspath(os.path.dirname(__file__)), "..", "static", "ui-old"
)
full_path = os.path.join(file_path, INDEX_HTML)
if not os.path.isfile(full_path):
raise HTTPError(404)
with open(full_path, "r", encoding="utf-8") as file:
self.write(file.read())
class RootControllerV3(BaseController):
async def get(self, path):
if not path and not self.get_argument("_switch", None):
default_ui = await self.application.digi_settings.get("default_ui")
if default_ui == "old":
self.redirect("/ui-old/")
return
if is_frozen():
# In PyInstaller mode, use resource path
full_path = get_resource_path(os.path.join("static", INDEX_HTML))
else:
# In source mode, use relative path
file_path = os.path.join(
os.path.abspath(os.path.dirname(__file__)), "..", "static"
)
full_path = os.path.join(file_path, INDEX_HTML)
if not os.path.isfile(full_path):
get_logger().error(f"Index file not found: {full_path}")
raise HTTPError(404)
try:
content = await IOLoop.current().run_in_executor(
None, lambda: open(full_path, "r", encoding="utf-8").read()
)
self.write(content)
except Exception as e:
get_logger().error(f"Error serving {INDEX_HTML}: {str(e)}")
raise HTTPError(500) from e
class StaticController(BaseController):
def get(self):
self.set_header("Content-Type", "")
uri = url_unescape(self.request.uri).strip(os.path.sep)
if is_frozen():
# In PyInstaller mode, use resource path
full_path = get_resource_path(uri)
else:
# In source mode, use relative path
full_path = os.path.join(
os.path.abspath(os.path.dirname(__file__)),
"..",
"static",
uri,
)
if not os.path.isfile(full_path):
get_logger().warning(f"Static file not found: {full_path}")
raise HTTPError(404)
try:
with open(full_path, "r", encoding="utf-8") as file:
self.write(file.read())
except UnicodeDecodeError:
try:
with open(full_path, "rb") as file:
self.write(file.read())
except Exception as exc:
get_logger().error(f"Error reading binary file {full_path}: {str(exc)}")
raise HTTPError(500) from exc
except Exception as exc:
get_logger().error(f"Error reading file {full_path}: {str(exc)}")
raise HTTPError(500) from exc
class ApiFallback(BaseAPIController):
def get(self):
self.set_status(404)
self.write({"message": "404 not found"})
def post(self):
self.set_status(404)
self.write({"message": "404 not found"})
def patch(self):
self.set_status(404)
self.write({"message": "404 not found"})
def delete(self):
self.set_status(404)
self.write({"message": "404 not found"})
@Route("/debug")
class DebugController(BaseController):
def get(self):
self.set_status(200)
self.set_header("Content-Type", "application/json")
self.write({"status": "OK", "imported_controllers": list(IMPORTED_CONTROLLERS)})
@ApiRoute("debug", ApiVersion.V1)
class ApiDebugController(BaseAPIController):
def get(self):
self.set_status(200)
self.set_header("Content-Type", "application/json")
self.write({"status": "OK", "api_version": 1})
@Route("/debug/metrics", ignore_logging=True)
class DebugMetricsController(MetricsHandler, BaseController):
pass