rougail/src/rougail/annotator/check.py
2023-11-14 13:00:18 +01:00

168 lines
6.5 KiB
Python

"""Annotate check
Created by:
EOLE (http://eole.orion.education.fr)
Copyright (C) 2005-2018
Forked by:
Cadoles (http://www.cadoles.com)
Copyright (C) 2019-2021
Silique (https://www.silique.fr)
Copyright (C) 2022-2023
distribued with GPL-2 or later license
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""
from typing import List, Any
from copy import copy
from rougail.annotator.target import TargetAnnotator
from rougail.annotator.param import ParamAnnotator
#from rougail.annotator.fill import get_jinja_variable_to_param
from rougail.i18n import _
from rougail.error import DictConsistencyError, display_xmlfiles
INTERNAL_FUNCTIONS = ['valid_in_network', 'valid_differ', 'valid_entier']
class Annotator(TargetAnnotator, ParamAnnotator):
"""Annotate check
"""
level = 40
def __init__(self,
objectspace,
*args,
):
return
self.objectspace = objectspace
self.only_variable = True
self.target_is_uniq = False
self.allow_function = True
self.functions = copy(functions)
self.functions.extend(INTERNAL_FUNCTIONS)
self.functions.extend(self.objectspace.rougailconfig['internal_functions'])
for path_prefix, constraints in self.get_constraints():
if not hasattr(constraints, 'check'):
continue
self.convert_target(constraints.check, path_prefix)
self.convert_param(constraints.check, path_prefix)
self.check_check(constraints)
self.convert_check_jinja(constraints, path_prefix)
self.check_change_warning(constraints)
self.convert_valid_entier(constraints)
self.convert_check(constraints)
del constraints.check
def check_check(self,
constraints,
): # pylint: disable=R0912
"""valid and manage <check>
"""
remove_indexes = []
for check_idx, check in enumerate(constraints.check):
if check.type == 'function' and not check.name in self.functions and not self.objectspace.just_doc:
msg = _(f'cannot find check function "{check.name}"')
raise DictConsistencyError(msg, 1, check.xmlfiles)
if hasattr(check, 'param') and check.param == []:
remove_indexes.append(check_idx)
remove_indexes.sort(reverse=True)
for idx in remove_indexes:
del constraints.check[idx]
def convert_valid_entier(self,
constraints,
) -> None:
"""valid and manage <check>
"""
remove_indexes = []
for check_idx, check in enumerate(constraints.check):
if not check.name == 'valid_entier':
continue
remove_indexes.append(check_idx)
if not hasattr(check, 'param'):
msg = _(f'{check.name} must have, at least, 1 param')
raise DictConsistencyError(msg, 17, check.xmlfiles)
for param in check.param:
if param.type != 'number':
msg = _(f'param in "valid_entier" must be an "integer", not "{param.type}"')
raise DictConsistencyError(msg, 18, check.xmlfiles)
if not hasattr(param, 'name'):
continue
for target in check.target:
if param.name == 'mini':
target.name.min_number = int(param.text)
elif param.name == 'maxi':
target.name.max_number = int(param.text)
else:
msg = _(f'unknown parameter "{param.name}" in check "valid_entier"')
raise DictConsistencyError(msg, 19, check.xmlfiles)
remove_indexes.sort(reverse=True)
for idx in remove_indexes:
del constraints.check[idx]
def convert_check_jinja(self,
constraints,
path_prefix,
) -> None:
"""convert jinja <check> to a function
"""
for check in constraints.check:
if check.type != 'jinja':
continue
if len(check.target) > 1:
msg = _(f'a check with type jinja cannot have more than one target')
raise DictConsistencyError(msg, 92, check.xmlfiles)
if not hasattr(check, 'param'):
check.param = []
jinja_text = check.name
check.name = 'valid_with_jinja'
new_param = self.objectspace.param(check.xmlfiles)
new_param.name = '__internal_jinja'
new_param.text = jinja_text
new_param.type = 'jinja'
check.param.append(new_param)
if path_prefix:
path = check.target[0].name.path.split('.', 1)[-1]
else:
path = check.target[0].name.path
get_jinja_variable_to_param(jinja_text,
self.objectspace,
check,
path_prefix,
check.target[0].name.name,
path,
)
def check_change_warning(self,
constraints,
):
"""convert level to "warnings_only"
"""
for check in constraints.check:
check.warnings_only = check.level == 'warning'
check.level = None
def convert_check(self,
constraints,
) -> None:
"""valid and manage <check>
"""
for check in constraints.check:
for target in check.target:
if not hasattr(target.name, 'validators'):
target.name.validators = []
target.name.validators.append(check)