102 lines
3.4 KiB
Python
102 lines
3.4 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
|
|
from typing import Self, Any, Sequence
|
|
from re import Match as REMatch
|
|
from mimetypes import guess_type as get_mime_by_extension
|
|
from Interfaces.Application.NucelarMonitorInterface import NucelarMonitorInterface
|
|
from Models.RouteModel import RouteModel
|
|
from Models.ResponseModel import ResponseModel
|
|
from Models.RequestModel import RequestModel
|
|
|
|
class RoutesManager:
|
|
|
|
def __init__(self:Self, nucelar_monitor:NucelarMonitorInterface) -> None:
|
|
self.nucelar_monitor:NucelarMonitorInterface = nucelar_monitor
|
|
|
|
key:str
|
|
|
|
self.__routes:list[RouteModel] = []
|
|
|
|
for key in (
|
|
"default_routes_files", "routes_files",
|
|
"default_routes", "routes"
|
|
):
|
|
self.add(self.nucelar_monitor.settings.get(key, None, []), True)
|
|
|
|
def add(self:Self, inputs:Any|None, overwrite:bool = False) -> None:
|
|
|
|
route:str|Sequence[str|list[str]|RouteModel]
|
|
|
|
for route in self.nucelar_monitor.files.load_json(inputs, False):
|
|
|
|
item:RouteModel = route if isinstance(route, RouteModel) else RouteModel(self.nucelar_monitor, route)
|
|
|
|
if item.error:
|
|
self.add(route, overwrite)
|
|
continue
|
|
|
|
exists:RouteModel
|
|
done:bool = False
|
|
|
|
for exists in self.__routes:
|
|
if exists.method == item.method and exists.route == item.route:
|
|
if overwrite:
|
|
done = True
|
|
self.__routes.remove(exists)
|
|
else:
|
|
break
|
|
|
|
if not done:
|
|
self.__routes.append(item)
|
|
|
|
def get(self:Self, request:RequestModel, response:ResponseModel) -> None:
|
|
|
|
route:RouteModel
|
|
|
|
for route in self.__routes:
|
|
if route.method != request.method:
|
|
continue
|
|
|
|
matches:REMatch[str]|None = route.route.match(request.request)
|
|
|
|
if not matches:
|
|
continue
|
|
|
|
request.set_uri_variables(route.variables, matches)
|
|
|
|
if route.action:
|
|
try:
|
|
route.action(request, response)
|
|
except Exception as exception:
|
|
response.build({
|
|
"ok" : False,
|
|
"code" : 500,
|
|
"message" : "Internal server error",
|
|
"error" : str(exception)
|
|
}, "application/json", 500, "Internal server error")
|
|
self.nucelar_monitor.exception(exception, "nucelar_monitor_routes_manager_get_exception", {
|
|
"request" : request.request,
|
|
"method" : request.method
|
|
})
|
|
return
|
|
if route.path:
|
|
|
|
index:str
|
|
|
|
for index in request.index_files:
|
|
|
|
full_path = route.path + request.request + ("" if index == "" else "/" + index)
|
|
|
|
if (response_data := self.nucelar_monitor.files.load_file(full_path, "rb")) is not None:
|
|
response.set_data(
|
|
response_data,
|
|
get_mime_by_extension(full_path)[0] or "application/octet-stream"
|
|
)
|
|
return
|
|
|
|
response.build({
|
|
"ok" : False,
|
|
"code" : 404,
|
|
"message" : "Not found"
|
|
}, "application/json", 404, "Not found") |