rougail/src/rougail/annotator/group.py

163 lines
7.1 KiB
Python

"""Annotate group
Created by:
EOLE (http://eole.orion.education.fr)
Copyright (C) 2005-2018
Forked by:
Cadoles (http://www.cadoles.com)
Copyright (C) 2019-2021
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 rougail.i18n import _
from rougail.error import DictConsistencyError
from rougail.utils import normalize_family
class Annotator:
"""Annotate group
"""
level = 10
def __init__(self,
objectspace,
*args,
):
self.objectspace = objectspace
if not hasattr(self.objectspace.space, 'constraints') or \
not hasattr(self.objectspace.space.constraints, 'group'):
return
self.convert_groups()
def convert_groups(self): # pylint: disable=C0111
"""convert groups
"""
# store old leaders family name
cache_paths = {}
for group in self.objectspace.space.constraints.group:
if group.leader in cache_paths:
leader_fam_path = cache_paths[group.leader]
else:
leader_fam_path = self.objectspace.paths.get_variable_family_path(group.leader, group.xmlfiles)
cache_paths[group.leader] = leader_fam_path
follower_names = list(group.follower.keys())
leader = self.objectspace.paths.get_variable(group.leader)
if '.' not in leader_fam_path:
# it's a namespace
ori_leader_family = self.objectspace.space.variables[leader_fam_path]
else:
# it's a sub family
ori_leader_family = self.objectspace.paths.get_family(leader_fam_path,
leader.namespace,
)
has_a_leader = False
for variable in list(ori_leader_family.variable.values()):
if isinstance(variable, self.objectspace.leadership) and \
variable.variable[0].name == leader.name:
# append follower to an existed leadership
leader_space = variable
has_a_leader = True
elif variable.name == leader.name:
# it's a leader
leader_space = self.manage_leader(variable,
group,
ori_leader_family,
)
has_a_leader = True
elif has_a_leader:
# it's should be a follower
self.manage_follower(follower_names.pop(0),
leader_fam_path,
variable,
leader_space,
)
# this variable is not more in ori_leader_family
ori_leader_family.variable.pop(normalize_family(variable.name))
if follower_names == []:
# no more follower
break
else:
joined = '", "'.join(follower_names)
msg = _(f'when parsing leadership, we espect to find those followers "{joined}"')
raise DictConsistencyError(msg, 31, variable.xmlfiles)
del self.objectspace.space.constraints.group
def manage_leader(self,
variable: 'Variable',
group: 'Group',
ori_leader_family,
) -> 'Leadership':
"""manage leader's variable
"""
if variable.multi is not True:
msg = _(f'the variable "{variable.name}" in a group must be multi')
raise DictConsistencyError(msg, 32, variable.xmlfiles)
if hasattr(group, 'name'):
ori_leadership_name = group.name
else:
ori_leadership_name = variable.name
leadership_name = normalize_family(ori_leadership_name)
leader_space = self.objectspace.leadership(variable.xmlfiles)
leader_space.variable = []
leader_space.name = leadership_name
leader_space.hidden = variable.hidden
if variable.hidden:
variable.frozen = True
variable.force_default_on_freeze = True
variable.hidden = None
if hasattr(group, 'description'):
leader_space.doc = group.description
elif variable.name == leadership_name and hasattr(variable, 'description'):
leader_space.doc = variable.description
else:
leader_space.doc = ori_leadership_name
leadership_path = ori_leader_family.path + '.' + leadership_name
self.objectspace.paths.add_leadership(variable.namespace,
leadership_path,
leader_space,
)
ori_leader_family.variable[normalize_family(variable.name)] = leader_space
leader_space.variable.append(variable)
self.objectspace.paths.set_leader(variable.namespace,
ori_leader_family.path,
leadership_name,
normalize_family(variable.name),
)
return leader_space
def manage_follower(self,
follower_name: str,
leader_family_name: str,
variable: 'Variable',
leader_space: 'Leadership',
) -> None:
"""manage follower
"""
if variable.name != follower_name:
msg = _('when parsing leadership, we expect to find the follower '
f'"{follower_name}" but we found "{variable.name}"')
raise DictConsistencyError(msg, 33, variable.xmlfiles)
self.objectspace.paths.set_leader(variable.namespace,
leader_family_name,
leader_space.name,
normalize_family(variable.name),
)
if leader_space.hidden:
variable.frozen = True
variable.force_default_on_freeze = True
leader_space.variable.append(variable)