mirror of
https://github.com/Casvt/MIND.git
synced 2026-02-19 11:54:46 -05:00
218 lines
5.7 KiB
Python
218 lines
5.7 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
"""
|
|
Process apprise.Apprise().details() output for URL builder.
|
|
"""
|
|
|
|
from itertools import chain
|
|
from re import compile
|
|
from typing import Any, Dict, List, Tuple, Union
|
|
|
|
from apprise import Apprise
|
|
|
|
from backend.base.helpers import when_not_none
|
|
|
|
remove_named_groups = compile(r'(?<=\()\?P<\w+>')
|
|
IGNORED_ARGS = {'cto', 'format', 'overflow', 'rto', 'verify'}
|
|
CUSTOM_URL_SCHEMA = {
|
|
"service_name": "Custom URL",
|
|
"setup_url": "https://github.com/caronc/apprise#supported-notifications",
|
|
"details": {
|
|
"templates": ("{url}",),
|
|
"tokens": {
|
|
"url": {
|
|
"name": "Apprise URL",
|
|
"type": "string",
|
|
"required": True
|
|
}
|
|
},
|
|
"args": {}
|
|
}
|
|
}
|
|
|
|
|
|
def _process_regex(
|
|
regex: Union[Tuple[str, str], None]
|
|
) -> Union[Tuple[str, str], None]:
|
|
return when_not_none(
|
|
regex,
|
|
lambda r: (remove_named_groups.sub('', r[0]), r[1])
|
|
)
|
|
|
|
|
|
def _process_list(
|
|
token_name: str,
|
|
token_details: Dict[str, Any],
|
|
all_tokens: Dict[str, Dict[str, Any]]
|
|
) -> Dict[str, Any]:
|
|
list_entry = {
|
|
'name': token_details['name'],
|
|
'map_to': token_name,
|
|
'required': token_details['required'],
|
|
'type': 'list',
|
|
'delim': token_details['delim'][0],
|
|
'content': []
|
|
}
|
|
|
|
for content in token_details['group']:
|
|
token = all_tokens[content]
|
|
list_entry['content'].append({
|
|
'name': token['name'],
|
|
'required': token['required'],
|
|
'type': token['type'],
|
|
'prefix': token.get('prefix'),
|
|
'regex': _process_regex(token.get('regex'))
|
|
})
|
|
|
|
return list_entry
|
|
|
|
|
|
def _process_normal_token(
|
|
token_name: str,
|
|
token_details: Dict[str, Any]
|
|
) -> Dict[str, Any]:
|
|
normal_entry = {
|
|
'name': token_details['name'],
|
|
'map_to': token_name,
|
|
'required': token_details['required'],
|
|
'type': token_details['type'].split(':')[0]
|
|
}
|
|
|
|
if token_details['type'].startswith('choice'):
|
|
normal_entry.update({
|
|
'options': token_details.get('values'),
|
|
'default': token_details.get('default')
|
|
})
|
|
|
|
else:
|
|
normal_entry.update({
|
|
'prefix': token_details.get('prefix'),
|
|
'min': token_details.get('min'),
|
|
'max': token_details.get('max'),
|
|
'regex': _process_regex(token_details.get('regex'))
|
|
})
|
|
|
|
return normal_entry
|
|
|
|
|
|
def _process_arg(
|
|
arg_name: str,
|
|
arg_details: Dict[str, Any]
|
|
) -> Dict[str, Any]:
|
|
args_entry = {
|
|
'name': arg_details.get('name', arg_name),
|
|
'map_to': arg_name,
|
|
'required': arg_details.get('required', False),
|
|
'type': arg_details['type'].split(':')[0],
|
|
}
|
|
|
|
if arg_details['type'].startswith('list'):
|
|
args_entry.update({
|
|
'delim': arg_details['delim'][0],
|
|
'content': []
|
|
})
|
|
|
|
elif arg_details['type'].startswith('choice'):
|
|
args_entry.update({
|
|
'options': arg_details['values'],
|
|
'default': arg_details.get('default')
|
|
})
|
|
|
|
elif arg_details['type'] == 'bool':
|
|
args_entry.update({
|
|
'default': arg_details['default']
|
|
})
|
|
|
|
else:
|
|
args_entry.update({
|
|
'min': arg_details.get('min'),
|
|
'max': arg_details.get('max'),
|
|
'regex': _process_regex(arg_details.get('regex'))
|
|
})
|
|
|
|
return args_entry
|
|
|
|
|
|
def _sort_tokens(t: Dict[str, Any]) -> List[int]:
|
|
result = [
|
|
int(not t['required'])
|
|
]
|
|
|
|
if t['name'] == 'Schema':
|
|
result.append(0)
|
|
|
|
if t['type'] == 'choice':
|
|
result.append(1)
|
|
|
|
elif t['type'] != 'list':
|
|
result.append(2)
|
|
|
|
else:
|
|
result.append(3)
|
|
|
|
return result
|
|
|
|
|
|
def get_apprise_services() -> List[Dict[str, Any]]:
|
|
"""Get a list of all Apprise services, their URL schemas, tokens and
|
|
arguments.
|
|
|
|
Returns:
|
|
List[Dict[str, Any]]: The list.
|
|
"""
|
|
result: List[Dict[str, Any]] = []
|
|
|
|
schemas = Apprise().details()['schemas']
|
|
for schema in chain((CUSTOM_URL_SCHEMA,), schemas):
|
|
entry = {
|
|
'name': str(schema['service_name']),
|
|
'doc_url': schema['setup_url'],
|
|
'details': {
|
|
'templates': schema['details']['templates'],
|
|
'tokens': [],
|
|
'args': []
|
|
}
|
|
}
|
|
|
|
# Process lists and tokens they contain first
|
|
handled_tokens = set()
|
|
for token_name, token_details in schema['details']['tokens'].items():
|
|
if not token_details['type'].startswith('list:'):
|
|
continue
|
|
|
|
list_entry = _process_list(
|
|
token_name, token_details, schema['details']['tokens']
|
|
)
|
|
entry['details']['tokens'].append(list_entry)
|
|
handled_tokens.add(token_name)
|
|
handled_tokens.update(token_details['group'])
|
|
|
|
# Process all other tokens
|
|
entry['details']['tokens'] += [
|
|
_process_normal_token(token_name, token_details)
|
|
for token_name, token_details in schema['details']['tokens'].items()
|
|
if token_name not in handled_tokens
|
|
]
|
|
|
|
# Process args
|
|
entry['details']['args'] += [
|
|
_process_arg(arg_name, arg_details)
|
|
for arg_name, arg_details in schema['details']['args'].items()
|
|
if not (
|
|
arg_details.get('alias_of') is not None
|
|
or arg_name in IGNORED_ARGS
|
|
)
|
|
]
|
|
|
|
# Sort tokens and args
|
|
entry['details']['tokens'].sort(key=_sort_tokens)
|
|
entry['details']['args'].sort(key=_sort_tokens)
|
|
result.append(entry)
|
|
|
|
result.sort(key=lambda s: (
|
|
int(s["name"] != "Custom URL"),
|
|
s["name"].lower()
|
|
))
|
|
|
|
return result
|