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.

192 lines
7.5 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 originalTextFor, Literal, Word, printables, OneOrMore,\
alphanums, ParseException, Optional, Group, restOfLine
class SambaFormat(Format):
FORMAT = 'samba'
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_section_line,
self._parse_parameter_line,
self._parse_to_delete_line]
super().__init__(processing_methods)
self._current_section = OrderedDict()
self._current_section_name = ''
self._ignore_comments = ignore_comments
self._need_finish = True
self._comments_processing = True
self._join_before = join_before
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)
@classmethod
def _initialize_parser(cls):
action_symbols = (Literal('!') | Literal('-'))
comment_symbols = (Literal(cls.comment_symbol) | Literal(';'))
assignment_symbol = Literal('=')
section_name = originalTextFor(OneOrMore(Word(alphanums+'_')))
cls._section_line = (Literal('[').suppress()
+ Optional(action_symbols, default='')('action')
+ section_name('name') + Literal(']').suppress()
)('section_name')
parameter_name = originalTextFor(
OneOrMore(Word(printables,
excludeChars='='))
)
parameter_value = originalTextFor(
OneOrMore(Word(printables))
)
cls._parameter_line = (Group(Optional(action_symbols('action'),
default='')
+ parameter_name('name')
)('parameter_name')
+ assignment_symbol.suppress()
+ parameter_value('parameter_value'))
cls._parameter_to_delete = (action_symbols('action')
+ parameter_name('name')
)('parameter_name')
cls._comment_line = originalTextFor(
comment_symbols + restOfLine
)('comment')
cls._initialized = True
def _parse_section_line(self, line):
'''Метод для парсинга строк содержащих имя секции.'''
try:
self._item_to_add = OrderedDict()
parsing_result = self._section_line.parseString(line)
self._match = True
if self._current_section_name != '':
if self._current_section_name in \
self._document_dictionary.keys():
self._document_dictionary[self._current_section_name].\
update(self._current_section)
else:
self._item_to_add[self._current_section_name] = \
self._current_section
self._ready_to_update = True
self._current_section = OrderedDict()
self._current_section_name = (parsing_result.action,
parsing_result.name.lower())
if self._last_comments_list != []:
self._current_section['#'] = self._last_comments_list
self._last_comments_list = []
except ParseException:
return
def _parse_parameter_line(self, line):
'''Метод для парсинга строк содержащих параметр.'''
try:
parsing_result = self._parameter_line.parseString(line)
self._match = True
key_value = (parsing_result.parameter_name.action,
parsing_result.parameter_name.name.lower())
parameter_value = parsing_result.parameter_value
parameter_value = self._last_comments_list + [parameter_value]
self._last_comments_list = []
self._current_section[key_value] = parameter_value
except ParseException:
return
def _parse_to_delete_line(self, line):
'''Метод для парсинга строк, подлежащих удалению, т.е. для которых
указано имя параметра со знаком !, и опционально присутствует значение
параметра.'''
try:
parsing_result = self._parameter_to_delete.parseString(line)
self._match = True
if parsing_result.action == '-':
return
key_value = (parsing_result.action,
parsing_result.name.lower())
parameter_value = self._last_comments_list
self._last_comments_list = []
self._current_section[key_value] = parameter_value
except ParseException:
return
def _parse_comment_line(self, line):
'''Метод для парсинга строк содержащих комментарий.'''
try:
parsing_result = self._comment_line.parseString(line)
self._match = True
if not self._ignore_comments:
self._last_comments_list.append(parsing_result.comment.strip())
except ParseException:
return
def _finish_method(self):
'''Метод для завершения парсинга. В данном случае добавляет в итоговый
словарь последнюю разобранную секцию.'''
self._item_to_add = OrderedDict()
if self._current_section_name in self._document_dictionary.keys():
self._document_dictionary[self._current_section_name].update(
self._current_section
)
else:
self._item_to_add[self._current_section_name] =\
self._current_section
self._document_dictionary.update(self._item_to_add)
self._item_to_add = OrderedDict()
self._current_section = OrderedDict()