You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

152 lines
5.8 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# vim: fileencoding=utf-8
#
from .base_format import Format
from collections import OrderedDict
from pyparsing import Word, Literal, printables, originalTextFor, OneOrMore,\
ParseException, restOfLine, Group, Optional, Regex
class OpenRCFormat(Format):
FORMAT = 'openrc'
EXECUTABLE = False
_initialized = False
comment_symbol = '#'
def __new__(cls, *args, **kwargs):
if not cls._initialized:
cls._initialize_parser()
return super().__new__(cls)
def __init__(self, document_text: str,
template_path,
ignore_comments=False,
join_before=False,
add_header=False,
already_changed=False,
**kwargs):
processing_methods = [self._parse_comment_line,
self._parse_parameter_line,
self._parse_to_delete_line]
super().__init__(processing_methods)
self._ignore_comments = ignore_comments
self._comments_processing = True
self._last_comments_list = []
if add_header and not ignore_comments:
self.header, document_text = self._get_header_and_document_text(
document_text,
template_path,
already_changed=already_changed)
else:
self.header = ''
document_text = document_text.strip()
if document_text == '':
self._document_dictionary = OrderedDict()
else:
document_lines = self._get_list_of_logic_lines(document_text)
self._lines_to_dictionary(document_lines)
def join_template(self, template: "OpenRCFormat") -> None:
'''Метод запускающий наложение шаблона.'''
self._document_dictionary = self._correct_register(template)
self._join(self._document_dictionary,
template._document_dictionary,
self._join_before)
def _correct_register(self, template: "OpenRCFormat") -> dict:
'''Метод для корректировки всех регистров.'''
corrected_dict = OrderedDict()
template_keys = {key[1].lower(): key[1] for key
in template._document_dictionary.keys()}
for key, value in self._document_dictionary.items():
if key[1].lower() in template_keys:
corrected_dict[('', template_keys[key[1].lower()])] = value
else:
corrected_dict[key] = value
return corrected_dict
@classmethod
def _initialize_parser(cls):
'''Метод для инициализации парсеров.'''
parameter_name = Word(printables, excludeChars='=')
parameter_value = originalTextFor(OneOrMore(Word(printables)))
action_symbols = (Literal('!') | Literal('-'))
cls._parameter_line = (Group(Optional(action_symbols,
default='')('action')
+ parameter_name('name'))('parameter_name')
+ Literal('=').suppress()
+ parameter_value('parameter_value'))
cls._parameter_to_delete = (Group(action_symbols('action')
+ parameter_name('name')
)('parameter_name')
+ restOfLine.suppress())
cls._comment_line = originalTextFor(
Literal(cls.comment_symbol)
+ Regex(r'.*'))('comment')
cls._initialized = True
def _parse_parameter_line(self, line):
'''Метод для парсинга строк содержащих параметр.'''
try:
self._item_to_add = OrderedDict()
parsing_result = self._parameter_line.parseString(line)
key_value = (parsing_result.parameter_name.action,
parsing_result.parameter_name.name)
parameter_value = parsing_result.parameter_value
parameter_value = self._last_comments_list + [parameter_value]
self._last_comments_list = []
self._item_to_add[key_value] = parameter_value
self._ready_to_update = True
self._match = True
except ParseException:
return
def _parse_to_delete_line(self, line):
'''Метод для парсинга строк, подлежащих удалению, т.е. для которых
указано имя параметра со знаком !, и опционально присутствует значение
параметра.'''
try:
self._item_to_add = OrderedDict()
parsing_result = self._parameter_to_delete.parseString(line)
if parsing_result.parameter_name.action == '-':
return
key_value = (parsing_result.parameter_name.action,
parsing_result.parameter_name.name)
parameter_value = self._last_comments_list
self._last_comments_list = []
self._item_to_add[key_value] = parameter_value
self._ready_to_update = True
self._match = True
except ParseException:
return
def _parse_comment_line(self, line):
'''Метод для парсинга строк содержащих комментарий.'''
try:
result = self._comment_line.parseString(line)
self._match = True
if not self._ignore_comments:
self._last_comments_list.append(result.comment)
except ParseException:
return