OpoTests/Python/Managers/RoutesManager.py

97 lines
3.1 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from typing import Self, Any
from Interfaces.OpoTestsInterface import OpoTestsInterface
from Models.RouteModel import RouteModel
from re import Match as REMatch
from Models.RequestModel import RequestModel
from Utils.Check import Check
from Utils.Utils import Utils
class RoutesManager:
def __init__(self:Self, ot:OpoTestsInterface) -> None:
self.ot:OpoTestsInterface = ot
self.__routes:tuple[RouteModel] = tuple()
def start(self:Self) -> None:
key:str
for key in ("default_routes_files", "default_routes", "routes_files", "routes"):
self.add(self.ot.settings.get(key, []), True)
def add(self:Self, inputs:str|RouteModel|list|tuple, overwrite:bool = False) -> None:
item:str|RouteModel|list|tuple
for item in self.ot.load_json_data(inputs, False) or (inputs,):
if Check.is_string(item):
route:RouteModel = RouteModel(item)
if route.done:
self.__routes += (route,)
else:
self.add(item, overwrite)
elif isinstance(item, RouteModel):
if item.done:
self.__routes += (item,)
elif Check.is_array(item):
if len(item) == 6 and all(subitem is None or Check.is_string(subitem) for subitem in item):
route:RouteModel = RouteModel(item)
if route.done:
self.__routes += (route,)
continue
for subitem in item:
self.add(subitem, overwrite)
def go(self:Self, request:RequestModel) -> tuple[Any|None, int]:
route:RouteModel
for route in self.__routes:
if route.method == request.method:
matches:REMatch = route.request.match(request.request)
if not matches:
continue
request.variables_request = {
route.variables[i] : value for i, value in enumerate(matches.groups()[1:])
}
if route.path:
for index in request.index_files:
path:str = request.public_path + '/' + request.request + ('/' + index if index else '')
data:bytes|None = self.ot.files.load(path)
if data is not None:
return (data, {"mime" : self.ot.files.get_mime(path)})
elif route.controller:
data:tuple[Any|None, dict[str, Any|None]]|None = self.ot.controllers.get(
route.controller,
route.action,
request
)
if data is not None:
return data
return (Utils.json_encode({
"ok" : False,
"code" : 404,
"message" : "Not found"
}), {
"http_code" : 404,
"mime" : "application/json"
})