1
0
mirror of https://github.com/dkmstr/openuds.git synced 2025-03-20 06:50:23 +03:00

Refactor HelpMethod and HelpInfo classes to include HTTP methods and improve documentation rendering

This commit is contained in:
Adolfo Gómez García 2025-02-04 13:20:03 +01:00
parent 458b4d3412
commit 8130afa2d5
No known key found for this signature in database
GPG Key ID: DD1ABF20724CDA23
3 changed files with 97 additions and 65 deletions

View File

@ -52,8 +52,10 @@ logger = logging.getLogger(__name__)
@dataclasses.dataclass
class HelpMethodInfo:
method: str
text: str
methods: list[types.rest.HelpNode.Methods]
def __str__(self) -> str:
return f'{self.method}: {self.text}'
@ -63,27 +65,69 @@ class HelpMethodInfo:
class HelpMethod(enum.Enum):
ITEM = HelpMethodInfo('<uuid>', 'Retrieves an item by its UUID')
LOG = HelpMethodInfo(f'<uuid>/{consts.rest.LOG}', 'Retrieves the log of an item')
OVERVIEW = HelpMethodInfo(consts.rest.OVERVIEW, 'General Overview of all items (a list')
TABLEINFO = HelpMethodInfo(consts.rest.TABLEINFO, 'Table visualization information (types, etc..)')
TYPES = HelpMethodInfo(consts.rest.TYPES, 'Retrieves a list of types available')
TYPES_TYPE = HelpMethodInfo(f'{consts.rest.TYPES}/<type>', 'Retrieves a type information')
GUI = HelpMethodInfo(consts.rest.GUI, 'GUI information')
GUI_TYPES = HelpMethodInfo(f'{consts.rest.GUI}/<type>', 'GUI Types information')
ITEM = HelpMethodInfo(
'<uuid>',
'Retrieves an item by its UUID',
[
types.rest.HelpNode.Methods.GET,
types.rest.HelpNode.Methods.PUT,
types.rest.HelpNode.Methods.DELETE,
],
)
LOG = HelpMethodInfo(
f'<uuid>/{consts.rest.LOG}',
'Retrieves the logs of an element by its UUID',
[
types.rest.HelpNode.Methods.GET,
],
)
OVERVIEW = HelpMethodInfo(
consts.rest.OVERVIEW, 'General Overview of all items (a list', [types.rest.HelpNode.Methods.GET]
)
TABLEINFO = HelpMethodInfo(
consts.rest.TABLEINFO,
'Table visualization information (types, etc..)',
[
types.rest.HelpNode.Methods.GET,
],
)
TYPES = HelpMethodInfo(
consts.rest.TYPES,
'Retrieves a list of types available',
[
types.rest.HelpNode.Methods.GET,
],
)
TYPES_TYPE = HelpMethodInfo(
f'{consts.rest.TYPES}/<type>',
'Retrieves a type information',
[
types.rest.HelpNode.Methods.GET,
],
)
GUI = HelpMethodInfo(consts.rest.GUI, 'GUI information', [types.rest.HelpNode.Methods.GET])
GUI_TYPES = HelpMethodInfo(
f'{consts.rest.GUI}/<type>', 'GUI Types information', [types.rest.HelpNode.Methods.GET]
)
@dataclasses.dataclass
@dataclasses.dataclass(frozen=True)
class HelpInfo:
level: int
path: str
text: str
methods: list[HelpMethod]
method: types.rest.HelpNode.Methods = types.rest.HelpNode.Methods.GET
@property
def is_empty(self) -> bool:
return not self.path
def as_dict(self) -> dict[str, str]:
return {
'path': self.path,
'text': self.text,
'method': self.method.value,
}
class Documentation(View):
@ -99,48 +143,36 @@ class Documentation(View):
help_data: list[HelpInfo] = []
def _process_node(node: 'types.rest.HelpNode', path: str, level: int) -> None:
if node.kind == types.rest.HelpNode.HelpNodeType.MODEL:
methods = [
HelpMethod.OVERVIEW,
HelpMethod.GUI,
HelpMethod.GUI_TYPES,
HelpMethod.TYPES,
HelpMethod.TYPES_TYPE,
HelpMethod.TABLEINFO,
HelpMethod.ITEM,
HelpMethod.LOG,
]
elif node.kind == types.rest.HelpNode.HelpNodeType.DETAIL:
methods = [
HelpMethod.OVERVIEW,
HelpMethod.GUI,
HelpMethod.GUI_TYPES,
HelpMethod.TYPES,
HelpMethod.TYPES_TYPE,
HelpMethod.TABLEINFO,
HelpMethod.ITEM,
HelpMethod.LOG,
]
else:
methods = []
if node.kind != types.rest.HelpNode.HelpNodeType.PATH:
help_data.append(HelpInfo(level, path, node.help.text, methods))
def _process_node(node: 'types.rest.HelpNode', path: str) -> None:
match node.kind:
case types.rest.HelpNode.Type.PATH:
pass
case types.rest.HelpNode.Type.MODEL | types.rest.HelpNode.Type.DETAIL:
for func in [
HelpMethod.OVERVIEW,
HelpMethod.GUI,
HelpMethod.GUI_TYPES,
HelpMethod.TYPES,
HelpMethod.TYPES_TYPE,
HelpMethod.TABLEINFO,
HelpMethod.ITEM,
HelpMethod.LOG,
]:
for method in func.value.methods:
help_data.append(HelpInfo(f'{path}/{func.value.method}', func.value.text, method))
case _:
for method in node.methods:
help_data.append(HelpInfo(path, node.help.text, method))
for child in node.children:
_process_node(
child,
child.help.path,
level + (0 if node.kind == types.rest.HelpNode.HelpNodeType.PATH else 1),
)
_process_node(child, child.help.path)
_process_node(Dispatcher.base_handler_node.help_node(), '', 0)
_process_node(Dispatcher.base_handler_node.help_node(), '')
response = render(
request=request,
template_name='uds/modern/documentation.html',
context={'help': [h for h in help_data if not h.is_empty]},
context={'help': [h.as_dict() for h in help_data]},
)
return response

View File

@ -159,22 +159,30 @@ class HelpPath:
@dataclasses.dataclass(frozen=True)
class HelpNode:
class HelpNodeType(enum.StrEnum):
class Type(enum.StrEnum):
MODEL = 'model'
DETAIL = 'detail'
CUSTOM = 'custom'
PATH = 'path'
class Methods(enum.StrEnum):
GET = 'GET'
POST = 'POST'
PUT = 'PUT'
DELETE = 'DELETE'
PATCH = 'PATCH'
help: HelpPath
children: list['HelpNode'] # Children nodes
kind: HelpNodeType
kind: Type
methods: set[Methods] = dataclasses.field(default_factory=lambda: {HelpNode.Methods.GET})
def __hash__(self) -> int:
return hash(self.help.path)
return hash(self.help.path + ''.join(method for method in self.methods))
def __eq__(self, other: object) -> bool:
if isinstance(other, HelpNode):
return self.help.path == other.help.path
return self.help.path == other.help.path and self.methods == other.methods
if not isinstance(other, HelpPath):
return False
@ -237,12 +245,12 @@ class HandlerNode:
custom_help: set[HelpNode] = set()
help_node_type = HelpNode.HelpNodeType.PATH
help_node_type = HelpNode.Type.PATH
if self.handler:
help_node_type = HelpNode.HelpNodeType.CUSTOM
help_node_type = HelpNode.Type.CUSTOM
if issubclass(self.handler, ModelHandler):
help_node_type = HelpNode.HelpNodeType.MODEL
help_node_type = HelpNode.Type.MODEL
# Add custom_methods
for method in self.handler.custom_methods:
# Method is a Me CustomModelMethod,
@ -252,7 +260,7 @@ class HandlerNode:
HelpNode(
HelpPath(path=self.full_path() + '/' + method.name, help=doc),
[],
HelpNode.HelpNodeType.CUSTOM,
HelpNode.Type.CUSTOM,
)
)
@ -263,7 +271,7 @@ class HandlerNode:
HelpNode(
HelpPath(path=self.full_path() + '/' + method_name, help=''),
[],
HelpNode.HelpNodeType.DETAIL,
HelpNode.Type.DETAIL,
)
)
# Add custom_methods
@ -282,7 +290,7 @@ class HandlerNode:
help=doc,
),
[],
HelpNode.HelpNodeType.CUSTOM,
HelpNode.Type.CUSTOM,
)
)

View File

@ -43,15 +43,7 @@
{% for h in help %}
<div>{{ h }}</div>
<div class="doc-item">
{% if h.methods %}
<div class="doc-item-methods">
{% for m in h.methods %}
<div class="doc-item-method">{{ h.path }}/{{ m.value.method }} : {{ m.value.text }}</div>
{% endfor %}
</div>
{% else %}
<div>{{ h.path }} : {{ h.text }}</div>
{% endif %}
<div>{{ h.path }} : {{ h.text }} {{ h.method }}</div>
</div>
{% endfor %}
</div>