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.
164 lines
6.2 KiB
164 lines
6.2 KiB
4 years ago
|
# vim: fileencoding=utf-8
|
||
|
#
|
||
|
from .base_format import BaseFormat
|
||
|
from collections import OrderedDict
|
||
|
from pyparsing import originalTextFor, Literal, ZeroOrMore, Word, printables,\
|
||
|
OneOrMore, alphanums, ParseException, pyparsing_unicode,\
|
||
|
Optional, Group
|
||
|
|
||
|
|
||
|
class SambaFormat(BaseFormat):
|
||
|
def __init__(self, document_text: str,
|
||
|
ignore_comments=False,
|
||
|
join_before=False):
|
||
|
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._format = 'samba'
|
||
|
|
||
|
self._last_comments_list = []
|
||
|
self._initialize_parser()
|
||
|
|
||
|
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 _initialize_parser(self):
|
||
|
action_symbols = (Literal('!') | Literal('-'))
|
||
|
|
||
|
comment_symbols = (Literal('#') | Literal(';'))
|
||
|
|
||
|
assignment_symbol = Literal('=')
|
||
|
|
||
|
section_name = originalTextFor(OneOrMore(Word(alphanums+'_')))
|
||
|
|
||
|
self._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))
|
||
|
)
|
||
|
|
||
|
self._parameter_line = (Group(Optional(action_symbols('action'),
|
||
|
default='')
|
||
|
+ parameter_name('name')
|
||
|
)('parameter_name')
|
||
|
+ assignment_symbol.suppress()
|
||
|
+ parameter_value('parameter_value'))
|
||
|
|
||
|
self._parameter_to_delete = (action_symbols('action')
|
||
|
+ parameter_name('name')
|
||
|
)('parameter_name')
|
||
|
|
||
|
self._comment_line = originalTextFor(
|
||
|
comment_symbols
|
||
|
+ ZeroOrMore(Word(
|
||
|
printables
|
||
|
+ pyparsing_unicode.alphanums))
|
||
|
)('comment')
|
||
|
|
||
|
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)
|
||
|
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()
|