Added formats
This commit is contained in:
commit
fce2667231
120 changed files with 8905 additions and 0 deletions
5
Makefile
Normal file
5
Makefile
Normal file
|
@ -0,0 +1,5 @@
|
|||
install:
|
||||
sudo python ./setup.py install --single-version-externally-managed --root=/
|
||||
|
||||
test: install
|
||||
pytest
|
0
README.txt
Normal file
0
README.txt
Normal file
0
calculate/__init__.py
Normal file
0
calculate/__init__.py
Normal file
0
calculate/templates/__init__.py
Normal file
0
calculate/templates/__init__.py
Normal file
0
calculate/templates/format/__init__.py
Normal file
0
calculate/templates/format/__init__.py
Normal file
189
calculate/templates/format/base_format.py
Normal file
189
calculate/templates/format/base_format.py
Normal file
|
@ -0,0 +1,189 @@
|
|||
# vim: fileencoding=utf-8
|
||||
#
|
||||
from collections import OrderedDict
|
||||
from jinja2 import Environment, PackageLoader
|
||||
from pprint import pprint
|
||||
try:
|
||||
from lxml.etree.ElementTree import fromstring
|
||||
except ImportError:
|
||||
from xml.etree.ElementTree import fromstring
|
||||
|
||||
|
||||
class BaseFormat():
|
||||
def __init__(self, processing_methods):
|
||||
self._processing_methods = processing_methods
|
||||
self._document_dictionary = OrderedDict()
|
||||
self._item_to_add = OrderedDict()
|
||||
self._format = 'none'
|
||||
|
||||
self.TEMPLATES_DIRECTORY = 'templates'
|
||||
|
||||
self._fatal_error_flag = False
|
||||
self._ready_to_update = False
|
||||
self._match = False
|
||||
|
||||
self._need_finish = False
|
||||
self._comments_processing = False
|
||||
|
||||
self._join_before = False
|
||||
self._join_before_in_areas = False
|
||||
|
||||
# для отладки.
|
||||
self._line_timer = 0
|
||||
|
||||
def _lines_to_dictionary(self, document_lines):
|
||||
# print('Lines processing...')
|
||||
for line in document_lines:
|
||||
# print(self._line_timer, '\t', line)
|
||||
for processing_method in self._processing_methods:
|
||||
processing_method(line)
|
||||
|
||||
if self._fatal_error_flag:
|
||||
# Действия если файл невозможно разобрать.
|
||||
print('Can not parse file.')
|
||||
self._document_dictionary = OrderedDict()
|
||||
return
|
||||
|
||||
if self._is_match():
|
||||
if self._is_ready_to_update():
|
||||
self._document_dictionary.update(self._item_to_add)
|
||||
break
|
||||
else:
|
||||
# Действия если не удалось разобрать строку.
|
||||
print('Line', self._line_timer,
|
||||
'is not correct. Can not parse file.')
|
||||
self._document_dictionary = OrderedDict()
|
||||
return
|
||||
|
||||
self._line_timer += 1
|
||||
|
||||
if self._need_finish:
|
||||
self._finish_method()
|
||||
|
||||
def _parse_xml_to_dictionary(self, xml_document_text):
|
||||
root = fromstring(xml_document_text)
|
||||
self._document_dictionary = self._processing_methods[root.tag](root)
|
||||
|
||||
def print_dictionary(self):
|
||||
pprint(self._document_dictionary)
|
||||
|
||||
def join_template(self, template):
|
||||
self._join(self._document_dictionary,
|
||||
template._document_dictionary,
|
||||
self._join_before)
|
||||
|
||||
def _get_list_of_logic_lines(self, text):
|
||||
list_of_lines = []
|
||||
lines_to_join = []
|
||||
for line in text.splitlines():
|
||||
line = line.strip()
|
||||
if line == '':
|
||||
continue
|
||||
if not line.endswith("\\"):
|
||||
lines_to_join.append(line)
|
||||
joined_line = "".join(lines_to_join)
|
||||
list_of_lines.append(joined_line)
|
||||
lines_to_join = []
|
||||
else:
|
||||
lines_to_join.append(line[:-1])
|
||||
return list_of_lines
|
||||
|
||||
def _join(self, original, template, join_before):
|
||||
if template == OrderedDict():
|
||||
return
|
||||
if join_before:
|
||||
forwarded_items = OrderedDict()
|
||||
for key_value in template:
|
||||
if key_value[0] == '!':
|
||||
# Удаление соответствующего элемента из original.
|
||||
if isinstance(key_value, tuple):
|
||||
item_to_delete = ('',) + key_value[1:]
|
||||
elif isinstance(key_value, str):
|
||||
item_to_delete = key_value[1:]
|
||||
|
||||
if item_to_delete in original.keys():
|
||||
original.pop(item_to_delete)
|
||||
elif key_value[0] == '-':
|
||||
# Замена соответствующего элемента из original.
|
||||
if isinstance(key_value, tuple):
|
||||
item_to_replace = ('',) + key_value[1:]
|
||||
elif isinstance(key_value, str):
|
||||
item_to_replace = key_value[1:]
|
||||
|
||||
if item_to_replace not in original.keys():
|
||||
continue
|
||||
|
||||
if isinstance(template[key_value], dict) and\
|
||||
template[key_value] == OrderedDict():
|
||||
original.pop(item_to_replace)
|
||||
continue
|
||||
|
||||
if self._comments_processing:
|
||||
if '#' in original[item_to_replace]:
|
||||
replaced = OrderedDict({'#':
|
||||
original[item_to_replace]['#']}
|
||||
)
|
||||
replaced.update(template[key_value])
|
||||
else:
|
||||
replaced = template[key_value]
|
||||
|
||||
original[item_to_replace] = replaced
|
||||
else:
|
||||
original[item_to_replace] = template[key_value]
|
||||
|
||||
elif key_value not in original.keys():
|
||||
if isinstance(template[key_value], dict):
|
||||
dictionary_to_add = OrderedDict()
|
||||
self._join(dictionary_to_add,
|
||||
template[key_value],
|
||||
self._join_before_in_areas)
|
||||
if dictionary_to_add != OrderedDict():
|
||||
if not join_before:
|
||||
original[key_value] = dictionary_to_add
|
||||
else:
|
||||
forwarded_items[key_value] = dictionary_to_add
|
||||
else:
|
||||
if not join_before:
|
||||
original[key_value] = template[key_value]
|
||||
else:
|
||||
forwarded_items[key_value] = template[key_value]
|
||||
else:
|
||||
if isinstance(original[key_value], dict) and \
|
||||
isinstance(template[key_value], dict):
|
||||
self._join(original[key_value],
|
||||
template[key_value],
|
||||
self._join_before_in_areas)
|
||||
else:
|
||||
if self._comments_processing:
|
||||
original[key_value][-1] = template[key_value][-1]
|
||||
else:
|
||||
original[key_value] = template[key_value]
|
||||
if join_before:
|
||||
for key_value in reversed(forwarded_items.keys()):
|
||||
original[key_value] = forwarded_items[key_value]
|
||||
original.move_to_end(key_value, last=False)
|
||||
|
||||
def get_document_text(self):
|
||||
file_loader = PackageLoader('calculate.templates.format',
|
||||
self.TEMPLATES_DIRECTORY)
|
||||
formats_environment = Environment(loader=file_loader,
|
||||
trim_blocks=True,
|
||||
lstrip_blocks=True)
|
||||
formats_environment.globals.update(zip=zip)
|
||||
formats_environment.add_extension('jinja2.ext.do')
|
||||
template = formats_environment.get_template(self._format)
|
||||
document_text = template.render(
|
||||
document_dictionary=self._document_dictionary
|
||||
)
|
||||
return document_text
|
||||
|
||||
def _finish_method(self):
|
||||
pass
|
||||
|
||||
def _is_ready_to_update(self):
|
||||
is_ready, self._match = self._ready_to_update, False
|
||||
return is_ready
|
||||
|
||||
def _is_match(self):
|
||||
is_match, self._match = self._match, False
|
||||
return is_match
|
293
calculate/templates/format/bind_format.py
Normal file
293
calculate/templates/format/bind_format.py
Normal file
|
@ -0,0 +1,293 @@
|
|||
# vim: fileencoding=utf-8
|
||||
#
|
||||
# ToDo: добавить проверку того, полностью ли парсился документ. Если отпарсился
|
||||
# не весь файл -- выдаем ошибку.
|
||||
#
|
||||
from .base_format import BaseFormat
|
||||
from collections import OrderedDict
|
||||
from pyparsing import originalTextFor, OneOrMore, Word, alphanums, Literal,\
|
||||
ZeroOrMore, Forward, Optional, Group, restOfLine,\
|
||||
cppStyleComment, Keyword, printables, nums, SkipTo
|
||||
|
||||
|
||||
class BINDFormat(BaseFormat):
|
||||
def __init__(self, document_text: str, ignore_comments=False):
|
||||
processing_methods = []
|
||||
|
||||
super().__init__(processing_methods)
|
||||
|
||||
self._ignore_comments = ignore_comments
|
||||
self._comments_processing = True
|
||||
self._format = 'bind'
|
||||
|
||||
self._last_comments_list = []
|
||||
self._initialize_parser()
|
||||
|
||||
if document_text == '':
|
||||
self._document_dictionary = OrderedDict()
|
||||
else:
|
||||
self._parse_text(document_text)
|
||||
|
||||
def _initialize_parser(self):
|
||||
left_brace = Literal('{')
|
||||
right_brace = Literal('}')
|
||||
semicolon = Literal(';')
|
||||
action_symbols = (Literal('!') |
|
||||
Literal('-'))
|
||||
|
||||
plain_allow = Keyword('allow')
|
||||
drop_allow = Keyword('!allow')
|
||||
replace_allow = Keyword('-allow')
|
||||
allow = (plain_allow | drop_allow | replace_allow)
|
||||
keys = Keyword('keys')
|
||||
inet = Keyword('inet')
|
||||
|
||||
statement = originalTextFor(
|
||||
Word(alphanums+'_-',
|
||||
excludeChars='{};')
|
||||
)
|
||||
|
||||
statement_name = originalTextFor(
|
||||
Word(printables,
|
||||
excludeChars='{};')
|
||||
)
|
||||
|
||||
statement_class = originalTextFor(
|
||||
Word(printables,
|
||||
excludeChars='{};')
|
||||
)
|
||||
|
||||
parameter_value = originalTextFor(
|
||||
Word(printables,
|
||||
excludeChars='{};')
|
||||
)('parameter')
|
||||
|
||||
ip_value = originalTextFor(
|
||||
Word(nums+':./',
|
||||
excludeChars=';{}')
|
||||
)
|
||||
|
||||
# Будущий парсер блока.
|
||||
block = Forward()
|
||||
|
||||
# Для парсинга директивы inet_spec.
|
||||
allow_item = (ip_value | statement_name) + semicolon.suppress()
|
||||
key_item = statement_name + semicolon.suppress()
|
||||
|
||||
allow_group = Group(Group(Optional(action_symbols,
|
||||
default='')('action')
|
||||
+ allow)
|
||||
+ Group(left_brace.suppress()
|
||||
+ ZeroOrMore(allow_item)
|
||||
+ right_brace.suppress()))
|
||||
|
||||
keys_group = Group(Group(Optional(action_symbols, default='')('action')
|
||||
+ keys)
|
||||
+ Group(left_brace.suppress()
|
||||
+ ZeroOrMore(key_item)
|
||||
+ right_brace.suppress()))
|
||||
|
||||
inet_spec = (Group(Optional(action_symbols, default='')('action')
|
||||
+ inet + originalTextFor(SkipTo(allow,
|
||||
include=False)
|
||||
)('parameter')
|
||||
)('name')
|
||||
+ Group(allow_group
|
||||
+ Optional(keys_group)
|
||||
+ semicolon.suppress())('content')
|
||||
).setParseAction(
|
||||
self._add_inet_specline
|
||||
)
|
||||
|
||||
# Для парсинга комментариев.
|
||||
python_style_comment = originalTextFor(Literal('#') + restOfLine)
|
||||
comments = (cppStyleComment |
|
||||
python_style_comment).setParseAction(
|
||||
self._create_comment_list
|
||||
)
|
||||
|
||||
# Для парсинга директивы include.
|
||||
include_line = (Optional(action_symbols, default='')('action')
|
||||
+ Keyword('include')
|
||||
+ Word(printables, excludeChars=';{}')
|
||||
+ Optional(semicolon.suppress())
|
||||
).setParseAction(
|
||||
self._add_include_line
|
||||
)
|
||||
|
||||
# Для парсинга простых директив состоящих из одного
|
||||
# или двух параметров.
|
||||
plain_line = (Group(Optional(action_symbols, default='')('action')
|
||||
+ statement)('name')
|
||||
+ Optional(parameter_value)
|
||||
+ Optional(semicolon.suppress())).setParseAction(
|
||||
self._add_plain_line
|
||||
)
|
||||
|
||||
# Метод для парсинга IP адресов.
|
||||
ip_line = (Group(Optional(action_symbols, default='')('action')
|
||||
+ ip_value
|
||||
+ Optional(semicolon.suppress()))('IP')
|
||||
).setParseAction(self._add_ipline)
|
||||
|
||||
# Парсеры параметров.
|
||||
param_line = (include_line |
|
||||
ip_line |
|
||||
plain_line)
|
||||
|
||||
# Парсер блока параметров.
|
||||
param_block = (Group(Optional(action_symbols, default='')('action')
|
||||
+ statement + Optional(statement_name)
|
||||
+ Optional(statement_class))('name')
|
||||
+ block('content')
|
||||
+ Optional(semicolon.suppress())).setParseAction(
|
||||
self._add_param_block
|
||||
)
|
||||
|
||||
# Виды блочных директив.
|
||||
block_types = (inet_spec | param_block)
|
||||
|
||||
# Парсер параметров с комментариями.
|
||||
# Note: Применение parser.ignore(comments) является причиной странного
|
||||
# поведения парсера, при котором невозможно многократное повторное
|
||||
# применение формата после установки флага ignore_comments.
|
||||
if self._ignore_comments:
|
||||
param_line_with_comments = (ZeroOrMore(comments).suppress()(
|
||||
'comments'
|
||||
)
|
||||
+ param_line('value')
|
||||
).setParseAction(
|
||||
self._add_comments_to_paramline
|
||||
)
|
||||
else:
|
||||
param_line_with_comments = (ZeroOrMore(comments)('comments')
|
||||
+ param_line('value')
|
||||
).setParseAction(
|
||||
self._add_comments_to_paramline
|
||||
)
|
||||
|
||||
# Парсер блока с комментариями.
|
||||
if self._ignore_comments:
|
||||
param_block_with_comments = (ZeroOrMore(comments).suppress()(
|
||||
'comments'
|
||||
)
|
||||
+ block_types('value')
|
||||
).setParseAction(
|
||||
self._add_comments_to_block
|
||||
)
|
||||
else:
|
||||
param_block_with_comments = (ZeroOrMore(comments)('comments')
|
||||
+ block_types('value')
|
||||
).setParseAction(
|
||||
self._add_comments_to_block
|
||||
)
|
||||
|
||||
# Парсер содержимого блоков.
|
||||
block_item = (param_block_with_comments |
|
||||
param_line_with_comments)
|
||||
|
||||
# Для парсинга всего блока с любым содержимым.
|
||||
block << Group(left_brace.suppress() + ZeroOrMore(block_item)
|
||||
+ right_brace.suppress())
|
||||
|
||||
# Парсер всего документа.
|
||||
self._document_parser = OneOrMore(block_item)
|
||||
|
||||
def _parse_text(self, text):
|
||||
parsing_result = self._document_parser.parseString(text, parseAll=True)
|
||||
list_of_elements = parsing_result.asList()
|
||||
for part in list_of_elements:
|
||||
self._join_dictionary(self._document_dictionary,
|
||||
part)
|
||||
|
||||
def _join_dictionary(self, out_dictionary, dictionary_to_add):
|
||||
for key in dictionary_to_add:
|
||||
if dictionary_to_add == OrderedDict():
|
||||
return
|
||||
if key in out_dictionary and\
|
||||
isinstance(dictionary_to_add[key], OrderedDict) and\
|
||||
isinstance(out_dictionary[key], OrderedDict):
|
||||
self._join_dictionary(out_dictionary[key],
|
||||
dictionary_to_add[key])
|
||||
else:
|
||||
out_dictionary[key] = dictionary_to_add[key]
|
||||
|
||||
def _add_plain_line(self, current_parse):
|
||||
name = tuple(current_parse.name.asList())
|
||||
if not current_parse.parameter == '':
|
||||
value = current_parse.parameter
|
||||
else:
|
||||
if current_parse.name.action == '-':
|
||||
return OrderedDict()
|
||||
value = ''
|
||||
|
||||
return OrderedDict({name: [value]})
|
||||
|
||||
def _add_include_line(self, current_parse):
|
||||
name = current_parse.asList()
|
||||
return OrderedDict({tuple(name): ['']})
|
||||
|
||||
def _add_ipline(self, current_parse):
|
||||
ip_value = current_parse.IP
|
||||
return OrderedDict({tuple(ip_value): ['']})
|
||||
|
||||
def _add_inet_specline(self, current_parse):
|
||||
# Удаляем пробельные символы из второго параметра директивы.
|
||||
current_parse.name.parameter = current_parse.name.parameter.strip()
|
||||
block_name = tuple(current_parse.name.asList())
|
||||
block_content = current_parse.content.asList()
|
||||
content = OrderedDict({'#': []})
|
||||
for item in block_content:
|
||||
current_keyword, values = item
|
||||
current_keyword = tuple(current_keyword)
|
||||
content[current_keyword] = values
|
||||
return OrderedDict({block_name: content})
|
||||
|
||||
def _add_param_block(self, current_parse):
|
||||
block_name = tuple(current_parse.name.asList())
|
||||
block_content = current_parse.content.asList()
|
||||
content = OrderedDict({'#': []})
|
||||
|
||||
for item in block_content:
|
||||
self._join_dictionary(content, item)
|
||||
return OrderedDict({block_name: content})
|
||||
|
||||
def _add_comments_to_paramline(self, current_parse):
|
||||
[parameter] = current_parse.value.asList()
|
||||
comments = current_parse.comments
|
||||
if parameter == OrderedDict():
|
||||
if not comments == '':
|
||||
self._last_comments_list.extend(comments.asList())
|
||||
return OrderedDict()
|
||||
|
||||
name = next(iter(parameter))
|
||||
value = parameter[name]
|
||||
|
||||
if not comments == '':
|
||||
comments_list = comments.asList()
|
||||
parameter[name] = (self._last_comments_list
|
||||
+ comments_list + value)
|
||||
self._last_comments_list = []
|
||||
return parameter
|
||||
|
||||
def _add_comments_to_block(self, current_parse):
|
||||
[value] = current_parse.value
|
||||
[block_name] = value
|
||||
block = value[block_name]
|
||||
|
||||
if not current_parse.comments == '':
|
||||
block['#'] = (self._last_comments_list
|
||||
+ current_parse.comments.asList())
|
||||
self._last_comments_list = []
|
||||
else:
|
||||
block.pop('#')
|
||||
return value
|
||||
|
||||
def _create_comment_list(self, current_parse):
|
||||
comments_list = []
|
||||
comments = current_parse.asList()
|
||||
for comment in comments:
|
||||
lines = comment.splitlines()
|
||||
for line in lines:
|
||||
comments_list.append(line.strip())
|
||||
return comments_list
|
150
calculate/templates/format/compiz_format.py
Normal file
150
calculate/templates/format/compiz_format.py
Normal file
|
@ -0,0 +1,150 @@
|
|||
# vim: fileencoding=utf-8
|
||||
#
|
||||
from .base_format import BaseFormat
|
||||
from collections import OrderedDict
|
||||
from pyparsing import originalTextFor, Literal, ZeroOrMore, Word, printables,\
|
||||
OneOrMore, alphanums, ParseException, restOfLine,\
|
||||
pyparsing_unicode, Group, Optional
|
||||
|
||||
|
||||
class CompizFormat(BaseFormat):
|
||||
def __init__(self, document_text: str, ignore_comments=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._ignore_comments = ignore_comments
|
||||
self._comments_processing = True
|
||||
self._need_finish = True
|
||||
self._format = 'compiz'
|
||||
|
||||
self._current_section = OrderedDict()
|
||||
self._current_section_name = ''
|
||||
|
||||
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):
|
||||
section_name = originalTextFor(
|
||||
OneOrMore(Word(alphanums+'_'))
|
||||
)
|
||||
|
||||
action_symbols = (Literal('!') | Literal('-'))
|
||||
|
||||
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 = Word(printables)
|
||||
|
||||
self._parameter_line = (Group(Optional(action_symbols,
|
||||
default='')('action')
|
||||
+ parameter_name('name')
|
||||
)('parameter_name')
|
||||
+ Literal('=').suppress()
|
||||
+ parameter_value('parameter_value'))
|
||||
|
||||
self._parameter_to_delete = (action_symbols('action')
|
||||
+ parameter_name('name')
|
||||
+ restOfLine.suppress())('parameter_name')
|
||||
|
||||
self._comment_line = originalTextFor(
|
||||
Literal('#')
|
||||
+ 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)
|
||||
self._current_section = OrderedDict()
|
||||
else:
|
||||
self._item_to_add[self._current_section_name] = \
|
||||
self._current_section
|
||||
self._current_section = OrderedDict()
|
||||
self._ready_to_update = True
|
||||
|
||||
self._current_section_name = tuple(
|
||||
parsing_result.section_name.asList()
|
||||
)
|
||||
|
||||
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 = tuple(parsing_result.parameter_name.asList())
|
||||
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 = tuple(parsing_result.parameter_name.asList())
|
||||
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):
|
||||
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._current_section = OrderedDict()
|
62
calculate/templates/format/diff_format.py
Normal file
62
calculate/templates/format/diff_format.py
Normal file
|
@ -0,0 +1,62 @@
|
|||
# vim: fileencoding=utf-8
|
||||
#
|
||||
from calculate.utils.files import Process
|
||||
from os import path
|
||||
|
||||
|
||||
class DiffFormat():
|
||||
def __init__(self, document_text: str):
|
||||
self._patch_text = document_text
|
||||
self._root_path = ''
|
||||
self._last_level = 0
|
||||
|
||||
# вынести в более общий класс или куда-то еще.
|
||||
self._changed_files_list = []
|
||||
|
||||
def execute_format(self, root_path):
|
||||
if path.exists(root_path):
|
||||
self._root_path = root_path
|
||||
else:
|
||||
# Какая-то обработка ошибки.
|
||||
error_message = 'Root path does not exist.'
|
||||
print(error_message)
|
||||
return False
|
||||
|
||||
if self._patch_text:
|
||||
return self._patch_document()
|
||||
else:
|
||||
# Какая-то обработка ошибки.
|
||||
error_message = 'Empty patch file.'
|
||||
print(error_message)
|
||||
return False
|
||||
|
||||
def _patch_document(self):
|
||||
for level in range(0, 4):
|
||||
patch_dry_run = Process('patch', '--dry-run',
|
||||
'-p{}'.format(level), cwd=self._root_path)
|
||||
patch_dry_run.write(self._patch_text)
|
||||
if patch_dry_run.success():
|
||||
break
|
||||
|
||||
patch_dry_run = Process('patch', '-R', '--dry-run',
|
||||
'-p{}'.format(level), cwd=self._root_path)
|
||||
patch_dry_run.write(self._patch_text)
|
||||
if patch_dry_run.success():
|
||||
return ''
|
||||
else:
|
||||
# Какая-то обработка ошибки.
|
||||
error_message = 'Correction failed.'
|
||||
print(error_message)
|
||||
return False
|
||||
|
||||
self._last_level = level
|
||||
patch_run = Process('patch', '-p{}'.format(level), cwd=self._root_path)
|
||||
patch_run.write(self._patch_text)
|
||||
|
||||
if patch_run.success():
|
||||
for line in patch_run:
|
||||
if line.startswith('patching file'):
|
||||
self._changed_files_list.append(line[13:].strip())
|
||||
return patch_run.read()
|
||||
else:
|
||||
return ''
|
229
calculate/templates/format/dovecot_format.py
Normal file
229
calculate/templates/format/dovecot_format.py
Normal file
|
@ -0,0 +1,229 @@
|
|||
# vim: fileencoding=utf-8
|
||||
#
|
||||
# ToDo: написать счетчик скобок для финальной оценки корректности
|
||||
# документа.
|
||||
#
|
||||
from .base_format import BaseFormat
|
||||
from collections import OrderedDict
|
||||
from pyparsing import originalTextFor, Literal, ZeroOrMore, Word, printables,\
|
||||
OneOrMore, alphanums, ParseException, pyparsing_unicode,\
|
||||
Group, Optional, alphas, lineEnd, lineStart, Keyword
|
||||
|
||||
|
||||
class DovecotFormat(BaseFormat):
|
||||
def __init__(self, document_text: str, ignore_comments=False):
|
||||
processing_methods = [self._parse_comment_line,
|
||||
self._parse_section_start_line,
|
||||
self._parse_include_line,
|
||||
self._parse_section_end_line,
|
||||
self._parse_parameter_line,
|
||||
self._parse_parameter_to_delete_line]
|
||||
|
||||
super().__init__(processing_methods)
|
||||
self._ignore_comments = ignore_comments
|
||||
self._need_finish = True
|
||||
self._comments_processing = True
|
||||
self._format = 'dovecot'
|
||||
|
||||
self._section_stack = OrderedDict()
|
||||
self._current_section_name = ''
|
||||
|
||||
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):
|
||||
# Знаки пунктуации и действий.
|
||||
left_brace = Literal('{')
|
||||
right_brace = Literal('}')
|
||||
action_symbols = (Literal('!') | Literal('-'))
|
||||
|
||||
self._comment_line_parser = originalTextFor(
|
||||
Literal('#')
|
||||
+ ZeroOrMore(Word(
|
||||
printables
|
||||
+ pyparsing_unicode.alphanums)
|
||||
)
|
||||
)('comment')
|
||||
|
||||
# Для парсинга строк с началом секций.
|
||||
section = Word(alphas, alphanums+'-_', excludeChars='{}')
|
||||
|
||||
section_name = Word(printables, excludeChars='{}')
|
||||
|
||||
self._section_start_parser = Group(Optional(action_symbols,
|
||||
default='')('action')
|
||||
+ section
|
||||
+ Optional(section_name)
|
||||
+ left_brace.suppress())('name')
|
||||
|
||||
# Для парсинга строк, указывающих конец секций.
|
||||
self._section_end_parser = lineStart() + right_brace + lineEnd()
|
||||
|
||||
# Для парсинга строк, содержащих параметры.
|
||||
parameter_name = Word(alphas, alphanums+'_-', excludeChars='{}=')
|
||||
|
||||
parameter_value = OneOrMore(Word(printables))
|
||||
|
||||
self._parameter_line_parser = (Group(Optional(action_symbols,
|
||||
default='')('action')
|
||||
+ parameter_name)('name')
|
||||
+ Literal('=').suppress()
|
||||
+ originalTextFor(
|
||||
parameter_value
|
||||
)('value'))
|
||||
|
||||
# Для парсинга строк с параметрами, подлежащими удалению.
|
||||
self._parameter_to_delete_parser = (action_symbols('action')
|
||||
+ parameter_name
|
||||
+ Optional(Literal('=')).suppress()
|
||||
)
|
||||
|
||||
# Для парсинга строк, содержащих директиву !include.
|
||||
include = Keyword('!include') | Keyword('!include_try')
|
||||
|
||||
include_line_plain = (Optional(~action_symbols, default='')('action')
|
||||
+ include('keyword') + Word(printables)('value'))
|
||||
|
||||
include_line_to_delete = (action_symbols('action') + include('keyword')
|
||||
+ Word(printables)('value'))
|
||||
|
||||
self._include_line_parser = (include_line_plain |
|
||||
include_line_to_delete)
|
||||
|
||||
def _parse_section_start_line(self, line):
|
||||
try:
|
||||
parsing_result = self._section_start_parser.parseString(line)
|
||||
self._match = True
|
||||
|
||||
section_name = tuple(parsing_result.name.asList())
|
||||
|
||||
if not self._last_comments_list == []:
|
||||
section_content = OrderedDict({'#': self._last_comments_list})
|
||||
self._last_comments_list = []
|
||||
else:
|
||||
section_content = OrderedDict()
|
||||
|
||||
new_section = OrderedDict({section_name: section_content})
|
||||
|
||||
if self._section_stack == OrderedDict():
|
||||
if section_name in self._document_dictionary:
|
||||
new_section = OrderedDict(
|
||||
{section_name:
|
||||
self._document_dictionary[section_name]}
|
||||
)
|
||||
else:
|
||||
if section_name in \
|
||||
self._section_stack[self._current_section_name]:
|
||||
new_section = OrderedDict({
|
||||
section_name:
|
||||
self._section_stack[self._current_section_name]
|
||||
[section_name]
|
||||
})
|
||||
else:
|
||||
self._section_stack[self._current_section_name].update(
|
||||
new_section
|
||||
)
|
||||
self._section_stack.update(new_section)
|
||||
self._current_section_name = section_name
|
||||
except ParseException:
|
||||
return
|
||||
|
||||
def _parse_section_end_line(self, line):
|
||||
try:
|
||||
self._section_end_parser.parseString(line)
|
||||
self._match = True
|
||||
|
||||
last_section_name, last_section = self._section_stack.popitem()
|
||||
|
||||
if self._section_stack == OrderedDict():
|
||||
self._item_to_add = OrderedDict({last_section_name:
|
||||
last_section})
|
||||
self._ready_to_update = True
|
||||
self._current_section_name = ''
|
||||
else:
|
||||
self._current_section_name = next(reversed(
|
||||
self._section_stack
|
||||
))
|
||||
except ParseException:
|
||||
return
|
||||
|
||||
def _parse_parameter_line(self, line):
|
||||
try:
|
||||
parsing_result = self._parameter_line_parser.parseString(line)
|
||||
self._match = True
|
||||
|
||||
parameter_name = tuple(parsing_result.name.asList())
|
||||
parameter_value = (self._last_comments_list
|
||||
+ [parsing_result.value.strip()])
|
||||
self._last_comments_list = []
|
||||
parameter = OrderedDict({parameter_name: parameter_value})
|
||||
|
||||
if self._section_stack == OrderedDict():
|
||||
self._item_to_add = parameter
|
||||
self._ready_to_update = True
|
||||
else:
|
||||
self._section_stack[self._current_section_name].update(
|
||||
parameter
|
||||
)
|
||||
except ParseException:
|
||||
return
|
||||
|
||||
def _parse_parameter_to_delete_line(self, line):
|
||||
try:
|
||||
parsing_result = self._parameter_to_delete_parser.parseString(line)
|
||||
self._match = True
|
||||
|
||||
parameter_name = tuple(parsing_result.asList())
|
||||
parameter_value = self._last_comments_list + ['']
|
||||
self._last_comments_list = []
|
||||
parameter = OrderedDict({parameter_name: parameter_value})
|
||||
|
||||
if self._section_stack == OrderedDict():
|
||||
self._item_to_add = parameter
|
||||
self._ready_to_update = True
|
||||
else:
|
||||
self._section_stack[self._current_section_name].update(
|
||||
parameter
|
||||
)
|
||||
except ParseException:
|
||||
return
|
||||
|
||||
def _parse_include_line(self, line):
|
||||
try:
|
||||
parsing_result = self._include_line_parser.parseString(line)
|
||||
self._match = True
|
||||
|
||||
parameter_name = tuple(parsing_result.asList())
|
||||
|
||||
if parsing_result.action == '-':
|
||||
return
|
||||
|
||||
parameter_value = self._last_comments_list + ['']
|
||||
self._last_comments_list = []
|
||||
include_item = OrderedDict({parameter_name: parameter_value})
|
||||
|
||||
if self._section_stack == OrderedDict():
|
||||
self._item_to_add = include_item
|
||||
self._ready_to_update = True
|
||||
else:
|
||||
self._section_stack[self._current_section_name].update(
|
||||
include_item
|
||||
)
|
||||
except ParseException:
|
||||
return
|
||||
|
||||
def _parse_comment_line(self, line):
|
||||
try:
|
||||
parsing_result = self._comment_line_parser.parseString(line)
|
||||
self._match = True
|
||||
|
||||
if not self._ignore_comments:
|
||||
self._last_comments_list.append(parsing_result.comment)
|
||||
except ParseException:
|
||||
return
|
26
calculate/templates/format/json_format.py
Normal file
26
calculate/templates/format/json_format.py
Normal file
|
@ -0,0 +1,26 @@
|
|||
# vim: fileencoding=utf-8
|
||||
#
|
||||
from .base_format import BaseFormat
|
||||
from collections import OrderedDict
|
||||
import json
|
||||
|
||||
|
||||
class JSONFormat(BaseFormat):
|
||||
def __init__(self, document_text: str, ignore_comments=False):
|
||||
processing_methods = []
|
||||
super().__init__(processing_methods)
|
||||
self._ignore_comments = ignore_comments
|
||||
self._format = 'json'
|
||||
|
||||
if document_text == '':
|
||||
self._document_dictionary = OrderedDict()
|
||||
else:
|
||||
self._text_to_dictionary(document_text)
|
||||
|
||||
def _text_to_dictionary(self, json_file_text):
|
||||
self._document_dictionary = json.loads(json_file_text,
|
||||
object_pairs_hook=OrderedDict)
|
||||
|
||||
def get_document_text(self):
|
||||
json_file_text = json.dumps(self._document_dictionary, indent=4)
|
||||
return json_file_text
|
155
calculate/templates/format/kde_format.py
Normal file
155
calculate/templates/format/kde_format.py
Normal file
|
@ -0,0 +1,155 @@
|
|||
# vim: fileencoding=utf-8
|
||||
#
|
||||
from .base_format import BaseFormat
|
||||
from collections import OrderedDict
|
||||
from pyparsing import originalTextFor, Literal, ZeroOrMore, Word, printables,\
|
||||
OneOrMore, alphanums, ParseException, restOfLine,\
|
||||
pyparsing_unicode, Group, Optional
|
||||
|
||||
|
||||
class KDEFormat(BaseFormat):
|
||||
def __init__(self, document_text: str, ignore_comments=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._ignore_comments = ignore_comments
|
||||
self._comments_processing = True
|
||||
self._need_finish = True
|
||||
self._format = 'kde'
|
||||
|
||||
self._current_section = OrderedDict()
|
||||
self._current_section_name = ''
|
||||
|
||||
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('-'))
|
||||
section_name_part_content = originalTextFor((OneOrMore(
|
||||
Word(alphanums+':'))))
|
||||
|
||||
section_name_part = (Literal('[').suppress()
|
||||
+ section_name_part_content
|
||||
+ Literal(']').suppress())
|
||||
|
||||
self._section_line = (Literal('[').suppress()
|
||||
+ Optional(action_symbols, default='')('action')
|
||||
+ section_name_part_content
|
||||
+ Literal(']').suppress()
|
||||
+ ZeroOrMore(section_name_part))('section_name')
|
||||
|
||||
parameter_name = originalTextFor(
|
||||
OneOrMore(Word(printables,
|
||||
excludeChars='='))
|
||||
)('parameter_name')
|
||||
|
||||
parameter_value = originalTextFor(OneOrMore(Word(
|
||||
pyparsing_unicode.alphanums
|
||||
+ printables))
|
||||
)('parameter_value')
|
||||
|
||||
self._parameter_line = (Group(Optional(action_symbols,
|
||||
default='')('action')
|
||||
+ parameter_name)('parameter_name')
|
||||
+ Literal('=').suppress()
|
||||
+ parameter_value('parameter_value'))
|
||||
|
||||
self._parameter_to_delete = (action_symbols('action')
|
||||
+ parameter_name('name')
|
||||
+ restOfLine.suppress())('parameter_name')
|
||||
|
||||
self._comment_line = originalTextFor(
|
||||
Literal('#')
|
||||
+ 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)
|
||||
self._current_section = OrderedDict()
|
||||
else:
|
||||
self._item_to_add[self._current_section_name] = \
|
||||
self._current_section
|
||||
self._current_section = OrderedDict()
|
||||
self._ready_to_update = True
|
||||
|
||||
self._current_section_name = tuple(
|
||||
parsing_result.section_name.asList()
|
||||
)
|
||||
|
||||
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 = tuple(parsing_result.parameter_name.asList())
|
||||
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 = tuple(parsing_result.parameter_name)
|
||||
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):
|
||||
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._current_section = OrderedDict()
|
100
calculate/templates/format/kernel_format.py
Normal file
100
calculate/templates/format/kernel_format.py
Normal file
|
@ -0,0 +1,100 @@
|
|||
# vim: fileencoding=utf-8
|
||||
#
|
||||
from .base_format import BaseFormat
|
||||
from collections import OrderedDict
|
||||
from pyparsing import Word, Literal, alphanums, printables, originalTextFor,\
|
||||
ZeroOrMore, OneOrMore, ParseException, restOfLine,\
|
||||
pyparsing_unicode, Group, Optional
|
||||
|
||||
|
||||
class KernelFormat(BaseFormat):
|
||||
def __init__(self, document_text: str, ignore_comments=False):
|
||||
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._format = 'kernel'
|
||||
|
||||
self._last_comments_list = []
|
||||
self._initialize_parser()
|
||||
|
||||
if document_text == '':
|
||||
self._document_dictionary = OrderedDict()
|
||||
else:
|
||||
documentLines = self._get_list_of_logic_lines(document_text)
|
||||
self._lines_to_dictionary(documentLines)
|
||||
|
||||
def _initialize_parser(self):
|
||||
parameter_name = Word(alphanums+'_')('parameter_name')
|
||||
|
||||
parameter_value = originalTextFor(
|
||||
OneOrMore(Word(printables))
|
||||
)('parameter_value')
|
||||
|
||||
action_symbols = (Literal('!') | Literal('-'))
|
||||
|
||||
self._parameter_line = (Group(Optional(action_symbols,
|
||||
default='')('action')
|
||||
+ parameter_name('name')
|
||||
)('parameter_name')
|
||||
+ Literal('=').suppress()
|
||||
+ parameter_value('parameter_value'))
|
||||
|
||||
self._parameter_to_delete = (Group(action_symbols('action')
|
||||
+ parameter_name('name')
|
||||
)('parameter_name')
|
||||
+ restOfLine.suppress())
|
||||
|
||||
self._comment_line = originalTextFor(
|
||||
Literal('#').suppress()
|
||||
+ ZeroOrMore(Word(printables
|
||||
+ pyparsing_unicode.alphanums))
|
||||
)('Comment')
|
||||
|
||||
def _parse_parameter_line(self, line):
|
||||
try:
|
||||
self._item_to_add = OrderedDict()
|
||||
parsing_result = self._parameter_line.parseString(line)
|
||||
|
||||
key_value = tuple(parsing_result.parameter_name.asList())
|
||||
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.action == '-':
|
||||
return
|
||||
|
||||
key_value = (parsing_result.parameter_name.action,
|
||||
parsing_result.parameter_name.name.upper())
|
||||
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
|
522
calculate/templates/format/ldap_format.py
Normal file
522
calculate/templates/format/ldap_format.py
Normal file
|
@ -0,0 +1,522 @@
|
|||
# vim: fileencoding=utf-8
|
||||
#
|
||||
from .base_format import BaseFormat
|
||||
from collections import OrderedDict
|
||||
from pyparsing import originalTextFor, Literal, ZeroOrMore, Word, printables,\
|
||||
OneOrMore, alphanums, ParseException, restOfLine,\
|
||||
pyparsing_unicode, nums, delimitedList, Optional,\
|
||||
Keyword, SkipTo, Group
|
||||
|
||||
|
||||
class LDAPFormat(BaseFormat):
|
||||
def __init__(self, document_text: str, ignore_comments=False):
|
||||
processing_methods = [self._parse_comment_line,
|
||||
self._parse_type_line,
|
||||
self._parse_access_line,
|
||||
self._parse_access_line_to_delete,
|
||||
self._parse_syncrepl_line,
|
||||
self._parse_syncrepl_line_to_delete,
|
||||
self._parse_notunique_line,
|
||||
self._parse_index_line,
|
||||
self._parse_index_line_to_delete,
|
||||
self._parse_plain_directive_line,
|
||||
self._parse_plain_directive_line_to_delete]
|
||||
|
||||
super().__init__(processing_methods)
|
||||
self._ignore_comments = ignore_comments
|
||||
self._comments_processing = True
|
||||
self._need_finish = True
|
||||
self._format = 'ldap'
|
||||
|
||||
if self._ignore_comments:
|
||||
self._current_type_section = OrderedDict()
|
||||
else:
|
||||
self._current_type_section = OrderedDict({'#': []})
|
||||
|
||||
self._current_type = ('', 'global')
|
||||
|
||||
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):
|
||||
self._comment_line = originalTextFor(
|
||||
Literal('#')
|
||||
+ ZeroOrMore(Word(printables
|
||||
+ pyparsing_unicode.alphanums))
|
||||
)('comment')
|
||||
|
||||
action_symbols = (Literal('!') | Literal('-'))
|
||||
assignment = Literal('=')
|
||||
|
||||
# Для парсинга строк c директивами неуникальными для секции.
|
||||
not_unique_directives = originalTextFor(
|
||||
Keyword('include') |
|
||||
Keyword('moduleload')
|
||||
)
|
||||
|
||||
not_unique_value = originalTextFor(
|
||||
OneOrMore(Word(printables))
|
||||
)('value')
|
||||
|
||||
self._not_unique_parser = (Optional(action_symbols,
|
||||
default='')('action')
|
||||
+ not_unique_directives
|
||||
+ not_unique_value + restOfLine.suppress())
|
||||
|
||||
# Для выделения областей global, backend и database.
|
||||
type_sections_keywords = originalTextFor(
|
||||
Keyword('backend') |
|
||||
Keyword('database')
|
||||
)
|
||||
|
||||
type_value = originalTextFor(Word(alphanums))
|
||||
|
||||
self._type_line = (Optional(action_symbols, default='')('action')
|
||||
+ type_sections_keywords
|
||||
+ type_value
|
||||
+ restOfLine.suppress())
|
||||
|
||||
# Для парсинга конструкции syncrepl rid=<replica ID> <parameters>
|
||||
content_without_spaces = Word(printables, excludeChars='"')
|
||||
|
||||
content_with_spaces = (Literal('"')
|
||||
+ OneOrMore(Word(printables,
|
||||
excludeChars='"'))
|
||||
+ Literal('"'))
|
||||
|
||||
parameter_without_spaces = (Word(printables, excludeChars='"=')
|
||||
+ assignment.suppress()
|
||||
+ content_without_spaces)
|
||||
|
||||
parameter_with_spaces = (Word(printables, excludeChars='"=')
|
||||
+ assignment.suppress()
|
||||
+ content_with_spaces)
|
||||
|
||||
values = OneOrMore(originalTextFor(parameter_with_spaces |
|
||||
parameter_without_spaces))('Values')
|
||||
|
||||
syncrepl_replica_id = originalTextFor(Literal('rid')
|
||||
+ assignment.suppress()
|
||||
+ Word(nums))('replicaID')
|
||||
|
||||
self._syncrepl_line_parser = (Group(Optional(action_symbols,
|
||||
default='')('action')
|
||||
+ Keyword('syncrepl')
|
||||
+ syncrepl_replica_id)('name')
|
||||
+ values('Values')
|
||||
+ restOfLine.suppress())
|
||||
|
||||
self._syncrepl_value_parser = (Group(Optional(action_symbols,
|
||||
default='')('action')
|
||||
+ originalTextFor(
|
||||
Word(
|
||||
printables,
|
||||
excludeChars='"='
|
||||
)
|
||||
))('name')
|
||||
+ assignment.suppress()
|
||||
+ originalTextFor(
|
||||
OneOrMore(
|
||||
Word(printables)
|
||||
)
|
||||
)('value'))
|
||||
|
||||
self._syncrepl_line_to_delete_parser = (Group(Optional(
|
||||
action_symbols,
|
||||
default=''
|
||||
)('action')
|
||||
+ Keyword('syncrepl')
|
||||
+ syncrepl_replica_id)('name')
|
||||
+ restOfLine.suppress())
|
||||
|
||||
# Для парсинга конструкции
|
||||
# access to <what> by <who>|<access level>|<control>
|
||||
access_keyword = originalTextFor(Literal('access to'))('keyword')
|
||||
|
||||
value = originalTextFor(parameter_with_spaces |
|
||||
parameter_without_spaces |
|
||||
content_without_spaces |
|
||||
content_with_spaces)
|
||||
|
||||
self._access_line_parser = (Group(Optional(action_symbols,
|
||||
default='')('action')
|
||||
+ access_keyword
|
||||
+ value)('name')
|
||||
+ Keyword('by').suppress()
|
||||
+ delimitedList(
|
||||
originalTextFor(value +
|
||||
SkipTo(
|
||||
Keyword('by'),
|
||||
include=False) |
|
||||
restOfLine
|
||||
),
|
||||
delim='by'
|
||||
)('Values'))
|
||||
|
||||
self._access_value_parser = (Group(Optional(action_symbols,
|
||||
default='')('action')
|
||||
+ originalTextFor(value))('name')
|
||||
+ originalTextFor(
|
||||
Optional(Word(alphanums))
|
||||
)('value'))
|
||||
|
||||
self._access_line_to_delete_parser = (Group(action_symbols('action')
|
||||
+ access_keyword
|
||||
+ value
|
||||
+ restOfLine.suppress())('name'))
|
||||
|
||||
# Для парсинга строк с директивами index.
|
||||
self._index_line_parser = (Group(Optional(action_symbols,
|
||||
default='')('action')
|
||||
+ Keyword('index')
|
||||
+ originalTextFor(Word(printables))
|
||||
)('name')
|
||||
+ originalTextFor(
|
||||
OneOrMore(Word(printables))
|
||||
)('value'))
|
||||
|
||||
self._index_line_to_delete_parser = (Group(action_symbols('action')
|
||||
+ Keyword('index')
|
||||
+ originalTextFor(
|
||||
Word(printables)
|
||||
))('name'))
|
||||
|
||||
# Для парсинга остальных директив.
|
||||
self._directive_line_parser = (Group(Optional(action_symbols,
|
||||
default='')('action')
|
||||
+ originalTextFor(
|
||||
Word(printables)
|
||||
))('name')
|
||||
+ originalTextFor(
|
||||
OneOrMore(Word(
|
||||
printables
|
||||
)
|
||||
))('value'))
|
||||
|
||||
self._directive_line_to_delete_parser = (action_symbols('action')
|
||||
+ originalTextFor(
|
||||
Word(printables)
|
||||
))('name')
|
||||
|
||||
def _get_list_of_logic_lines(self, text):
|
||||
list_of_lines = []
|
||||
lines_to_join = []
|
||||
for line in text.splitlines():
|
||||
if line.strip() == '':
|
||||
continue
|
||||
|
||||
if not line.startswith(' ') and not line.startswith('\t'):
|
||||
joined_line = "".join(lines_to_join)
|
||||
if joined_line != '':
|
||||
list_of_lines.append(joined_line)
|
||||
lines_to_join = []
|
||||
|
||||
line.strip()
|
||||
else:
|
||||
line = ' ' + line.strip()
|
||||
|
||||
lines_to_join.append(line)
|
||||
|
||||
joined_line = "".join(lines_to_join)
|
||||
list_of_lines.append(joined_line)
|
||||
|
||||
return list_of_lines
|
||||
|
||||
def _parse_type_line(self, line):
|
||||
try:
|
||||
self._item_to_add = OrderedDict()
|
||||
parsing_result = self._type_line.parseString(line)
|
||||
self._match = True
|
||||
|
||||
type_name = tuple(parsing_result.asList())
|
||||
|
||||
if self._current_type in self._document_dictionary.keys():
|
||||
self._document_dictionary[self._current_type].update(
|
||||
self._current_type_section
|
||||
)
|
||||
else:
|
||||
self._item_to_add[self._current_type] =\
|
||||
self._current_type_section
|
||||
self._ready_to_update = True
|
||||
|
||||
# Если глобальная область пуста -- передаем ее комментарии
|
||||
# следующей за ней области.
|
||||
if self._current_type == ('', 'global') and\
|
||||
list(self._current_type_section.keys()) == ['#']:
|
||||
self._last_comments_list = self._current_type_section['#']
|
||||
self._item_to_add[self._current_type] = OrderedDict()
|
||||
|
||||
self._current_type_section = OrderedDict()
|
||||
self._current_type = type_name
|
||||
|
||||
if self._last_comments_list != []:
|
||||
self._current_type_section['#'] = self._last_comments_list
|
||||
self._last_comments_list = []
|
||||
except ParseException:
|
||||
return
|
||||
|
||||
def _parse_notunique_line(self, line):
|
||||
'''Метод для парсинга строк c директивами неуникальными для секции.
|
||||
Аргументы: line -- строка, которую нужно распарсить.
|
||||
'''
|
||||
try:
|
||||
self._item_to_add = OrderedDict()
|
||||
parsing_result = self._not_unique_parser.parseString(line)
|
||||
self._match = True
|
||||
|
||||
parsing_result.value = parsing_result.value.strip()
|
||||
|
||||
not_unique_name = tuple(parsing_result.asList())
|
||||
parameter_value = ['']
|
||||
|
||||
parameter_value = self._last_comments_list + parameter_value
|
||||
self._last_comments_list = []
|
||||
self._current_type_section[not_unique_name] = parameter_value
|
||||
except ParseException:
|
||||
return
|
||||
|
||||
def _parse_access_line(self, line):
|
||||
'''Метод для парсинга строк содержащих конструкцию
|
||||
access to <what> by <who>|<access level>|<control>.
|
||||
Аргументы: line -- строка, которую нужно распарсить.
|
||||
'''
|
||||
try:
|
||||
parsing_result = self._access_line_parser.parseString(line)
|
||||
self._match = True
|
||||
|
||||
values = [value.strip() for value in
|
||||
parsing_result.Values.asList()]
|
||||
values.reverse()
|
||||
|
||||
parameter_name = tuple(parsing_result.name)
|
||||
|
||||
value_dictionary = OrderedDict()
|
||||
if self._last_comments_list != []:
|
||||
value_dictionary['#'] = self._last_comments_list
|
||||
self._last_comments_list = []
|
||||
|
||||
for value in values:
|
||||
try:
|
||||
value_parsing = self._access_value_parser.\
|
||||
parseString(value)
|
||||
|
||||
param_name = tuple(value_parsing.name)
|
||||
param_value = value_parsing.value
|
||||
value_dictionary[param_name] = [param_value]
|
||||
except ParseException:
|
||||
continue
|
||||
|
||||
parameter_value = value_dictionary
|
||||
|
||||
if parameter_name in self._current_type_section.keys():
|
||||
self._current_type_section[parameter_name].update(
|
||||
value_dictionary
|
||||
)
|
||||
else:
|
||||
self._current_type_section[parameter_name] = parameter_value
|
||||
except ParseException:
|
||||
return
|
||||
|
||||
def _parse_access_line_to_delete(self, line):
|
||||
'''Метод для парсинга строк, предписывающих удаление конструкций
|
||||
access to, если указано только ее название и значение What.
|
||||
Аргументы: line -- строка, которую нужно распарсить.
|
||||
'''
|
||||
try:
|
||||
parsing_result = self._access_line_to_delete_parser.parseString(
|
||||
line
|
||||
)
|
||||
self._match = True
|
||||
|
||||
parameter_name = tuple(parsing_result.name.asList())
|
||||
|
||||
if parsing_result.name.action == '-':
|
||||
return
|
||||
|
||||
parameter_value = OrderedDict({'#': self._last_comments_list})
|
||||
self._last_comments_list = []
|
||||
self._current_type_section[parameter_name] = parameter_value
|
||||
except ParseException:
|
||||
return
|
||||
|
||||
def _parse_syncrepl_line(self, line):
|
||||
'''Метод для парсинга строк содержащих конструкцию syncrepl
|
||||
rep=<ReplicaID>.
|
||||
Аргументы: line -- строка, которую нужно распарсить.
|
||||
'''
|
||||
try:
|
||||
parsing_result = self._syncrepl_line_parser.parseString(line)
|
||||
self._match = True
|
||||
|
||||
values = [value.strip() for value in parsing_result.Values.asList()]
|
||||
parameter_name = tuple(parsing_result.name.asList())
|
||||
|
||||
value_dictionary = OrderedDict()
|
||||
if self._last_comments_list != []:
|
||||
value_dictionary['#'] = self._last_comments_list
|
||||
self._last_comments_list = []
|
||||
|
||||
for value in values:
|
||||
try:
|
||||
value_parsing = self._syncrepl_value_parser.parseString(
|
||||
value
|
||||
)
|
||||
param_name = tuple(value_parsing.name.asList())
|
||||
param_value = value_parsing.value
|
||||
value_dictionary[param_name] = [param_value]
|
||||
except ParseException:
|
||||
continue
|
||||
|
||||
parameter_value = value_dictionary
|
||||
|
||||
if parameter_name in self._current_type_section.keys():
|
||||
self._current_type_section[parameter_name].update(
|
||||
value_dictionary
|
||||
)
|
||||
else:
|
||||
self._current_type_section[parameter_name] = parameter_value
|
||||
except ParseException:
|
||||
return
|
||||
|
||||
def _parse_syncrepl_line_to_delete(self, line):
|
||||
'''Метод для парсинга строк, предписывающих удаление конструкций
|
||||
syncrepl rid=<ReplicaID>, если указано только ее название и значение
|
||||
ReplicaID.
|
||||
Аргументы: line -- строка, которую нужно распарсить.
|
||||
'''
|
||||
try:
|
||||
parsing_result = self._syncrepl_line_to_delete_parser.parseString(
|
||||
line
|
||||
)
|
||||
self._match = True
|
||||
|
||||
parameter_name = tuple(parsing_result.name.asList())
|
||||
|
||||
if parsing_result.name.action == '-':
|
||||
return
|
||||
|
||||
parameter_value = OrderedDict({'#': self._last_comments_list})
|
||||
self._last_comments_list = []
|
||||
self._current_type_section[parameter_name] = parameter_value
|
||||
except ParseException:
|
||||
return
|
||||
|
||||
def _parse_index_line(self, line):
|
||||
'''Метод для парсинга строк с директивами index.
|
||||
Аргументы: line -- строка, которую нужно распарсить.
|
||||
'''
|
||||
try:
|
||||
parsing_result = self._index_line_parser.parseString(line)
|
||||
self._match = True
|
||||
|
||||
parameter_name = tuple(parsing_result.name.asList())
|
||||
|
||||
parameter_value = parsing_result.value
|
||||
|
||||
parameter_value = self._last_comments_list + [parameter_value]
|
||||
self._last_comments_list = []
|
||||
self._current_type_section[parameter_name] = parameter_value
|
||||
except ParseException:
|
||||
return
|
||||
|
||||
def _parse_index_line_to_delete(self, line):
|
||||
'''Метод для парсинга строк, предписывающих удаление директив index,
|
||||
если указано только из имя, но отсутвует значение.
|
||||
Аргументы: line -- строка, которую нужно распарсить.
|
||||
'''
|
||||
try:
|
||||
parsing_result = self._index_line_to_delete_parser.parseString(line)
|
||||
self._match = True
|
||||
|
||||
parameter_name = tuple(parsing_result.name.asList())
|
||||
|
||||
if parsing_result.name.action == '-':
|
||||
return
|
||||
|
||||
parameter_value = self._last_comments_list
|
||||
self._last_comments_list = []
|
||||
self._current_type_section[parameter_name] = parameter_value
|
||||
except ParseException:
|
||||
return
|
||||
|
||||
def _parse_plain_directive_line(self, line):
|
||||
'''Метод для парсинга строк с простыми уникальными для секции
|
||||
директивами.
|
||||
Аргументы: line -- строка, которую нужно распарсить.
|
||||
'''
|
||||
try:
|
||||
parsing_result = self._directive_line_parser.parseString(line)
|
||||
self._match = True
|
||||
|
||||
parameter_name = tuple(parsing_result.name.asList())
|
||||
parameter_value = parsing_result.value
|
||||
|
||||
parameter_value = self._last_comments_list + [parameter_value]
|
||||
self._last_comments_list = []
|
||||
self._current_type_section[parameter_name] = parameter_value
|
||||
except ParseException:
|
||||
return
|
||||
|
||||
def _parse_plain_directive_line_to_delete(self, line):
|
||||
'''Метод для парсинга строк, предписывающих удаление простых уникальных
|
||||
директив, если указано только их имя, но отсутствует значение.
|
||||
Аргументы: line -- строка, которую нужно распарсить.
|
||||
'''
|
||||
try:
|
||||
parsing_result = self._directive_line_to_delete_parser.parseString(
|
||||
line
|
||||
)
|
||||
self._match = True
|
||||
|
||||
parameter_name = tuple(parsing_result.name.asList())
|
||||
|
||||
if parsing_result.action == '-':
|
||||
return
|
||||
|
||||
parameter_value = self._last_comments_list
|
||||
self._last_comments_list = []
|
||||
self._current_type_section[parameter_name] = parameter_value
|
||||
except ParseException:
|
||||
return
|
||||
|
||||
def _parse_comment_line(self, line):
|
||||
'''Метод для парсинга строк с комментариями и добавления их в список
|
||||
комментариев _last_comments_list, предназначенный для сбора
|
||||
комментариев и последующего их присваивания параметрам и секциям.
|
||||
Аргументы: line -- строка, которую нужно распарсить.'''
|
||||
try:
|
||||
parsing_result = self._comment_line.parseString(line)
|
||||
self._match = True
|
||||
|
||||
if not self._ignore_comments:
|
||||
# До того, как первый элемент встречен -- все комментарии
|
||||
# должны быть присвоены глобальной области.
|
||||
if self._current_type == ('', 'global') and\
|
||||
list(self._current_type_section.keys()) == ['#']:
|
||||
self._current_type_section['#'].append(
|
||||
parsing_result.comment
|
||||
)
|
||||
else:
|
||||
self._last_comments_list.append(parsing_result.comment)
|
||||
|
||||
except ParseException:
|
||||
return
|
||||
|
||||
def _finish_method(self):
|
||||
self._item_to_add = OrderedDict()
|
||||
if self._current_type in self._document_dictionary.keys():
|
||||
self._document_dictionary[self._current_type].update(
|
||||
self._current_type_section
|
||||
)
|
||||
else:
|
||||
self._item_to_add[self._current_type] = self._current_type_section
|
||||
self._document_dictionary.update(self._item_to_add)
|
||||
|
||||
self._item_to_add = OrderedDict()
|
||||
self._current_type_section = OrderedDict()
|
99
calculate/templates/format/openrc_format.py
Normal file
99
calculate/templates/format/openrc_format.py
Normal file
|
@ -0,0 +1,99 @@
|
|||
# vim: fileencoding=utf-8
|
||||
#
|
||||
from .base_format import BaseFormat
|
||||
from collections import OrderedDict
|
||||
from pyparsing import Word, Literal, printables, originalTextFor, ZeroOrMore,\
|
||||
OneOrMore, ParseException, restOfLine,\
|
||||
pyparsing_unicode, Group, Optional
|
||||
|
||||
|
||||
class OpenRCFormat(BaseFormat):
|
||||
def __init__(self, document_text: str, ignore_comments=False):
|
||||
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._format = 'openrc'
|
||||
|
||||
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):
|
||||
parameter_name = Word(printables, excludeChars='=')
|
||||
|
||||
parameter_value = originalTextFor(OneOrMore(Word(printables)))
|
||||
|
||||
action_symbols = (Literal('!') | Literal('-'))
|
||||
|
||||
self._parameter_line = (Group(Optional(action_symbols,
|
||||
default='')('action')
|
||||
+ parameter_name('name'))('parameter_name')
|
||||
+ Literal('=').suppress()
|
||||
+ parameter_value('parameter_value'))
|
||||
|
||||
self._parameter_to_delete = (Group(action_symbols('action')
|
||||
+ parameter_name('name')
|
||||
)('parameter_name')
|
||||
+ restOfLine.suppress())
|
||||
|
||||
self._comment_line = originalTextFor(
|
||||
Literal('#')
|
||||
+ ZeroOrMore(Word(printables
|
||||
+ pyparsing_unicode.alphanums))
|
||||
)('comment')
|
||||
|
||||
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.lower())
|
||||
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.lower())
|
||||
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
|
177
calculate/templates/format/patch_format.py
Normal file
177
calculate/templates/format/patch_format.py
Normal file
|
@ -0,0 +1,177 @@
|
|||
# vim: fileencoding=utf-8
|
||||
#
|
||||
from .base_format import BaseFormat
|
||||
from collections import OrderedDict
|
||||
import re
|
||||
try:
|
||||
from lxml.etree.ElementTree import fromstring
|
||||
except ImportError:
|
||||
from xml.etree.ElementTree import fromstring
|
||||
|
||||
|
||||
class PatchFormat(BaseFormat):
|
||||
def __init__(self, document_text: str, multiline=False, dotall=False):
|
||||
processing_methods = OrderedDict()
|
||||
super().__init__(processing_methods)
|
||||
self._format = 'patch'
|
||||
|
||||
self._multiline_flag = multiline
|
||||
self._dotall_flag = dotall
|
||||
self._parsed_patch = None
|
||||
|
||||
self._document_to_patch = ''
|
||||
self._FLAG_VALUES = {'True': True,
|
||||
'False': False,
|
||||
'true': True,
|
||||
'false': False,
|
||||
'1': True,
|
||||
'0': False}
|
||||
|
||||
self._XML_ROOT_LINE = '<?xml version="1.0" encoding="utf-8"?>\
|
||||
<patch>{0}</patch>'
|
||||
|
||||
if not self._parse_patch(document_text):
|
||||
# Какая-то обработка ошибки.
|
||||
print('Error: Can not parse patch document.')
|
||||
|
||||
def _parse_patch(self, patch_text):
|
||||
xml_patch = self._XML_ROOT_LINE.format(patch_text.strip())
|
||||
try:
|
||||
self._parsed_patch = fromstring(xml_patch)
|
||||
return True
|
||||
except Exception:
|
||||
# Какая-то обработка ошибки.
|
||||
print('Error: Incorrect text of the template.')
|
||||
return False
|
||||
|
||||
def execute_format(self, document_to_patch):
|
||||
if not document_to_patch.strip() == '':
|
||||
self._document_to_patch = document_to_patch
|
||||
|
||||
if self._parse_patch is None:
|
||||
return False
|
||||
else:
|
||||
if not self._patch_document(document_to_patch):
|
||||
error_message = 'Error: Can not run patch.'
|
||||
print(error_message)
|
||||
return False
|
||||
|
||||
else:
|
||||
after_patch = self._document_to_patch
|
||||
self._document_to_patch = ''
|
||||
return after_patch
|
||||
|
||||
def _patch_document(self, document_to_patch):
|
||||
patch_iterator = self._parsed_patch.getiterator()
|
||||
PATCH_DOCUMENT_TAGS = ('reg', 'text')
|
||||
|
||||
patch_element = next(patch_iterator, False)
|
||||
|
||||
if not patch_element or not patch_element.tag == 'patch':
|
||||
print('Error: Incorrect text of the template.')
|
||||
return False
|
||||
|
||||
while True:
|
||||
for patch_tag in PATCH_DOCUMENT_TAGS:
|
||||
patch_element = next(patch_iterator, None)
|
||||
|
||||
if patch_element is None:
|
||||
if patch_tag == 'text':
|
||||
print('Error: Last <text>Text</text> '
|
||||
'object is missed.')
|
||||
return False
|
||||
else:
|
||||
break
|
||||
|
||||
if patch_element.tag == patch_tag:
|
||||
if patch_element.text is not None:
|
||||
element_text = patch_element.text.strip()
|
||||
if element_text == '':
|
||||
error_message = 'Error: Incorrect text of the \
|
||||
template: <{0}>%s</{0}>'.format(
|
||||
patch_tag
|
||||
)
|
||||
print(error_message)
|
||||
return False
|
||||
else:
|
||||
error_message = 'Error: Incorrect text of the \
|
||||
template: <{0}></{0}>'.format(
|
||||
patch_tag
|
||||
)
|
||||
print(error_message)
|
||||
return False
|
||||
|
||||
if patch_tag == 'reg':
|
||||
dotall = patch_element.attrib.get('dotall', False)
|
||||
regex_flags = 0
|
||||
|
||||
if 'multiline' in patch_element.attrib:
|
||||
multiline = patch_element.attrib['multiline']
|
||||
if multiline not in self._FLAG_VALUES:
|
||||
error_message = ('Error: Invalid multiline '
|
||||
'value.')
|
||||
print(error_message)
|
||||
return False
|
||||
else:
|
||||
multiline = self._FLAG_VALUES[multiline]
|
||||
|
||||
# Если глобально флаг MULTILINE включен, но в
|
||||
# атрибутах тэга <reg> этот флаг присутствует со
|
||||
# значением False -- для этого регулярного
|
||||
# выражения этот флаг также будет False.
|
||||
multiline_global = self._multiline_flag & multiline
|
||||
else:
|
||||
multiline = False
|
||||
multiline_global = self._multiline_flag
|
||||
|
||||
if multiline_global or multiline:
|
||||
regex_flags |= re.MULTILINE
|
||||
|
||||
if 'dotall' in patch_element.attrib:
|
||||
dotall = patch_element.attrib['dotall']
|
||||
if dotall not in self._FLAG_VALUES:
|
||||
error_message = 'Error: Invalid dotall value.'
|
||||
print(error_message)
|
||||
return False
|
||||
else:
|
||||
dotall = self._FLAG_VALUES[dotall]
|
||||
|
||||
# Если глобально флаг DOTALL включен, но в
|
||||
# атрибутах тэга <reg> этот флаг присутствует со
|
||||
# значением False -- для этого регулярного
|
||||
# выражения этот флаг также будет False.
|
||||
dotall_global = self._dotall_flag & dotall
|
||||
else:
|
||||
dotall = False
|
||||
dotall_global = self._dotall_flag
|
||||
|
||||
if dotall_global or dotall:
|
||||
regex_flags |= re.DOTALL
|
||||
|
||||
regex_expression = re.compile(element_text,
|
||||
regex_flags)
|
||||
else:
|
||||
text_for_replace = element_text
|
||||
else:
|
||||
if patch_element.tag in PATCH_DOCUMENT_TAGS:
|
||||
error_message = 'Error: <{0}> is expected, \
|
||||
<{1}> instead.'.format(
|
||||
patch_tag,
|
||||
patch_element.tag
|
||||
)
|
||||
print(error_message)
|
||||
else:
|
||||
error_message = 'Error: Unknown tag: {0}'.format(
|
||||
patch_element.tag
|
||||
)
|
||||
print(error_message)
|
||||
# Какая-то обработка ошибки.
|
||||
error_message = 'Error: Incorrect text of the template.'
|
||||
print(error_message)
|
||||
return False
|
||||
else:
|
||||
self._document_to_patch = re.sub(regex_expression,
|
||||
text_for_replace,
|
||||
self._document_to_patch)
|
||||
continue
|
||||
return True
|
98
calculate/templates/format/postfix_format.py
Normal file
98
calculate/templates/format/postfix_format.py
Normal file
|
@ -0,0 +1,98 @@
|
|||
# vim: fileencoding=utf-8
|
||||
#
|
||||
from .base_format import BaseFormat
|
||||
from collections import OrderedDict
|
||||
from pyparsing import Word, Literal, alphanums, printables, originalTextFor,\
|
||||
ZeroOrMore, OneOrMore, ParseException,\
|
||||
pyparsing_unicode, Group, Optional
|
||||
|
||||
|
||||
class PostfixFormat(BaseFormat):
|
||||
def __init__(self, document_text: str, ignore_comments=False):
|
||||
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._format = 'postfix'
|
||||
|
||||
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):
|
||||
parameter_name = Word(alphanums+'_')
|
||||
|
||||
parameter_value = originalTextFor(OneOrMore(Word(printables)))
|
||||
|
||||
action_symbols = (Literal('!') | Literal('-'))
|
||||
|
||||
assignment = Literal('=')
|
||||
|
||||
self._parameter_line = (Group(Optional(action_symbols,
|
||||
default='')('action')
|
||||
+ parameter_name)('parameter_name')
|
||||
+ assignment.suppress()
|
||||
+ parameter_value('parameter_value'))
|
||||
|
||||
self._parameter_to_delete = (action_symbols('action')
|
||||
+ parameter_name('Name')
|
||||
)('parameter_name')
|
||||
|
||||
self._comment_line = originalTextFor(
|
||||
Literal('#')
|
||||
+ ZeroOrMore(Word(printables
|
||||
+ pyparsing_unicode.alphanums))
|
||||
)('comment')
|
||||
|
||||
def _parse_parameter_line(self, line):
|
||||
try:
|
||||
self._item_to_add = OrderedDict()
|
||||
parsing_result = self._parameter_line.parseString(line)
|
||||
self._match = True
|
||||
|
||||
key_value = tuple(parsing_result.parameter_name.asList())
|
||||
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
|
||||
except ParseException:
|
||||
return
|
||||
|
||||
def _parse_to_delete_line(self, line):
|
||||
try:
|
||||
self._item_to_add = OrderedDict()
|
||||
parsing_result = self._parameter_to_delete.parseString(line)
|
||||
self._match = True
|
||||
|
||||
if parsing_result.action == '-':
|
||||
return
|
||||
|
||||
key_value = tuple(parsing_result.parameter_name.asList())
|
||||
parameter_value = self._last_comments_list
|
||||
self._last_comments_list = []
|
||||
|
||||
self._item_to_add[key_value] = parameter_value
|
||||
self._ready_to_update = True
|
||||
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
|
99
calculate/templates/format/procmail_format.py
Normal file
99
calculate/templates/format/procmail_format.py
Normal file
|
@ -0,0 +1,99 @@
|
|||
# vim: fileencoding=utf-8
|
||||
#
|
||||
from .base_format import BaseFormat
|
||||
from collections import OrderedDict
|
||||
from pyparsing import Word, Literal, alphanums, printables, originalTextFor,\
|
||||
ZeroOrMore, OneOrMore, ParseException, restOfLine,\
|
||||
pyparsing_unicode, Group, Optional
|
||||
|
||||
|
||||
class ProcmailFormat(BaseFormat):
|
||||
def __init__(self, document_text: str, ignore_comments=False):
|
||||
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._format = 'procmail'
|
||||
|
||||
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):
|
||||
parameter_name = Word(alphanums+'_.')
|
||||
|
||||
parameter_value = originalTextFor(OneOrMore(Word(printables)))
|
||||
|
||||
action_symbols = (Literal('!') | Literal('-'))
|
||||
|
||||
self._parameter_line = (Group(Optional(action_symbols,
|
||||
default='')('action')
|
||||
+ parameter_name('Name')
|
||||
)('parameter_name')
|
||||
+ Literal('=').suppress()
|
||||
+ parameter_value('parameter_value'))
|
||||
|
||||
self._parameter_to_delete = (Group(action_symbols('action')
|
||||
+ parameter_name('Name')
|
||||
)('parameter_name')
|
||||
+ restOfLine.suppress())
|
||||
|
||||
self._comment_line = originalTextFor(
|
||||
Literal('#')
|
||||
+ ZeroOrMore(
|
||||
Word(printables
|
||||
+ pyparsing_unicode.alphanums)
|
||||
)
|
||||
)('comment')
|
||||
|
||||
def _parse_parameter_line(self, line):
|
||||
try:
|
||||
parsing_result = self._parameter_line.parseString(line)
|
||||
self._match = True
|
||||
|
||||
key_value = tuple(parsing_result.parameter_name.asList())
|
||||
parameter_value = parsing_result.parameter_value
|
||||
|
||||
parameter_value = self._last_comments_list + [parameter_value]
|
||||
self._last_comments_list = []
|
||||
|
||||
self._item_to_add = OrderedDict({key_value: parameter_value})
|
||||
self._ready_to_update = 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)
|
||||
self._match = True
|
||||
|
||||
if parsing_result.parameter_name.action == '-':
|
||||
return
|
||||
|
||||
key_value = tuple(parsing_result.parameter_name.asList())
|
||||
parameter_value = self._last_comments_list
|
||||
self._last_comments_list = []
|
||||
|
||||
self._item_to_add = OrderedDict({key_value: parameter_value})
|
||||
self._ready_to_update = True
|
||||
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
|
411
calculate/templates/format/proftpd_format.py
Normal file
411
calculate/templates/format/proftpd_format.py
Normal file
|
@ -0,0 +1,411 @@
|
|||
# vim: fileencoding=utf-8
|
||||
#
|
||||
from .base_format import BaseFormat
|
||||
from jinja2 import Environment, PackageLoader
|
||||
from collections import OrderedDict
|
||||
from pyparsing import originalTextFor, Literal, ZeroOrMore, Word, printables,\
|
||||
OneOrMore, alphanums, ParseException, pyparsing_unicode,\
|
||||
Group, Optional, alphas, Keyword
|
||||
|
||||
|
||||
class ProFTPDFormat(BaseFormat):
|
||||
def __init__(self, document_text: str, ignore_comments=False):
|
||||
processing_methods = [self._parse_comment_line,
|
||||
self._parse_section_start_line,
|
||||
self._parse_section_end_line,
|
||||
self._parse_single_key_directive_line,
|
||||
self._parse_double_key_directive_line,
|
||||
self._parse_to_delete_double_key_directive_line,
|
||||
self._parse_full_key_directive_line,
|
||||
self._parse_plain_directive_line,
|
||||
self._parse_to_delete_plain_directive_line]
|
||||
|
||||
super().__init__(processing_methods)
|
||||
self._ignore_comments = ignore_comments
|
||||
self._need_finish = True
|
||||
self._comments_processing = True
|
||||
self._format = 'proftpd'
|
||||
|
||||
self._section_stack = []
|
||||
self._actions_stack = []
|
||||
|
||||
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):
|
||||
left_angle_bracket = Literal('<')
|
||||
right_angle_bracket = Literal('>')
|
||||
slash = Literal('/')
|
||||
|
||||
action_symbols = (Literal('!') |
|
||||
Literal('-'))
|
||||
|
||||
directive = Word(alphas, alphanums)
|
||||
|
||||
section_value = Word(printables, excludeChars='<>')
|
||||
|
||||
directive_value = Word(printables)
|
||||
|
||||
self._section_start_parser = (left_angle_bracket.suppress()
|
||||
+ Optional(action_symbols,
|
||||
default='')('action')
|
||||
+ Group(directive('name')
|
||||
+ originalTextFor(
|
||||
OneOrMore(section_value)
|
||||
)('value')
|
||||
)('directive')
|
||||
+ right_angle_bracket.suppress())
|
||||
|
||||
self._section_end_parser = (left_angle_bracket.suppress()
|
||||
+ slash.suppress()
|
||||
+ directive('directive')
|
||||
+ right_angle_bracket.suppress())
|
||||
|
||||
self._plain_directive_parser = (Optional(action_symbols)('action')
|
||||
+ Group(directive('name')
|
||||
+ originalTextFor(
|
||||
OneOrMore(directive_value)
|
||||
)('value')
|
||||
)('directive')
|
||||
)
|
||||
|
||||
self._delete_plain_directive_parser = (action_symbols('action')
|
||||
+ directive('directive'))
|
||||
|
||||
single_key_directive = (Keyword('AllowAll') |
|
||||
Keyword('DenyAll') |
|
||||
Keyword('AccessDenyMsg') |
|
||||
Keyword('AccessGrantMsg') |
|
||||
Keyword('ByteRatioErrMsg') |
|
||||
Keyword('LeechRatioMsg') |
|
||||
Keyword('CwdRatioMsg') |
|
||||
Keyword('FileRatioErrMsg'))
|
||||
|
||||
self._single_key_directive_parser = (Optional(action_symbols)('action')
|
||||
+ single_key_directive(
|
||||
'directive'
|
||||
))
|
||||
|
||||
double_key_directive = (Keyword('AccessDenyMsg') |
|
||||
Keyword('AccessGrantMsg') |
|
||||
Keyword('ByteRatioErrMsg') |
|
||||
Keyword('Allow from') | Keyword('Allow') |
|
||||
Keyword('AllowFilter') |
|
||||
Keyword('AnonymousGroup') |
|
||||
Keyword('AuthPAMConfig') |
|
||||
Keyword('Bind') |
|
||||
Keyword('CDPath') |
|
||||
Keyword('Define') |
|
||||
Keyword('Deny from') | Keyword('Deny') |
|
||||
Keyword('DenyFilter') |
|
||||
Keyword('DisplayChdir') |
|
||||
Keyword('ExtendedLog') |
|
||||
Keyword('AnonRatio') |
|
||||
Keyword('GroupRatio') |
|
||||
Keyword('HideGroup') |
|
||||
Keyword('HideUser') |
|
||||
Keyword('HostRatio') |
|
||||
Keyword('Include') |
|
||||
Keyword('LDAPAttr') |
|
||||
Keyword('LeechRatioMsg') |
|
||||
Keyword('CwdRatioMsg') |
|
||||
Keyword('FileRatioErrMsg') |
|
||||
Keyword('LogFormat') |
|
||||
Keyword('MaxClientsPerClass') |
|
||||
Keyword('PIDFile') |
|
||||
Keyword('RewriteMap') |
|
||||
Keyword('RewriteRule') |
|
||||
Keyword('SetEnv') |
|
||||
Keyword('SQLConnectInfo') |
|
||||
Keyword('SQLGroupWhereClause') |
|
||||
Keyword('SQLLog') |
|
||||
Keyword('SQLNamedQuery') |
|
||||
Keyword('SQLShowInfo') |
|
||||
Keyword('SQLUserInfo') |
|
||||
Keyword('SQLUserWhereClause') |
|
||||
Keyword('LoadModule') |
|
||||
Keyword('LoadFile') |
|
||||
Keyword('TransferRate') |
|
||||
Keyword('UnsetEnv') |
|
||||
Keyword('UserPassword') |
|
||||
Keyword('UserRatio') |
|
||||
Keyword('ModuleControlsACLs') |
|
||||
Keyword('ControlsACLs'))
|
||||
|
||||
self._double_key_directive_parser = (Optional(action_symbols)('action')
|
||||
+ Group((double_key_directive
|
||||
+ directive_value
|
||||
)('name')
|
||||
+ originalTextFor(
|
||||
ZeroOrMore(
|
||||
directive_value
|
||||
)
|
||||
)('value')
|
||||
)('directive')
|
||||
)
|
||||
|
||||
self._delete_double_key_directive_parser = (action_symbols('action')
|
||||
+ Group(
|
||||
(
|
||||
double_key_directive
|
||||
+ directive_value
|
||||
)('name')
|
||||
)('directive')
|
||||
)
|
||||
|
||||
full_key_directive = (Keyword('AllowClass') |
|
||||
Keyword('AllowGroup') |
|
||||
Keyword('AllowUser') |
|
||||
Keyword('Class') |
|
||||
Keyword('DenyClass') |
|
||||
Keyword('DenyGroup') |
|
||||
Keyword('DenyUser') |
|
||||
Keyword('DirFakeGroup') |
|
||||
Keyword('DirFakeUser') |
|
||||
Keyword('HideFiles') |
|
||||
Keyword('MaxRetrieveFileSize') |
|
||||
Keyword('MaxStoreFileSize') |
|
||||
Keyword('RewriteCondition') |
|
||||
Keyword('RewriteLock') |
|
||||
Keyword('TimeoutSession') |
|
||||
Keyword('UserAlias'))
|
||||
|
||||
self._full_key_directive_parser = (Optional(action_symbols)('action')
|
||||
+ Group(full_key_directive
|
||||
+ OneOrMore(
|
||||
directive_value
|
||||
)
|
||||
)('directive')
|
||||
)
|
||||
|
||||
self._comment_line = originalTextFor(
|
||||
Literal('#')
|
||||
+ ZeroOrMore(Word(printables
|
||||
+ pyparsing_unicode.alphanums))
|
||||
)('comment')
|
||||
|
||||
def _parse_section_start_line(self, line):
|
||||
try:
|
||||
parsing_result = self._section_start_parser.parseString(line)
|
||||
self._match = True
|
||||
|
||||
section_name = tuple(parsing_result.directive.asList())
|
||||
self._actions_stack.append(parsing_result.action)
|
||||
self._section_stack.append(section_name)
|
||||
|
||||
except ParseException:
|
||||
return
|
||||
|
||||
def _parse_section_end_line(self, line):
|
||||
try:
|
||||
parsing_result = self._section_end_parser.parseString(line)
|
||||
self._match = True
|
||||
|
||||
current_section = self._section_stack.pop()
|
||||
self._actions_stack.pop()
|
||||
directive = tuple(parsing_result.directive)
|
||||
|
||||
if not current_section[1] != directive:
|
||||
# Здесь будет кидаться исключение.
|
||||
self._fatal_error_flag = True
|
||||
return
|
||||
|
||||
except ParseException:
|
||||
return
|
||||
|
||||
def _parse_plain_directive_line(self, line):
|
||||
try:
|
||||
parsing_result = self._plain_directive_parser.parseString(line)
|
||||
self._match = True
|
||||
|
||||
for action_item in self._actions_stack:
|
||||
if not action_item == '':
|
||||
action = (action_item, )
|
||||
break
|
||||
else:
|
||||
action = (parsing_result.action, )
|
||||
|
||||
if not self._section_stack == []:
|
||||
context = (tuple(self._section_stack), )
|
||||
else:
|
||||
context = ('', )
|
||||
|
||||
directive = (parsing_result.directive.name, )
|
||||
directive_value = [parsing_result.directive.value]
|
||||
|
||||
directive_name = action + context + directive
|
||||
directive_value = self._last_comments_list + directive_value
|
||||
self._last_comments_list = []
|
||||
|
||||
self._item_to_add = OrderedDict({directive_name: directive_value})
|
||||
self._ready_to_update = True
|
||||
except ParseException:
|
||||
return
|
||||
|
||||
def _parse_to_delete_plain_directive_line(self, line):
|
||||
try:
|
||||
parsing_result = self._delete_plain_directive_parser.parseString(
|
||||
line
|
||||
)
|
||||
self._match = True
|
||||
|
||||
action = (parsing_result.action, )
|
||||
|
||||
if not self._section_stack == []:
|
||||
context = (tuple(self._section_stack), )
|
||||
else:
|
||||
context = ('', )
|
||||
|
||||
directive = (parsing_result.directive, )
|
||||
directive_name = action + context + directive
|
||||
|
||||
directive_value = self._last_comments_list + ['']
|
||||
self._last_comments_list = []
|
||||
|
||||
self._item_to_add = OrderedDict({directive_name: directive_value})
|
||||
self._ready_to_update = True
|
||||
except ParseException:
|
||||
return
|
||||
|
||||
def _parse_single_key_directive_line(self, line):
|
||||
try:
|
||||
parsing_result = self._single_key_directive_parser.parseString(
|
||||
line
|
||||
)
|
||||
self._match = True
|
||||
|
||||
for action_item in self._actions_stack:
|
||||
if not action_item == '':
|
||||
action = (action_item, )
|
||||
break
|
||||
else:
|
||||
action = (parsing_result.action, )
|
||||
|
||||
if not self._section_stack == []:
|
||||
context = (tuple(self._section_stack), )
|
||||
else:
|
||||
context = ('', )
|
||||
|
||||
directive = (parsing_result.directive, )
|
||||
directive_value = ['']
|
||||
|
||||
directive_name = action + context + directive
|
||||
directive_value = self._last_comments_list + directive_value
|
||||
self._last_comments_list = []
|
||||
|
||||
self._item_to_add = OrderedDict({directive_name: directive_value})
|
||||
self._ready_to_update = True
|
||||
except ParseException:
|
||||
return
|
||||
|
||||
def _parse_double_key_directive_line(self, line):
|
||||
try:
|
||||
parsing_result = self._double_key_directive_parser.parseString(
|
||||
line
|
||||
)
|
||||
self._match = True
|
||||
|
||||
for action_item in self._actions_stack:
|
||||
if not action_item == '':
|
||||
action = (action_item, )
|
||||
break
|
||||
else:
|
||||
action = (parsing_result.action, )
|
||||
|
||||
if not self._section_stack == []:
|
||||
context = (tuple(self._section_stack), )
|
||||
else:
|
||||
context = ('', )
|
||||
|
||||
directive = tuple(parsing_result.directive.name.asList())
|
||||
directive_value = [parsing_result.directive.value]
|
||||
|
||||
directive_name = action + context + directive
|
||||
directive_value = self._last_comments_list + directive_value
|
||||
self._last_comments_list = []
|
||||
|
||||
self._item_to_add = OrderedDict({directive_name: directive_value})
|
||||
self._ready_to_update = True
|
||||
except ParseException:
|
||||
return
|
||||
|
||||
def _parse_to_delete_double_key_directive_line(self, line):
|
||||
try:
|
||||
parsing_result = self._delete_double_key_directive_parser.\
|
||||
parseString(line)
|
||||
self._match = True
|
||||
|
||||
action = (parsing_result.action, )
|
||||
|
||||
if not self._section_stack == []:
|
||||
context = (tuple(self._section_stack), )
|
||||
else:
|
||||
context = ('', )
|
||||
|
||||
directive = tuple(parsing_result.directive.name.asList())
|
||||
directive_name = action + context + directive
|
||||
|
||||
directive_value = self._last_comments_list + ['']
|
||||
self._last_comments_list = []
|
||||
|
||||
self._item_to_add = OrderedDict({directive_name: directive_value})
|
||||
self._ready_to_update = True
|
||||
except ParseException:
|
||||
return
|
||||
|
||||
def _parse_full_key_directive_line(self, line):
|
||||
try:
|
||||
parsing_result = self._full_key_directive_parser.parseString(line)
|
||||
self._match = True
|
||||
|
||||
for action_item in self._actions_stack:
|
||||
if not action_item == '':
|
||||
action = (action_item, )
|
||||
break
|
||||
else:
|
||||
action = (parsing_result.action, )
|
||||
|
||||
if not self._section_stack == []:
|
||||
context = (tuple(self._section_stack), )
|
||||
else:
|
||||
context = ('', )
|
||||
|
||||
directive = tuple(parsing_result.directive.asList())
|
||||
directive_value = ['']
|
||||
|
||||
directive_name = action + context + directive
|
||||
directive_value = self._last_comments_list + directive_value
|
||||
self._last_comments_list = []
|
||||
|
||||
self._item_to_add = OrderedDict({directive_name: directive_value})
|
||||
self._ready_to_update = 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
|
||||
|
||||
def get_document_text(self):
|
||||
file_loader = PackageLoader('calculate.templates.format',
|
||||
self.TEMPLATES_DIRECTORY)
|
||||
formats_environment = Environment(loader=file_loader)
|
||||
formats_environment.globals.update(zip=zip)
|
||||
formats_environment.add_extension('jinja2.ext.do')
|
||||
template = formats_environment.get_template(self._format)
|
||||
document_text = template.render(
|
||||
document_dictionary=self._document_dictionary
|
||||
)
|
||||
return document_text
|
163
calculate/templates/format/samba_format.py
Normal file
163
calculate/templates/format/samba_format.py
Normal file
|
@ -0,0 +1,163 @@
|
|||
# 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()
|
27
calculate/templates/format/templates/bind
Normal file
27
calculate/templates/format/templates/bind
Normal file
|
@ -0,0 +1,27 @@
|
|||
{% for item_name, item_value in document_dictionary.items() recursive %}
|
||||
{% if item_name != '#' %}
|
||||
{% if item_value is mapping %}
|
||||
{% if not loop.first %}
|
||||
|
||||
{% endif %}
|
||||
{% if '#' in item_value %}
|
||||
{% for comment in item_value['#'] %}
|
||||
{{ comment }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if item_name[1] == 'inet' %}
|
||||
{{ item_name[1:] | join(' ') }}
|
||||
{%- for keyword in item_value %}
|
||||
{%- if keyword != '#' %} {{ keyword[1] }} { {{ item_value[keyword] | join('; ')}}; }{% endif %}{% endfor %};
|
||||
{% else %}
|
||||
{{ item_name[1:] | join(' ') }} {
|
||||
{{ loop(item_value.items()) | indent}}};
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% for comment in item_value[:-1] %}
|
||||
{{ comment }}
|
||||
{% endfor %}
|
||||
{{ item_name[1:] | join(' ') }}{% if not item_value[-1] == '' %} {{ item_value[-1] }}{% endif%};
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
17
calculate/templates/format/templates/compiz
Normal file
17
calculate/templates/format/templates/compiz
Normal file
|
@ -0,0 +1,17 @@
|
|||
{% for section_name in document_dictionary.keys() %}
|
||||
{% if '#' in document_dictionary[section_name].keys() %}
|
||||
{% for comment in document_dictionary[section_name]['#'] %}
|
||||
{{ comment }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
[{{ section_name[1] }}]
|
||||
{% for parameter_name in document_dictionary[section_name].keys() %}
|
||||
{% if parameter_name != '#' %}
|
||||
{% for comment in document_dictionary[section_name][parameter_name][:-1]%}
|
||||
{{ comment }}
|
||||
{% endfor %}
|
||||
{{ parameter_name[1] }}={{ document_dictionary[section_name][parameter_name][-1] }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% endfor %}
|
28
calculate/templates/format/templates/dovecot
Normal file
28
calculate/templates/format/templates/dovecot
Normal file
|
@ -0,0 +1,28 @@
|
|||
{% for item_name, item_value in document_dictionary.items() recursive %}
|
||||
{% if item_name != '#' %}
|
||||
{% if item_value is mapping %}
|
||||
{% if '#' in item_value %}
|
||||
{% for comment in item_value['#'] %}
|
||||
{{ comment }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{{ item_name[1:] | join(' ') }} {
|
||||
{{ loop(item_value.items()) | indent}}}
|
||||
{% else %}
|
||||
{% for comment in item_value[:-1] %}
|
||||
{{ comment }}
|
||||
{% endfor %}
|
||||
{{ item_name[1:] | join(' ') }}{%- if not item_value[-1] == '' %} = {{ item_value[-1] }}
|
||||
{% else %}
|
||||
{%- if not loop.last%}
|
||||
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if not loop.last%}
|
||||
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
|
19
calculate/templates/format/templates/kde
Normal file
19
calculate/templates/format/templates/kde
Normal file
|
@ -0,0 +1,19 @@
|
|||
{% for section_name in document_dictionary.keys() %}
|
||||
{% if '#' in document_dictionary[section_name].keys() %}
|
||||
{% for comment in document_dictionary[section_name]['#'] %}
|
||||
{{ comment }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% for section_part in section_name[1:] %}
|
||||
[{{ section_part }}]{% endfor %}
|
||||
|
||||
{% for parameter_name in document_dictionary[section_name].keys() %}
|
||||
{% if parameter_name != '#' %}
|
||||
{% for comment in document_dictionary[section_name][parameter_name][:-1]%}
|
||||
{{ comment }}
|
||||
{% endfor %}
|
||||
{{ parameter_name[1] }}={{ document_dictionary[section_name][parameter_name][-1] }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% endfor %}
|
6
calculate/templates/format/templates/kernel
Normal file
6
calculate/templates/format/templates/kernel
Normal file
|
@ -0,0 +1,6 @@
|
|||
{% for parameter_name in document_dictionary.keys() %}
|
||||
{% for comment in document_dictionary[parameter_name][:-1]%}
|
||||
{{ comment }}
|
||||
{% endfor %}
|
||||
{{ parameter_name[1] }}={{ document_dictionary[parameter_name][-1] }}
|
||||
{% endfor %}
|
59
calculate/templates/format/templates/ldap
Normal file
59
calculate/templates/format/templates/ldap
Normal file
|
@ -0,0 +1,59 @@
|
|||
{% for section_type in document_dictionary.keys() %}
|
||||
{% if '#' in document_dictionary[section_type] %}
|
||||
{% for comment in document_dictionary[section_type]['#']%}
|
||||
{{ comment }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if section_type != ('', 'global')%}
|
||||
{{ section_type[1] }} {{ section_type[2] }}
|
||||
{% endif %}
|
||||
{% for directive in document_dictionary[section_type].keys() if directive[1] == 'include' %}
|
||||
{% for comment in document_dictionary[section_type][directive][:-1] %}
|
||||
{{ comment }}
|
||||
{% endfor %}
|
||||
{{ directive[1] }} {{ directive[2] }}
|
||||
{% endfor %}
|
||||
{% for directive in document_dictionary[section_type].keys() %}
|
||||
{% if directive != '#' and directive[1] != 'include' %}
|
||||
{% set directive_value = document_dictionary[section_type][directive] %}
|
||||
{% if directive[1] == 'access to' %}
|
||||
{% set access_values = directive_value.keys()|list %}
|
||||
{% if '#' in directive_value %}
|
||||
{% for comment in directive_value['#'] %}
|
||||
{{ comment }}
|
||||
{% endfor %}
|
||||
{% set access_values = access_values[1:] %}
|
||||
{% endif %}
|
||||
{% if access_values|length == 1 %}
|
||||
{{ directive[1] }} {{ directive[2] }} by {{ access_values[0][1] }} {{ directive_value[access_values[0]][0] }}
|
||||
{% else %}
|
||||
{{ directive[1] }} {{ directive[2] }}
|
||||
{% for value in access_values|reverse %}
|
||||
by {{ value[1] }} {{ directive_value[value][0] }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% elif directive[1] == 'syncrepl' %}
|
||||
{% set syncrepl_values = directive_value.keys()|list%}
|
||||
{% if '#' in directive_value %}
|
||||
{% for comment in directive_value['#'] %}
|
||||
{{ comment }}
|
||||
{% endfor %}
|
||||
{% set syncrepl_values = syncrepl_values[1:]%}
|
||||
{% endif %}
|
||||
{{ directive[1] }} {{ directive[2] }}
|
||||
{% for value in syncrepl_values %}
|
||||
{{ value[1] }}={{ directive_value[value][0] }}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% for comment in directive_value[:-1] %}
|
||||
{{ comment }}
|
||||
{% endfor %}
|
||||
{{ directive[1:]|join(' ') }}{% if directive_value[-1] != '' %} {{ directive_value[-1] }}
|
||||
{% else %}
|
||||
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% endfor %}
|
7
calculate/templates/format/templates/openrc
Normal file
7
calculate/templates/format/templates/openrc
Normal file
|
@ -0,0 +1,7 @@
|
|||
{% for parameter_name in document_dictionary.keys() %}
|
||||
{% for comment in document_dictionary[parameter_name][:-1]%}
|
||||
{{ comment }}
|
||||
{% endfor %}
|
||||
{{ parameter_name[1] }}={{ document_dictionary[parameter_name][-1] }}
|
||||
|
||||
{% endfor %}
|
8
calculate/templates/format/templates/postfix
Normal file
8
calculate/templates/format/templates/postfix
Normal file
|
@ -0,0 +1,8 @@
|
|||
{% for parameter_name in document_dictionary.keys() %}
|
||||
{% for comment in document_dictionary[parameter_name][:-1]%}
|
||||
{{ comment }}
|
||||
{% endfor %}
|
||||
{{ parameter_name[1] }} = {{ document_dictionary[parameter_name][-1] }}
|
||||
|
||||
{% endfor %}
|
||||
|
7
calculate/templates/format/templates/procmail
Normal file
7
calculate/templates/format/templates/procmail
Normal file
|
@ -0,0 +1,7 @@
|
|||
{% for parameter_name in document_dictionary.keys() %}
|
||||
{% for comment in document_dictionary[parameter_name][:-1]%}
|
||||
{{ comment }}
|
||||
{% endfor %}
|
||||
{{ parameter_name[1] }}={{ document_dictionary[parameter_name][-1] }}
|
||||
|
||||
{% endfor %}
|
38
calculate/templates/format/templates/proftpd
Normal file
38
calculate/templates/format/templates/proftpd
Normal file
|
@ -0,0 +1,38 @@
|
|||
{%- set section_stack = [] -%}
|
||||
{%- set counters = namespace(level=0,indent=0) -%}
|
||||
{%- for item_name, item_value in document_dictionary.items() -%}
|
||||
{%- set count_flag = True -%}
|
||||
{%- set counters.level = 0 -%}
|
||||
{%- for item_level, current_level in zip(item_name[1], section_stack) -%}
|
||||
{%- if not item_level == current_level -%}
|
||||
{%- set count_flag = False -%}
|
||||
{%- elif count_flag -%}
|
||||
{%- set counters.level = counters.level + 1 -%}
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
{%- for section_name in section_stack[counters.level: ] | reverse -%}
|
||||
{%- set counters.indent = counters.indent - 1 -%}
|
||||
{{- ' ' * counters.indent }}</{{ section_name[0] }}>
|
||||
{% if loop.last %}
|
||||
{% endif -%}
|
||||
{% do section_stack.pop() -%}
|
||||
{%- endfor -%}
|
||||
{%- for comment in item_value[:-1] -%}
|
||||
{% if loop.first %}
|
||||
{% endif -%}
|
||||
{{ ' ' * counters.indent }}{{ comment }}
|
||||
{% endfor -%}
|
||||
{%- for section_name in item_name[1][counters.level: ] -%}
|
||||
{{ ' ' * counters.indent }}<{{ section_name | join(' ') }}>
|
||||
{% set counters.indent = counters.indent + 1 -%}
|
||||
{%- do section_stack.append(section_name) -%}
|
||||
{%- endfor -%}
|
||||
{{ ' ' * counters.indent }}{{ item_name[2:] | join(' ') }}{% if not item_value[-1] == '' %} {{ item_value[-1] }}{% endif %}
|
||||
{% endfor -%}
|
||||
{%- for section_name in section_stack | reverse -%}
|
||||
{%- set counters.indent = counters.indent - 1 -%}
|
||||
{{ ' ' * counters.indent }}</{{ section_name[0] }}>
|
||||
{%- if not loop.last %}
|
||||
{% endif -%}
|
||||
{%- endfor %}
|
||||
|
16
calculate/templates/format/templates/samba
Normal file
16
calculate/templates/format/templates/samba
Normal file
|
@ -0,0 +1,16 @@
|
|||
{% for section_name in document_dictionary.keys() %}
|
||||
{% if '#' in document_dictionary[section_name].keys() %}
|
||||
{% for comment in document_dictionary[section_name]['#'] %}
|
||||
{{ comment }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
[{{ section_name[1] }}]
|
||||
{% for parameter_name in document_dictionary[section_name].keys() %}
|
||||
{% if parameter_name != '#' %}
|
||||
{% for comment in document_dictionary[section_name][parameter_name][:-1]%}
|
||||
{{ comment }}
|
||||
{% endfor %}
|
||||
{{ parameter_name[1] }} = {{ document_dictionary[section_name][parameter_name][-1] }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
14
calculate/templates/format/templates/squid
Normal file
14
calculate/templates/format/templates/squid
Normal file
|
@ -0,0 +1,14 @@
|
|||
{% for parameter_name, parameter_value in document_dictionary.items() %}
|
||||
{% for comment in document_dictionary[parameter_name][:-1]%}
|
||||
{{ comment }}
|
||||
{% endfor %}
|
||||
{{ parameter_name[1:] | join(' ') }}{%- if not parameter_value[-1] == '' %} {{ parameter_value[-1] }}
|
||||
{% else %}
|
||||
{%- if not loop.last%}
|
||||
|
||||
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
|
223
calculate/templates/format/xml_gconf_format.py
Normal file
223
calculate/templates/format/xml_gconf_format.py
Normal file
|
@ -0,0 +1,223 @@
|
|||
# vim: fileencoding=utf-8
|
||||
#
|
||||
from pyparsing import originalTextFor, Literal, Word, printables, OneOrMore,\
|
||||
Optional
|
||||
from .base_format import BaseFormat
|
||||
from collections import OrderedDict
|
||||
try:
|
||||
from lxml.etree import Element, SubElement, ElementTree, tostring
|
||||
except ImportError:
|
||||
from xml.etree.ElementTree import Element, SubElement, ElementTree, \
|
||||
tostring
|
||||
|
||||
|
||||
class XMLGConfFormat(BaseFormat):
|
||||
def __init__(self, document_text: str):
|
||||
processing_methods = OrderedDict({'gconf': self._gconf,
|
||||
'entry': self._entry,
|
||||
'dir': self._dir,
|
||||
'stringvalue': self._stringvalue,
|
||||
'default': self._default,
|
||||
'local_schema': self._local_schema,
|
||||
'li': self._li,
|
||||
'longdesc': self._longdesc,
|
||||
'unknown': self._unknown})
|
||||
super().__init__(processing_methods)
|
||||
self._format = 'xml_gconf'
|
||||
|
||||
self._initialize_parser()
|
||||
|
||||
self._parse_xml_to_dictionary(document_text)
|
||||
|
||||
def _initialize_parser(self):
|
||||
action_symbols = (Literal('!') | Literal('-'))
|
||||
|
||||
name = originalTextFor(OneOrMore(Word(printables)))
|
||||
|
||||
self._node_name = Optional(action_symbols)('action') + name('name')
|
||||
|
||||
def _entry(self, xml_element):
|
||||
try:
|
||||
element_items = OrderedDict(xml_element.attrib)
|
||||
|
||||
name = element_items.pop('name')
|
||||
parsing_result = self._node_name.parseString(name)
|
||||
|
||||
if 'value' in element_items:
|
||||
entry_value = element_items.pop('value')
|
||||
|
||||
elif 'ltype' in element_items:
|
||||
entry_value = []
|
||||
for child in xml_element:
|
||||
item_to_add = self._processing_methods.get(child.tag,
|
||||
self._unknown
|
||||
)(child)
|
||||
entry_value.append(item_to_add)
|
||||
else:
|
||||
entry_value = OrderedDict()
|
||||
for child in xml_element:
|
||||
item_to_add = self._processing_methods.get(child.tag,
|
||||
self._unknown
|
||||
)(child)
|
||||
entry_value.update(item_to_add)
|
||||
element_name = (parsing_result.action,
|
||||
xml_element.tag,
|
||||
('name', parsing_result.name),
|
||||
*element_items.items())
|
||||
return OrderedDict({element_name: entry_value})
|
||||
except Exception:
|
||||
# Какая-то обработка ошибки.
|
||||
return OrderedDict()
|
||||
|
||||
def _gconf(self, xml_element):
|
||||
output_dictionary = OrderedDict()
|
||||
element_name = ('', xml_element.tag)
|
||||
for child in xml_element:
|
||||
item_to_add = self._processing_methods.get(child.tag,
|
||||
self._unknown)(child)
|
||||
output_dictionary.update(item_to_add)
|
||||
|
||||
return OrderedDict({element_name: output_dictionary})
|
||||
|
||||
def _dir(self, xml_element):
|
||||
output_dictionary = OrderedDict()
|
||||
try:
|
||||
parsing_result = self._node_name.parseString(
|
||||
xml_element.attrib['name']
|
||||
)
|
||||
element_name = (parsing_result.action,
|
||||
xml_element.tag,
|
||||
('name', parsing_result.name))
|
||||
except Exception:
|
||||
# Какая-то обработка ошибки.
|
||||
return OrderedDict()
|
||||
|
||||
for child in xml_element:
|
||||
item_to_add = self._processing_methods.get(child.tag,
|
||||
self._unknown)(child)
|
||||
output_dictionary.update(item_to_add)
|
||||
|
||||
return OrderedDict({element_name: output_dictionary})
|
||||
|
||||
def _longdesc(self, xml_element):
|
||||
element_name = ('', 'longdesc')
|
||||
description = xml_element.text
|
||||
|
||||
if description is not None:
|
||||
return OrderedDict({element_name: description})
|
||||
else:
|
||||
# Пустая строка. Возможно ошибка.
|
||||
# Какая-то обработка ошибки.
|
||||
return OrderedDict({element_name: ''})
|
||||
|
||||
def _local_schema(self, xml_element):
|
||||
output_dictionary = OrderedDict()
|
||||
try:
|
||||
element_name = ('', xml_element.tag,
|
||||
*xml_element.items())
|
||||
|
||||
except Exception:
|
||||
# Какая-то обработка ошибки.
|
||||
return OrderedDict()
|
||||
|
||||
for child in xml_element:
|
||||
item_to_add = self._processing_methods.get(child.tag,
|
||||
self._unknown)(child)
|
||||
output_dictionary.update(item_to_add)
|
||||
|
||||
return OrderedDict({element_name: output_dictionary})
|
||||
|
||||
def _stringvalue(self, xml_element):
|
||||
element_name = ('', 'stringvalue')
|
||||
value = xml_element.text
|
||||
|
||||
if value is not None:
|
||||
return OrderedDict({element_name: value})
|
||||
else:
|
||||
# Пустая строка. Возможно ошибка.
|
||||
# Какая-то обработка ошибки.
|
||||
return OrderedDict({element_name: ''})
|
||||
|
||||
def _default(self, xml_element):
|
||||
output_dictionary = OrderedDict()
|
||||
element_name = ('', xml_element.tag, *xml_element.items())
|
||||
|
||||
for child in xml_element:
|
||||
item_to_add = self._processing_methods.get(child.tag,
|
||||
self._unknown)(child)
|
||||
output_dictionary.update(item_to_add)
|
||||
|
||||
return OrderedDict({element_name: output_dictionary})
|
||||
|
||||
def _li(self, xml_element):
|
||||
child = next(iter(xml_element))
|
||||
|
||||
list_element = self._processing_methods.get(child.tag,
|
||||
self._unknown)(child)
|
||||
# Единственным возможным типом списковых значений пока является string.
|
||||
string_value = next(iter(list_element.values()))
|
||||
return string_value
|
||||
|
||||
def _unknown(self, xml_element):
|
||||
# Действия если элемент неизвестен.
|
||||
element_name = ('', Element.tag)
|
||||
return OrderedDict({element_name: 'Unknown element'})
|
||||
|
||||
def get_document_text(self):
|
||||
gconf_header = next(iter(self._document_dictionary))
|
||||
|
||||
root = Element('gconf')
|
||||
|
||||
self._build_section(root, self._document_dictionary[gconf_header])
|
||||
|
||||
document_tree = ElementTree(root)
|
||||
xml_document = tostring(document_tree,
|
||||
encoding="UTF-8",
|
||||
xml_declaration=True,
|
||||
pretty_print=True).decode()
|
||||
return xml_document
|
||||
|
||||
def _build_section(self, current_element, dictionary):
|
||||
for dict_element in dictionary.keys():
|
||||
element_tag = dict_element[1]
|
||||
element_attributes = OrderedDict({key: value for key, value in
|
||||
dict_element[2:]})
|
||||
|
||||
if element_tag == 'dir' or element_tag == 'local_schema'\
|
||||
or element_tag == 'default':
|
||||
include_element = SubElement(current_element,
|
||||
element_tag,
|
||||
**element_attributes)
|
||||
self._build_section(include_element,
|
||||
dictionary[dict_element])
|
||||
|
||||
elif element_tag == 'entry':
|
||||
if isinstance(dictionary[dict_element], OrderedDict):
|
||||
include_element = SubElement(current_element,
|
||||
element_tag,
|
||||
**element_attributes)
|
||||
|
||||
self._build_section(include_element,
|
||||
dictionary[dict_element])
|
||||
elif 'ltype' in element_attributes:
|
||||
if element_attributes['ltype'] == 'string':
|
||||
entry_element = SubElement(current_element,
|
||||
element_tag,
|
||||
**element_attributes)
|
||||
for value in dictionary[dict_element]:
|
||||
list_element = SubElement(entry_element,
|
||||
'li', type='string')
|
||||
include_element = SubElement(list_element,
|
||||
'stringvalue')
|
||||
include_element.text = value
|
||||
|
||||
else:
|
||||
include_element = SubElement(current_element,
|
||||
element_tag,
|
||||
**element_attributes,
|
||||
value=dictionary[dict_element]
|
||||
)
|
||||
elif element_tag == 'longdesc' or element_tag == 'stringvalue':
|
||||
include_element = SubElement(current_element,
|
||||
element_tag)
|
||||
include_element.text = dictionary[dict_element]
|
164
calculate/templates/format/xml_xfce_format.py
Normal file
164
calculate/templates/format/xml_xfce_format.py
Normal file
|
@ -0,0 +1,164 @@
|
|||
# vim: fileencoding=utf-8
|
||||
#
|
||||
from .base_format import BaseFormat
|
||||
from pyparsing import originalTextFor, Literal, Word, printables, OneOrMore,\
|
||||
Optional
|
||||
from collections import OrderedDict
|
||||
try:
|
||||
from lxml.etree import Element, SubElement, ElementTree, tostring
|
||||
except ImportError:
|
||||
from xml.etree.ElementTree import Element, SubElement, ElementTree, \
|
||||
tostring
|
||||
|
||||
|
||||
class XMLXfceFormat(BaseFormat):
|
||||
def __init__(self, document_text: str, ignore_comments=False):
|
||||
processing_methods = OrderedDict({'channel': self._channel,
|
||||
'property': self._property,
|
||||
'value': self._value,
|
||||
'unknown': self._unknown})
|
||||
super().__init__(processing_methods)
|
||||
self._format = 'xml_xfce'
|
||||
|
||||
self._initialize_parser()
|
||||
|
||||
if document_text == '':
|
||||
self._document_dictionary = OrderedDict()
|
||||
else:
|
||||
self._parse_xml_to_dictionary(document_text)
|
||||
|
||||
def _initialize_parser(self):
|
||||
action_symbols = (Literal('!') | Literal('-'))
|
||||
|
||||
name = originalTextFor(OneOrMore(Word(printables)))
|
||||
|
||||
self._node_name = Optional(action_symbols)('action') + name('name')
|
||||
|
||||
# Кортежи с названиями атрибутов различных элементов.
|
||||
self._ELEMENT_ATTRIBUTES = ('tag', 'name', 'type', 'value')
|
||||
self._CHANNEL_ATTRIBUTES = ('tag', 'name', 'version')
|
||||
self._VALUE_ATTRIBUTES = ('tag', 'type', 'value')
|
||||
|
||||
def _property(self, xml_element):
|
||||
try:
|
||||
parsing_result = self._node_name.parseString(
|
||||
xml_element.attrib['name']
|
||||
)
|
||||
element_name = (parsing_result.action,
|
||||
xml_element.tag,
|
||||
parsing_result.name,
|
||||
xml_element.attrib['type'])
|
||||
except Exception:
|
||||
# Какая-то обработка ошибки.
|
||||
return OrderedDict()
|
||||
|
||||
if xml_element.attrib['type'] == 'empty':
|
||||
output = OrderedDict()
|
||||
for child in xml_element:
|
||||
child_value = self._processing_methods.get(child.tag,
|
||||
self._unknown
|
||||
)(child)
|
||||
output.update(child_value)
|
||||
|
||||
elif xml_element.attrib['type'] == 'array':
|
||||
output = []
|
||||
for child in xml_element:
|
||||
child_value = self._processing_methods.get(child.tag,
|
||||
self._unknown
|
||||
)(child)
|
||||
output.append(child_value)
|
||||
else:
|
||||
try:
|
||||
output = xml_element.attrib['value']
|
||||
except KeyError:
|
||||
# Какая-то обработка ошибки.
|
||||
return OrderedDict()
|
||||
|
||||
return OrderedDict({element_name: output})
|
||||
|
||||
def _value(self, xml_element):
|
||||
try:
|
||||
value = (xml_element.tag,
|
||||
xml_element.attrib['type'],
|
||||
xml_element.attrib['value'])
|
||||
except KeyError:
|
||||
# Какая-то обработка ошибки.
|
||||
return ('',)
|
||||
return value
|
||||
|
||||
def _channel(self, xml_element):
|
||||
output_dictionary = OrderedDict()
|
||||
try:
|
||||
parsing_result = self._node_name.parseString(
|
||||
xml_element.attrib['name']
|
||||
)
|
||||
element_name = (parsing_result.action,
|
||||
xml_element.tag,
|
||||
parsing_result.name,
|
||||
xml_element.attrib['version'])
|
||||
except Exception:
|
||||
# Какая-то обработка ошибки.
|
||||
return OrderedDict()
|
||||
|
||||
for child in xml_element:
|
||||
item_to_add = self._processing_methods.get(child.tag,
|
||||
self._unknown)(child)
|
||||
output_dictionary.update(item_to_add)
|
||||
|
||||
return OrderedDict({element_name: output_dictionary})
|
||||
|
||||
def _unknown(self, xml_element):
|
||||
# Действия если элемент неизвестен.
|
||||
element_name = ('', xml_element.tag)
|
||||
return OrderedDict({element_name: 'Unknown element'})
|
||||
|
||||
def get_document_text(self):
|
||||
channel = next(iter(self._document_dictionary.keys()))
|
||||
channel_head = OrderedDict(
|
||||
{key: value for key, value in
|
||||
zip(self._CHANNEL_ATTRIBUTES, channel[1:])}
|
||||
)
|
||||
|
||||
root = Element(channel_head.pop('tag'), **channel_head)
|
||||
|
||||
self._build_section(root, self._document_dictionary[channel])
|
||||
document_tree = ElementTree(root)
|
||||
xml_document = tostring(document_tree,
|
||||
encoding="UTF-8",
|
||||
xml_declaration=True,
|
||||
pretty_print=True).decode()
|
||||
|
||||
return xml_document
|
||||
|
||||
def _build_section(self, current_element, dictionary):
|
||||
for dict_element in dictionary.keys():
|
||||
element_head = OrderedDict({key: value for key, value in
|
||||
zip(self._ELEMENT_ATTRIBUTES,
|
||||
dict_element[1:])})
|
||||
|
||||
if element_head['type'] == 'empty':
|
||||
include_element = SubElement(current_element,
|
||||
element_head.pop('tag'),
|
||||
**element_head)
|
||||
self._build_section(include_element,
|
||||
dictionary[dict_element])
|
||||
|
||||
elif element_head['type'] == 'array':
|
||||
include_element = SubElement(current_element,
|
||||
element_head.pop('tag'),
|
||||
**element_head)
|
||||
|
||||
for list_element in dictionary[dict_element]:
|
||||
list_element_head = OrderedDict(
|
||||
{key: value for key, value in
|
||||
zip(self._VALUE_ATTRIBUTES,
|
||||
list_element)}
|
||||
)
|
||||
SubElement(include_element,
|
||||
list_element_head.pop('tag'),
|
||||
**list_element_head)
|
||||
else:
|
||||
SubElement(current_element,
|
||||
element_head.pop('tag'),
|
||||
**element_head,
|
||||
value=dictionary[dict_element])
|
0
calculate/utils/__init__.py
Normal file
0
calculate/utils/__init__.py
Normal file
261
calculate/utils/files.py
Normal file
261
calculate/utils/files.py
Normal file
|
@ -0,0 +1,261 @@
|
|||
# vim: fileencoding=utf-8
|
||||
#
|
||||
from subprocess import Popen, PIPE
|
||||
from io import TextIOWrapper
|
||||
from os import path
|
||||
import os
|
||||
|
||||
|
||||
class FilesError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class PipeProcess():
|
||||
def _get_stdout(self):
|
||||
return PIPE
|
||||
|
||||
def close(self):
|
||||
pass
|
||||
|
||||
@property
|
||||
def shell_command(self):
|
||||
return ''
|
||||
|
||||
|
||||
class KeyboardInputProcess():
|
||||
def _get_stdout(self):
|
||||
return None
|
||||
|
||||
def close(self):
|
||||
pass
|
||||
|
||||
@property
|
||||
def shell_command(self):
|
||||
return ''
|
||||
|
||||
|
||||
class Process():
|
||||
def __init__(self, command, *parameters, **kwargs):
|
||||
if 'stdin' not in kwargs:
|
||||
self._stdin = PipeProcess()
|
||||
elif kwargs['stdin'] == PIPE:
|
||||
self._stdin = PipeProcess()
|
||||
elif kwargs['stdin'] is None:
|
||||
self._stdin = KeyboardInputProcess()
|
||||
else:
|
||||
self._stdin = kwargs['stdin']
|
||||
|
||||
self._stdout = kwargs.get('stdout', PIPE)
|
||||
self._stderr = kwargs.get('stderr', PIPE)
|
||||
|
||||
self._envdict = kwargs.get('envdict', os.environ.copy())
|
||||
self._envdict['LANG'] = kwargs.get('lang', 'C')
|
||||
|
||||
self._timeout = kwargs.get('timeout', None)
|
||||
self._cwd = kwargs.get('cwd', None)
|
||||
|
||||
self._command = _get_program_path(command)
|
||||
if not self._command:
|
||||
raise FilesError("command not found '{}'".format(command))
|
||||
self._command = [self._command, *parameters]
|
||||
|
||||
self._process = None
|
||||
self._iterator = iter([])
|
||||
|
||||
# Flags.
|
||||
self._opened = False
|
||||
self._is_read = False
|
||||
|
||||
self._readable = False
|
||||
self._writable = False
|
||||
self._readable_errors = False
|
||||
|
||||
# I/O handlers.
|
||||
self.stdin_handler = None
|
||||
self.stdout_handler = None
|
||||
self.stderr_handler = None
|
||||
|
||||
# Caches.
|
||||
self._output_cache = ''
|
||||
self._error_cache = ''
|
||||
|
||||
def _get_stdout(self):
|
||||
self._open_process()
|
||||
return self.stdout_handler
|
||||
|
||||
def _get_stdin(self):
|
||||
return self.stdin_handler
|
||||
|
||||
def _open_process(self):
|
||||
try:
|
||||
piped_stdin = self._stdin._get_stdout()
|
||||
self._process = Popen(self._command,
|
||||
stdout=self._stdout,
|
||||
stdin=piped_stdin,
|
||||
stderr=self._stderr,
|
||||
cwd=self._cwd,
|
||||
close_fds=True,
|
||||
env=self._envdict)
|
||||
|
||||
if piped_stdin == PIPE:
|
||||
self.stdin_handler = TextIOWrapper(self._process.stdin,
|
||||
encoding='utf8')
|
||||
self._writable = True
|
||||
elif piped_stdin is not None:
|
||||
self.stdin_handler = self._stdin._get_stdin()
|
||||
self._writable = True
|
||||
|
||||
if self._stdout == PIPE:
|
||||
self.stdout_handler = TextIOWrapper(self._process.stdout,
|
||||
encoding='utf8')
|
||||
self._readable = True
|
||||
|
||||
if self._stderr == PIPE:
|
||||
self.stderr_handler = TextIOWrapper(self._process.stderr,
|
||||
encoding='utf8')
|
||||
self._readable_errors = True
|
||||
|
||||
self._opened = True
|
||||
except Exception as error:
|
||||
print('error:', error)
|
||||
raise FilesError('Can not open process.')
|
||||
|
||||
def close(self):
|
||||
if self._opened:
|
||||
if self._process.stdin:
|
||||
self.stdin_handler.close()
|
||||
self._stdin.close()
|
||||
self._opened = False
|
||||
|
||||
def write(self, data):
|
||||
if not self._opened:
|
||||
self._open_process()
|
||||
self._is_read = False
|
||||
self._output_cache = ''
|
||||
try:
|
||||
if self._writable:
|
||||
self.stdin_handler.write(data)
|
||||
self.stdin_handler.flush()
|
||||
else:
|
||||
raise FilesError('Process stdin is not writable.')
|
||||
except IOError as error:
|
||||
raise FilesError(str(error))
|
||||
|
||||
def read(self):
|
||||
if not self._opened and not self._writable:
|
||||
self._open_process()
|
||||
|
||||
if not self._readable:
|
||||
raise FilesError('Process is not readable.')
|
||||
try:
|
||||
if not self._is_read:
|
||||
if self._writable:
|
||||
self.close()
|
||||
|
||||
if self._readable:
|
||||
self._output_cache = self.stdout_handler.read()
|
||||
|
||||
if self._readable_errors:
|
||||
self._error_cache = self.stderr_handler.read()
|
||||
|
||||
self._process.poll()
|
||||
self._is_read = True
|
||||
return self._output_cache
|
||||
except KeyboardInterrupt:
|
||||
self.kill()
|
||||
raise
|
||||
|
||||
def read_error(self):
|
||||
self.read()
|
||||
if not self._error_cache:
|
||||
try:
|
||||
self._error_cache = self.stderr_handler.read()
|
||||
except IOError:
|
||||
self._error_cache = ''
|
||||
return self._error_cache
|
||||
|
||||
def kill(self):
|
||||
if self._opened:
|
||||
self._process.kill()
|
||||
|
||||
def read_lines(self):
|
||||
return self.read().split('\n')
|
||||
|
||||
def __iter__(self):
|
||||
if not self._iterator:
|
||||
self._iterator = iter(self.read_lines())
|
||||
return self._iterator
|
||||
|
||||
def next(self):
|
||||
return next(self.__iter__(), None)
|
||||
|
||||
@property
|
||||
def writable(self):
|
||||
return self._writable
|
||||
|
||||
@property
|
||||
def readable(self):
|
||||
return self._readable
|
||||
|
||||
@property
|
||||
def readable_errors(self):
|
||||
return self._readable_errors
|
||||
|
||||
def return_code(self):
|
||||
self.read()
|
||||
return self._process.returncode
|
||||
|
||||
@property
|
||||
def shell_command(self):
|
||||
command = ' '.join(self._command)
|
||||
previous_commands = self._stdin.shell_command
|
||||
if previous_commands == '':
|
||||
return command
|
||||
else:
|
||||
return ' | '.join([previous_commands, command])
|
||||
|
||||
def success(self):
|
||||
return self.return_code() == 0
|
||||
|
||||
def failed(self):
|
||||
return self.return_code() != 0
|
||||
|
||||
|
||||
class ProgramPathCache():
|
||||
def __init__(self):
|
||||
self._cache = {}
|
||||
|
||||
def __call__(self, program_name, prefix='/'):
|
||||
program_base_name = path.basename(program_name)
|
||||
PATH = os.environ['PATH']
|
||||
PATH = PATH.split(':')
|
||||
cache_key = (program_base_name, prefix)
|
||||
|
||||
if cache_key in self._cache:
|
||||
self._cache[cache_key]
|
||||
|
||||
if program_name.startswith('/'):
|
||||
if path.exists(join_paths(prefix, program_name)):
|
||||
self._cache[cache_key] = program_name
|
||||
return program_name
|
||||
for program_name in (join_paths(bin_path, program_base_name)
|
||||
for bin_path in PATH):
|
||||
if path.exists(join_paths(prefix, program_name)):
|
||||
self._cache[cache_key] = program_name
|
||||
return program_name
|
||||
return False
|
||||
|
||||
|
||||
_get_program_path = ProgramPathCache()
|
||||
|
||||
|
||||
def join_paths(*paths):
|
||||
if len(paths) == 1:
|
||||
return next(iter(paths))
|
||||
|
||||
paths_to_join = filter(lambda path: path.strip() and path != "/",
|
||||
map(lambda path:
|
||||
path[1:] if path.startswith('/') else path,
|
||||
paths[1:]))
|
||||
output_path = path.join(paths[0], *paths_to_join)
|
||||
return output_path
|
BIN
calculate/vars/.datavars.py.swp
Normal file
BIN
calculate/vars/.datavars.py.swp
Normal file
Binary file not shown.
0
calculate/vars/__init__.py
Normal file
0
calculate/vars/__init__.py
Normal file
51
calculate/vars/datavars.py
Normal file
51
calculate/vars/datavars.py
Normal file
|
@ -0,0 +1,51 @@
|
|||
import site
|
||||
import os
|
||||
|
||||
class Variable:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def get(self):
|
||||
"""
|
||||
Функция заполнения переменной
|
||||
"""
|
||||
pass
|
||||
|
||||
def set(self, value):
|
||||
"""
|
||||
Функция модификации переменной
|
||||
"""
|
||||
pass
|
||||
|
||||
def choice(self):
|
||||
"""
|
||||
Функция возвращет список доступных значений для переменной
|
||||
"""
|
||||
pass
|
||||
|
||||
def check(self, value):
|
||||
"""
|
||||
Функция проверки значения устанавливаемого значения
|
||||
"""
|
||||
|
||||
class NamespaceError(Exception):
|
||||
pass
|
||||
|
||||
class Namespace:
|
||||
DefaultPath = "[default_path]"
|
||||
def __init__(self, varPath=DefaultPath):
|
||||
if varPath is Namespace.DefaultPath:
|
||||
self.varPath = self._getMainPackage()
|
||||
else:
|
||||
self.varPath = varPath
|
||||
self.childs = []
|
||||
|
||||
def _getMainPackage(self):
|
||||
site_dirs = [os.path.normpath(x) for x in site.getsitepackages()]
|
||||
for site_dir in site_dirs:
|
||||
calculate_dir = os.path.join(site_dir, "calculate/vars")
|
||||
if os.path.exists(calculate_dir):
|
||||
return calculate_dir
|
||||
|
||||
def findVariablePackages(self, dirPath):
|
||||
pass
|
0
calculate/vars/os/__init__.py
Normal file
0
calculate/vars/os/__init__.py
Normal file
4
calculate/vars/os/gentoo/__init__.py
Normal file
4
calculate/vars/os/gentoo/__init__.py
Normal file
|
@ -0,0 +1,4 @@
|
|||
from calculate.vars.datavars import Variable
|
||||
|
||||
class Profile(Variable):
|
||||
pass
|
164
conftest.py
Normal file
164
conftest.py
Normal file
|
@ -0,0 +1,164 @@
|
|||
import pytest
|
||||
from collections import OrderedDict
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def StringDictionaries():
|
||||
ParamLine1 = OrderedDict({'parameter name1': 'value1'})
|
||||
ParamLine2 = OrderedDict({'parameter name2': 'value2'})
|
||||
ParamLine3 = OrderedDict({'parameter name3': 'value3'})
|
||||
|
||||
Section1 = OrderedDict({'section name1': OrderedDict(**ParamLine1,
|
||||
**ParamLine2)})
|
||||
Section2 = OrderedDict({'section name2': OrderedDict(**ParamLine1,
|
||||
**ParamLine2)})
|
||||
Section3 = OrderedDict({'section name3': OrderedDict(**ParamLine3)})
|
||||
|
||||
OriginalDictionary = OrderedDict(**Section1, **Section2)
|
||||
TemplateDictionary = OrderedDict(**Section3)
|
||||
ResultDictionary = OrderedDict(**Section1, **Section2, **Section3)
|
||||
|
||||
return (OriginalDictionary, TemplateDictionary, ResultDictionary)
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def TupleDictionaries():
|
||||
ParamLine1 = OrderedDict({('', 'parameter name1'): 'value1'})
|
||||
ParamLine2 = OrderedDict({('', 'parameter name2'): 'value2'})
|
||||
ParamLine3 = OrderedDict({('', 'parameter name3'): 'value3'})
|
||||
|
||||
Section1 = OrderedDict({('', 'section name1'): OrderedDict(**ParamLine1,
|
||||
**ParamLine2)})
|
||||
Section2 = OrderedDict({('', 'section name2'): OrderedDict(**ParamLine1,
|
||||
**ParamLine2)})
|
||||
Section3 = OrderedDict({('', 'section name3'): OrderedDict(**ParamLine3)})
|
||||
|
||||
OriginalDictionary = OrderedDict(**Section1, **Section2)
|
||||
TemplateDictionary = OrderedDict(**Section3)
|
||||
ResultDictionary = OrderedDict(**Section1, **Section2, **Section3)
|
||||
|
||||
return (OriginalDictionary, TemplateDictionary, ResultDictionary)
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def MergeSectionDictionaries():
|
||||
ParamLine1 = OrderedDict({('', 'parameter name1'): 'value1'})
|
||||
ParamLine2 = OrderedDict({('', 'parameter name2'): 'value2'})
|
||||
ParamLine3 = OrderedDict({('', 'parameter name3'): 'value3'})
|
||||
|
||||
Section1 = OrderedDict({('', 'section name1'): OrderedDict(**ParamLine1,
|
||||
**ParamLine2)})
|
||||
Section2 = OrderedDict({('', 'section name2'): OrderedDict(**ParamLine1,
|
||||
**ParamLine2)})
|
||||
Section2Add = OrderedDict({('', 'section name2'):
|
||||
OrderedDict(**ParamLine3)})
|
||||
Section2Added = OrderedDict({('', 'section name2'):
|
||||
OrderedDict(**ParamLine1,
|
||||
**ParamLine2,
|
||||
**ParamLine3)})
|
||||
|
||||
OriginalDictionary = OrderedDict(**Section1, **Section2)
|
||||
TemplateDictionary = OrderedDict(**Section2Add)
|
||||
ResultDictionary = OrderedDict(**Section1, **Section2Added)
|
||||
|
||||
return (OriginalDictionary, TemplateDictionary, ResultDictionary)
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def ChangeParameterDictionaries():
|
||||
ParamLine1 = OrderedDict({('', 'parameter name1'): 'value1'})
|
||||
ParamLine2 = OrderedDict({('', 'parameter name2'): 'value2'})
|
||||
ParamLine3 = OrderedDict({('', 'parameter name3'): 'value3'})
|
||||
ParamLine2New = OrderedDict({('', 'parameter name2'): 'NewValue'})
|
||||
ParamLine3New = OrderedDict({('', 'parameter name3'): 'OtherValue'})
|
||||
|
||||
Section = OrderedDict({('', 'section name1'): OrderedDict(**ParamLine1,
|
||||
**ParamLine2,
|
||||
**ParamLine3)})
|
||||
SectionNew = OrderedDict({('', 'section name1'):
|
||||
OrderedDict(**ParamLine1,
|
||||
**ParamLine2New,
|
||||
**ParamLine3New)})
|
||||
|
||||
OriginalDictionary = OrderedDict(**Section)
|
||||
TemplateDictionary = OrderedDict(**SectionNew)
|
||||
ResultDictionary = TemplateDictionary
|
||||
|
||||
return (OriginalDictionary, TemplateDictionary, ResultDictionary)
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def DeleteSectionDictionaries():
|
||||
ParamLine1 = OrderedDict({('', 'parameter name1'): 'value1'})
|
||||
ParamLine2 = OrderedDict({('', 'parameter name2'): 'value2'})
|
||||
|
||||
Section1 = OrderedDict({('', 'section name1'): OrderedDict(**ParamLine1,
|
||||
**ParamLine2)})
|
||||
Section2 = OrderedDict({('', 'section name2'): OrderedDict(**ParamLine1,
|
||||
**ParamLine2)})
|
||||
SectionDel = OrderedDict({('!', 'section name2'): OrderedDict()})
|
||||
|
||||
OriginalDictionary = OrderedDict(**Section1, **Section2)
|
||||
TemplateDictionary = OrderedDict(**SectionDel)
|
||||
ResultDictionary = OrderedDict(**Section1)
|
||||
|
||||
return (OriginalDictionary, TemplateDictionary, ResultDictionary)
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def ReplaceSectionDictionaries():
|
||||
ParamLine1 = OrderedDict({('', 'parameter name1'): 'value1'})
|
||||
ParamLine2 = OrderedDict({('', 'parameter name2'): 'value2'})
|
||||
ParamLine3 = OrderedDict({('', 'parameter name3'): 'value3'})
|
||||
ParamLine4 = OrderedDict({('', 'parameter name4'): 'value4'})
|
||||
|
||||
Section1 = OrderedDict({('', 'section name1'): OrderedDict(**ParamLine1,
|
||||
**ParamLine2)})
|
||||
Section2 = OrderedDict({('', 'section name2'): OrderedDict(**ParamLine1,
|
||||
**ParamLine2)})
|
||||
Section2Replace = OrderedDict({('-', 'section name2'):
|
||||
OrderedDict(**ParamLine3, **ParamLine4)})
|
||||
Section2Replaced = OrderedDict({('', 'section name2'):
|
||||
OrderedDict(**ParamLine3, **ParamLine4)})
|
||||
|
||||
OriginalDictionary = OrderedDict(**Section1, **Section2)
|
||||
TemplateDictionary = OrderedDict(**Section2Replace)
|
||||
ResultDictionary = OrderedDict(**Section1, **Section2Replaced)
|
||||
|
||||
return (OriginalDictionary, TemplateDictionary, ResultDictionary)
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def DeleteParameterDictionaries():
|
||||
ParamLine1 = OrderedDict({('', 'parameter name1'): 'value1'})
|
||||
ParamLine2 = OrderedDict({('', 'parameter name2'): 'value2'})
|
||||
ParamLineDel = OrderedDict({('!', 'parameter name2'): 'value2'})
|
||||
|
||||
Section1 = OrderedDict({('', 'section name1'): OrderedDict(**ParamLine1,
|
||||
**ParamLine2)})
|
||||
Section2 = OrderedDict({('', 'section name2'): OrderedDict(**ParamLine1,
|
||||
**ParamLine2)})
|
||||
SectionDel = OrderedDict({('', 'section name2'):
|
||||
OrderedDict(**ParamLineDel)})
|
||||
SectionAfterDel = OrderedDict({('', 'section name2'):
|
||||
OrderedDict(**ParamLine1)})
|
||||
|
||||
OriginalDictionary = OrderedDict(**Section1, **Section2)
|
||||
TemplateDictionary = OrderedDict(**SectionDel)
|
||||
ResultDictionary = OrderedDict(**Section1, **SectionAfterDel)
|
||||
|
||||
return (OriginalDictionary, TemplateDictionary, ResultDictionary)
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def DictionariesWithoutSections():
|
||||
ParamLine1 = OrderedDict({('', 'parameter name1'): 'value1'})
|
||||
ParamLine2 = OrderedDict({('', 'parameter name2'): 'value2'})
|
||||
ParamLine3 = OrderedDict({('', 'parameter name3'): 'value3'})
|
||||
ParamLineDel = OrderedDict({('!', 'parameter name2'): ''})
|
||||
|
||||
OriginalDictionary = OrderedDict(**ParamLine1, **ParamLine2)
|
||||
TemplateDictionary = OrderedDict(**ParamLine3, **ParamLineDel)
|
||||
ResultDictionary = OrderedDict(**ParamLine1, **ParamLine3)
|
||||
|
||||
return (OriginalDictionary, TemplateDictionary, ResultDictionary)
|
23
pytest.ini
Normal file
23
pytest.ini
Normal file
|
@ -0,0 +1,23 @@
|
|||
# vim: fileencoding=utf-8
|
||||
# pytest.ini
|
||||
[pytest]
|
||||
markers =
|
||||
vars: marker for running tests for datavars
|
||||
base: marker for running tests for base format class.
|
||||
bind: marker for running tests for bind format.
|
||||
compiz: marker for running tests for compiz format.
|
||||
diff: marker for running test for diff format.
|
||||
dovecot: marker for running tests for devecot format.
|
||||
json: marker for running tests for json format.
|
||||
kde: marker for running test for kde format.
|
||||
kernel: marker for running test for kernel format.
|
||||
ldap: marker for running test for ldap format.
|
||||
openrc: marker for running test for openrc format.
|
||||
patch: marker for running test fot patch format.
|
||||
postfix: marker for running test for postfix format.
|
||||
procmail: marker for running test for procmail format.
|
||||
proftpd: marker for running tests for proftpd format.
|
||||
samba: marker for running tests for samba format.
|
||||
xml_xfce: marker for running tests for xml xfce format.
|
||||
xml_gconf: marker for running tests for xml gconf format.
|
||||
files: marker for running tests for calculate.utils.files module.
|
8
setup.py
Normal file
8
setup.py
Normal file
|
@ -0,0 +1,8 @@
|
|||
from setuptools import setup, find_packages
|
||||
from os.path import join, dirname
|
||||
|
||||
setup(
|
||||
name='calculate-lib',
|
||||
version='1.0',
|
||||
packages=find_packages(),
|
||||
)
|
0
tests/format/__init__.py
Normal file
0
tests/format/__init__.py
Normal file
83
tests/format/test_base.py
Normal file
83
tests/format/test_base.py
Normal file
|
@ -0,0 +1,83 @@
|
|||
import pytest
|
||||
from calculate.templates.format.base_format import BaseFormat
|
||||
|
||||
|
||||
@pytest.mark.base
|
||||
class TestJoinMethod:
|
||||
def test_if_inputs_are_dictionaries_with_string_keys_without_any_action_marks__the_dictionaties_just_merged(self, StringDictionaries):
|
||||
BaseObject = BaseFormat([])
|
||||
Original, Template, Result = StringDictionaries
|
||||
BaseObject._join(Original, Template, join_before=False)
|
||||
assert Original == Result
|
||||
|
||||
def test_if_inputs_are_dictionaries_with_tuple_keys_without_any_action_marks_as_their_keys__the_dictionaries_just_merged(self, TupleDictionaries):
|
||||
BaseObject = BaseFormat([])
|
||||
Original, Template, Result = TupleDictionaries
|
||||
BaseObject._join(Original, Template, join_before=False)
|
||||
assert Original == Result
|
||||
|
||||
def test_if_inputs_are_dictionaries_with_same_sections_which_contain_different_parameters__a_section_from_the_template_added_to_the_same_section_of_original_dictionary(self, MergeSectionDictionaries):
|
||||
BaseObject = BaseFormat([])
|
||||
Original, Template, Result = MergeSectionDictionaries
|
||||
BaseObject._join(Original, Template, join_before=False)
|
||||
assert Original == Result
|
||||
|
||||
def test_if_inputs_are_dictionaries_with_parameters_with_same_name_in_same_section__parameters_values_in_original_dictionary_changed_to_values_from_template(self, ChangeParameterDictionaries):
|
||||
BaseObject = BaseFormat([])
|
||||
Original, Template, Result = ChangeParameterDictionaries
|
||||
BaseObject._join(Original, Template, join_before=False)
|
||||
assert Original == Result
|
||||
|
||||
def test_if_input_template_dictionary_has_delete_mark_for_section__section_will_be_deleted(self, DeleteSectionDictionaries):
|
||||
BaseObject = BaseFormat([])
|
||||
Original, Template, Result = DeleteSectionDictionaries
|
||||
BaseObject._join(Original, Template, join_before=False)
|
||||
assert Original == Result
|
||||
|
||||
def test_if_input_template_dictionary_has_replace_mark_for_section__section_will_be_deleted(self, ReplaceSectionDictionaries):
|
||||
BaseObject = BaseFormat([])
|
||||
Original, Template, Result = ReplaceSectionDictionaries
|
||||
BaseObject._join(Original, Template, join_before=False)
|
||||
assert Original == Result
|
||||
|
||||
def test_if_input_template_dictionary_has_delete_mark_for_parameter__parameter_will_be_deleted(self, DeleteParameterDictionaries):
|
||||
BaseObject = BaseFormat([])
|
||||
Original, Template, Result = DeleteParameterDictionaries
|
||||
BaseObject._join(Original, Template, join_before=False)
|
||||
assert Original == Result
|
||||
|
||||
def test_if_input_dictionaries_have_no_sections_and_have_only_parameter_lines__it_will_be_processed_correctly(self, DictionariesWithoutSections):
|
||||
BaseObject = BaseFormat([])
|
||||
Original, Template, Result = DictionariesWithoutSections
|
||||
BaseObject._join(Original, Template, join_before=False)
|
||||
assert Original == Result
|
||||
|
||||
|
||||
@pytest.mark.base
|
||||
class TestLogicLinesMethod:
|
||||
def test_if_input_is_text_document_the_method_returns_list_of_its_lines(self):
|
||||
with open('./tests/format/testfiles/logic_lines_test.txt', 'r') as InputFile:
|
||||
InputText = InputFile.read()
|
||||
|
||||
processingMethods = []
|
||||
OutputLines = ['First string of test file.',
|
||||
'Second string of test file.',
|
||||
'Third string of test file.',
|
||||
'Fourth string of test file.']
|
||||
|
||||
BaseObject = BaseFormat(processingMethods)
|
||||
InputLines = BaseObject._get_list_of_logic_lines(InputText)
|
||||
assert InputLines == OutputLines
|
||||
|
||||
|
||||
def test_if_lines_in_document_divided_using_backslash_as_continuation_symbol__method_returns_list_of_full_lines(self):
|
||||
with open('./tests/format/testfiles/logic_lines_test_input.txt', 'r') as InputFile:
|
||||
InputText = InputFile.read()
|
||||
|
||||
with open('./tests/format/testfiles/logic_lines_test_output.txt', 'r') as OutputFile:
|
||||
OutputText = OutputFile.read()
|
||||
|
||||
BaseObject = BaseFormat([])
|
||||
InputLines = BaseObject._get_list_of_logic_lines(InputText)
|
||||
OutputLines = BaseObject._get_list_of_logic_lines(OutputText)
|
||||
assert InputLines == OutputLines
|
298
tests/format/test_bind.py
Normal file
298
tests/format/test_bind.py
Normal file
|
@ -0,0 +1,298 @@
|
|||
import pytest
|
||||
from collections import OrderedDict
|
||||
from calculate.templates.format.bind_format import BINDFormat
|
||||
|
||||
|
||||
@pytest.mark.bind
|
||||
class TestParsingMethods:
|
||||
def test_if_input_document_contains_just_few_parameter_lines__the_initialised_object_contains_correct_dictionary(self):
|
||||
document_text = '''directory "/var/bind";
|
||||
pid-file "/run/named/named.pid";
|
||||
disable-empty-zone "10.in-addr.arpa";
|
||||
'''
|
||||
|
||||
result = OrderedDict({
|
||||
('', 'directory'):
|
||||
['"/var/bind"'],
|
||||
('', 'pid-file'):
|
||||
['"/run/named/named.pid"'],
|
||||
('', 'disable-empty-zone'):
|
||||
['"10.in-addr.arpa"']
|
||||
})
|
||||
|
||||
bind_object = BINDFormat(document_text)
|
||||
assert bind_object._document_dictionary == result
|
||||
|
||||
def test_if_input_document_contains_some_block_of_parameters__the_initialised_object_contains_correct_dictionary(self):
|
||||
document_text = '''
|
||||
acl "dns_servers" {
|
||||
127.0.0.1;
|
||||
10.0.1.3;
|
||||
10.1.0.3;
|
||||
};
|
||||
|
||||
options {
|
||||
response-policy {
|
||||
zone "rpz.zone";
|
||||
};
|
||||
recursion yes;
|
||||
};
|
||||
|
||||
zone "localhost" IN {
|
||||
type master;
|
||||
file "pri/localhost.zone";
|
||||
notify no;
|
||||
}
|
||||
'''
|
||||
|
||||
acl_section = OrderedDict({('', '127.0.0.1'): [''],
|
||||
('', '10.0.1.3'): [''],
|
||||
('', '10.1.0.3'): ['']})
|
||||
response_section = OrderedDict({('', 'zone'): ['"rpz.zone"']})
|
||||
options_section = OrderedDict({('', 'response-policy'): response_section,
|
||||
('', 'recursion'): ['yes']})
|
||||
zone_section = OrderedDict({('', 'type'): ['master'],
|
||||
('', 'file'): ['"pri/localhost.zone"'],
|
||||
('', 'notify'): ['no']})
|
||||
result = OrderedDict({('', 'acl', '"dns_servers"'): acl_section,
|
||||
('', 'options'): options_section,
|
||||
('', 'zone', '"localhost"', 'IN'): zone_section})
|
||||
|
||||
bind_object = BINDFormat(document_text)
|
||||
assert bind_object._document_dictionary == result
|
||||
|
||||
def test_if_input_document_contains_some_blocks_with_similar_names__the_blocks_join_recursively(self):
|
||||
document_text = '''
|
||||
acl "dns_servers" {
|
||||
127.0.0.1;
|
||||
10.0.1.3;
|
||||
10.1.0.3;
|
||||
};
|
||||
|
||||
options {
|
||||
response-policy {
|
||||
mood "almost.blue";
|
||||
};
|
||||
todo "drink.beer"
|
||||
};
|
||||
|
||||
acl "dns_servers" {
|
||||
10.3.0.3;
|
||||
10.4.0.3;
|
||||
};
|
||||
|
||||
options {
|
||||
response-policy {
|
||||
zone "rpz.zone";
|
||||
};
|
||||
}
|
||||
'''
|
||||
acl_section = OrderedDict({('', '127.0.0.1'): [''],
|
||||
('', '10.0.1.3'): [''],
|
||||
('', '10.1.0.3'): [''],
|
||||
('', '10.3.0.3'): [''],
|
||||
('', '10.4.0.3'): ['']})
|
||||
response_section = OrderedDict({('', 'mood'): ['"almost.blue"'],
|
||||
('', 'zone'): ['"rpz.zone"']})
|
||||
options_section = OrderedDict({('', 'response-policy'):
|
||||
response_section,
|
||||
('', 'todo'): ['"drink.beer"']})
|
||||
|
||||
result = OrderedDict({('', 'acl', '"dns_servers"'): acl_section,
|
||||
('', 'options'): options_section})
|
||||
|
||||
bind_object = BINDFormat(document_text)
|
||||
assert bind_object._document_dictionary == result
|
||||
|
||||
def test_if_input_document_contains_blocks_and_parameters_with_action_marks__the_key_tuples_of_object_s_dictionary_have_it_as_its_first_element(self):
|
||||
document_text = '''
|
||||
!pid-file "/run/named/named.pid";
|
||||
-disable-empty-zone "10.in-addr.arpa";
|
||||
|
||||
acl "dns_servers" {
|
||||
!127.0.0.1;
|
||||
10.0.1.3;
|
||||
10.1.0.3;
|
||||
};
|
||||
|
||||
-options {
|
||||
!response-policy {
|
||||
zone "rpz.zone";
|
||||
};
|
||||
!recursion yes;
|
||||
}
|
||||
'''
|
||||
acl_section = OrderedDict({('!', '127.0.0.1'): [''],
|
||||
('', '10.0.1.3'): [''],
|
||||
('', '10.1.0.3'): ['']})
|
||||
response_section = OrderedDict({('', 'zone'): ['"rpz.zone"']})
|
||||
options_section = OrderedDict({('!', 'response-policy'):
|
||||
response_section,
|
||||
('!', 'recursion'): ['yes']})
|
||||
|
||||
result = OrderedDict({('!', 'pid-file'):
|
||||
['"/run/named/named.pid"'],
|
||||
('-', 'disable-empty-zone'):
|
||||
['"10.in-addr.arpa"'],
|
||||
('', 'acl', '"dns_servers"'): acl_section,
|
||||
('-', 'options'): options_section})
|
||||
|
||||
bind_object = BINDFormat(document_text)
|
||||
assert bind_object._document_dictionary == result
|
||||
|
||||
def test_if_parameters_and_blocks_in_input_document_has_some_comments__the_comments_will_be_collected_in_the_list_of_parameter_value_or_with_special_key_in_block_dictionary(self):
|
||||
document_text = '''
|
||||
// Comment 1
|
||||
!pid-file "/run/named/named.pid";
|
||||
/*
|
||||
* A very big comment.
|
||||
* Still here...
|
||||
* The pure giant of the comment kind.
|
||||
*/
|
||||
-disable-empty-zone "10.in-addr.arpa";
|
||||
|
||||
# Comment 2
|
||||
// Comment 3
|
||||
acl "dns_servers" {
|
||||
!127.0.0.1;
|
||||
// Comment 4
|
||||
10.0.1.3;
|
||||
10.1.0.3;
|
||||
};
|
||||
|
||||
-options {
|
||||
!response-policy {
|
||||
/*
|
||||
* This comment is very important.
|
||||
* And I have no idea, why this
|
||||
* comment is so important.
|
||||
*/
|
||||
zone "rpz.zone";
|
||||
};
|
||||
!recursion yes;
|
||||
}
|
||||
'''
|
||||
|
||||
acl_section = OrderedDict({'#': ['# Comment 2', '// Comment 3'],
|
||||
('!', '127.0.0.1'): [''],
|
||||
('', '10.0.1.3'): ['// Comment 4', ''],
|
||||
('', '10.1.0.3'): ['']})
|
||||
response_section = OrderedDict({('', 'zone'):
|
||||
['/*',
|
||||
'* This comment is very important.',
|
||||
'* And I have no idea, why this',
|
||||
'* comment is so important.',
|
||||
'*/',
|
||||
'"rpz.zone"']})
|
||||
options_section = OrderedDict({('!', 'response-policy'):
|
||||
response_section,
|
||||
('!', 'recursion'): ['yes']})
|
||||
|
||||
result = OrderedDict({('!', 'pid-file'):
|
||||
['// Comment 1',
|
||||
'"/run/named/named.pid"'],
|
||||
('-', 'disable-empty-zone'):
|
||||
['/*',
|
||||
'* A very big comment.',
|
||||
'* Still here...',
|
||||
'* The pure giant of the comment kind.',
|
||||
'*/',
|
||||
'"10.in-addr.arpa"'],
|
||||
('', 'acl', '"dns_servers"'): acl_section,
|
||||
('-', 'options'): options_section})
|
||||
|
||||
bind_object = BINDFormat(document_text)
|
||||
assert bind_object._document_dictionary == result
|
||||
|
||||
def test_if_the_IgnoreComments_flag_is_set__the_parser_ignores_all_comments(self):
|
||||
document_text = '''
|
||||
// Comment 1
|
||||
!pid-file "/run/named/named.pid";
|
||||
/*
|
||||
* A very big comment.
|
||||
* Still here...
|
||||
* The pure giant of comment kind.
|
||||
*/
|
||||
-disable-empty-zone "10.in-addr.arpa";
|
||||
|
||||
# Comment 2
|
||||
// Comment 3
|
||||
acl "dns_servers" {
|
||||
!127.0.0.1;
|
||||
// Comment 4
|
||||
10.0.1.3;
|
||||
10.1.0.3;
|
||||
};
|
||||
|
||||
-options {
|
||||
!response-policy {
|
||||
/*
|
||||
* This comment is very important.
|
||||
* And I have no idea, why this
|
||||
* comment is so important.
|
||||
*/
|
||||
zone "rpz.zone";
|
||||
};
|
||||
!recursion yes;
|
||||
}
|
||||
'''
|
||||
|
||||
acl_section = OrderedDict({('!', '127.0.0.1'): [''],
|
||||
('', '10.0.1.3'): [''],
|
||||
('', '10.1.0.3'): ['']})
|
||||
response_section = OrderedDict({('', 'zone'): ['"rpz.zone"']})
|
||||
options_section = OrderedDict({('!', 'response-policy'):
|
||||
response_section,
|
||||
('!', 'recursion'): ['yes']})
|
||||
|
||||
result = OrderedDict({('!', 'pid-file'):
|
||||
['"/run/named/named.pid"'],
|
||||
('-', 'disable-empty-zone'):
|
||||
['"10.in-addr.arpa"'],
|
||||
('', 'acl', '"dns_servers"'): acl_section,
|
||||
('-', 'options'): options_section})
|
||||
|
||||
bind_object = BINDFormat(document_text, ignore_comments=True)
|
||||
assert bind_object._document_dictionary == result
|
||||
|
||||
def test_if_input_document_contains_parameters_to_delete_without_values_or_with_empty_block__the_document_object_contains_dictionary_with_item_to_delete(self):
|
||||
document_text = '''
|
||||
!pid-file;
|
||||
|
||||
!acl "dns_servers" {};
|
||||
|
||||
options {
|
||||
!response-policy {};
|
||||
!recursion;
|
||||
}
|
||||
'''
|
||||
|
||||
options_section = OrderedDict({('!', 'response-policy'):
|
||||
OrderedDict(),
|
||||
('!', 'recursion'): ['']})
|
||||
|
||||
result = OrderedDict({('!', 'pid-file'):
|
||||
[''],
|
||||
('!', 'acl', '"dns_servers"'): OrderedDict(),
|
||||
('', 'options'): options_section})
|
||||
|
||||
bind_object = BINDFormat(document_text)
|
||||
assert bind_object._document_dictionary == result
|
||||
|
||||
def test_joining_documents_1(self):
|
||||
with open('./tests/format/testfiles/bind_original.conf', 'r') as original_file:
|
||||
original_text = original_file.read()
|
||||
print(original_text)
|
||||
bind_original_object = BINDFormat(original_text)
|
||||
|
||||
with open('./tests/format/testfiles/bind_template.conf', 'r') as template_file:
|
||||
template_text = template_file.read()
|
||||
bind_template_object = BINDFormat(template_text,
|
||||
ignore_comments=True)
|
||||
|
||||
bind_original_object.join_template(bind_template_object)
|
||||
|
||||
with open('./tests/format/testfiles/bind_result.conf', 'r') as result_file:
|
||||
result_text = result_file.read()
|
||||
|
||||
assert bind_original_object.get_document_text() == result_text
|
218
tests/format/test_compiz.py
Normal file
218
tests/format/test_compiz.py
Normal file
|
@ -0,0 +1,218 @@
|
|||
import pytest
|
||||
from collections import OrderedDict
|
||||
from calculate.templates.format.compiz_format import CompizFormat
|
||||
from pprint import pprint
|
||||
|
||||
|
||||
@pytest.mark.compiz
|
||||
class TestParsingMethods:
|
||||
def test_if_input_document_contains_just_few_parameter_lines__the_initialised_object_contains_correct_dictionary(self):
|
||||
document_text = '''
|
||||
[Added Associations]
|
||||
application/illustrator=zzz-gimp.desktop
|
||||
application/pdf=evince.desktop;
|
||||
application/rtf=libreoffice-writer.desktop;
|
||||
application/vnd.oasis.opendocument.spreadsheet=calculate-calc.desktop;
|
||||
'''
|
||||
|
||||
section = OrderedDict({('', 'application/illustrator'):
|
||||
['zzz-gimp.desktop'],
|
||||
('', 'application/pdf'):
|
||||
['evince.desktop;'],
|
||||
('', 'application/rtf'):
|
||||
['libreoffice-writer.desktop;'],
|
||||
('', 'application/vnd.oasis.opendocument.spreadsheet'):
|
||||
['calculate-calc.desktop;']})
|
||||
|
||||
result = OrderedDict({('', 'Added Associations'): section})
|
||||
|
||||
compiz_object = CompizFormat(document_text)
|
||||
assert compiz_object._document_dictionary == result
|
||||
|
||||
def test_if_input_document_contains_few_parameter_lines_and_some_empty_lines__the_initialized_object_contains_correct_dictionary(self):
|
||||
document_text = '''
|
||||
[Added Associations]
|
||||
|
||||
application/illustrator=zzz-gimp.desktop
|
||||
application/pdf=evince.desktop;
|
||||
|
||||
|
||||
application/rtf=libreoffice-writer.desktop;
|
||||
|
||||
application/vnd.oasis.opendocument.spreadsheet=calculate-calc.desktop;
|
||||
'''
|
||||
|
||||
section = OrderedDict({('', 'application/illustrator'):
|
||||
['zzz-gimp.desktop'],
|
||||
('', 'application/pdf'):
|
||||
['evince.desktop;'],
|
||||
('', 'application/rtf'):
|
||||
['libreoffice-writer.desktop;'],
|
||||
('', 'application/vnd.oasis.opendocument.spreadsheet'):
|
||||
["calculate-calc.desktop;"]})
|
||||
|
||||
result = OrderedDict({('', 'Added Associations'): section})
|
||||
|
||||
compiz_object = CompizFormat(document_text)
|
||||
assert compiz_object._document_dictionary == result
|
||||
|
||||
def test_if_input_document_contains_sections_with_different_names_but_different_parameters__the_parameters_merged_in_one_section(self):
|
||||
document_text = '''
|
||||
[Added Associations]
|
||||
application/illustrator=zzz-gimp.desktop
|
||||
application/pdf=evince.desktop;
|
||||
[Added Associations]
|
||||
application/rtf=libreoffice-writer.desktop;
|
||||
application/vnd.oasis.opendocument.spreadsheet=calculate-calc.desktop;
|
||||
'''
|
||||
|
||||
section = OrderedDict({('', 'application/illustrator'):
|
||||
['zzz-gimp.desktop'],
|
||||
('', 'application/pdf'):
|
||||
['evince.desktop;'],
|
||||
('', 'application/rtf'):
|
||||
['libreoffice-writer.desktop;'],
|
||||
('', 'application/vnd.oasis.opendocument.spreadsheet'):
|
||||
['calculate-calc.desktop;']})
|
||||
|
||||
result = OrderedDict({('', 'Added Associations'): section})
|
||||
|
||||
compiz_object = CompizFormat(document_text)
|
||||
assert compiz_object._document_dictionary == result
|
||||
|
||||
def test_if_input_document_contains_sections_with_parameters_with_action_marks__the_key_tuples_of_object_s_dictionary_have_it_as_its_first_element(self):
|
||||
document_text = '''
|
||||
[Added Associations]
|
||||
!application/illustrator=zzz-gimp.desktop
|
||||
-application/pdf=evince.desktop;
|
||||
!application/vnd.oasis.opendocument.spreadsheet=calculate-calc.desktop;
|
||||
'''
|
||||
|
||||
section = OrderedDict({('!', 'application/illustrator'):
|
||||
['zzz-gimp.desktop'],
|
||||
('-', 'application/pdf'):
|
||||
['evince.desktop;'],
|
||||
('!', 'application/vnd.oasis.opendocument.spreadsheet'):
|
||||
["calculate-calc.desktop;"]})
|
||||
|
||||
result = OrderedDict({('', 'Added Associations'): section})
|
||||
|
||||
compiz_object = CompizFormat(document_text)
|
||||
assert compiz_object._document_dictionary == result
|
||||
|
||||
def test_if_parameter_in_input_document_has_some_comments__the_comments_will_be_collected_in_the_list_of_parameter_value(self):
|
||||
document_text = '''
|
||||
# Comment
|
||||
[Added Associations]
|
||||
# Comment1
|
||||
application/illustrator=zzz-gimp.desktop
|
||||
application/pdf=evince.desktop;
|
||||
|
||||
# Comment2
|
||||
# Comment3
|
||||
|
||||
application/rtf=libreoffice-writer.desktop;
|
||||
|
||||
[Other Section]
|
||||
#Comment
|
||||
!application/vnd.oasis.opendocument.spreadsheet=calculate-calc.desktop;
|
||||
'''
|
||||
|
||||
section_1 = OrderedDict({'#': ['# Comment'],
|
||||
('', 'application/illustrator'):
|
||||
['# Comment1',
|
||||
'zzz-gimp.desktop'],
|
||||
('', 'application/pdf'):
|
||||
['evince.desktop;'],
|
||||
('', 'application/rtf'):
|
||||
['# Comment2',
|
||||
'# Comment3',
|
||||
'libreoffice-writer.desktop;']})
|
||||
|
||||
section_2 = OrderedDict({('!', 'application/vnd.oasis.opendocument.spreadsheet'):
|
||||
['#Comment',
|
||||
"calculate-calc.desktop;"]})
|
||||
|
||||
result = OrderedDict({('', 'Added Associations'): section_1,
|
||||
('', 'Other Section'): section_2})
|
||||
|
||||
compiz_object = CompizFormat(document_text)
|
||||
assert compiz_object._document_dictionary == result
|
||||
|
||||
def test_if_the_IgnoreComments_flag_is_set__the_parser_ignores_all_comments(self):
|
||||
document_text = '''
|
||||
# Comment
|
||||
[Added Associations]
|
||||
# Comment1
|
||||
application/illustrator=zzz-gimp.desktop
|
||||
application/pdf=evince.desktop;
|
||||
|
||||
# Comment2
|
||||
# Comment3
|
||||
|
||||
application/rtf=libreoffice-writer.desktop;
|
||||
|
||||
[Other Section]
|
||||
#Comment
|
||||
!application/vnd.oasis.opendocument.spreadsheet=calculate-calc.desktop;
|
||||
'''
|
||||
|
||||
section_1 = OrderedDict({('', 'application/illustrator'):
|
||||
['zzz-gimp.desktop'],
|
||||
('', 'application/pdf'):
|
||||
['evince.desktop;'],
|
||||
('', 'application/rtf'):
|
||||
['libreoffice-writer.desktop;']})
|
||||
|
||||
section_2 = OrderedDict({('!', 'application/vnd.oasis.opendocument.spreadsheet'):
|
||||
["calculate-calc.desktop;"]})
|
||||
|
||||
result = OrderedDict({('', 'Added Associations'): section_1,
|
||||
('', 'Other Section'): section_2})
|
||||
|
||||
compiz_object = CompizFormat(document_text, ignore_comments=True)
|
||||
assert compiz_object._document_dictionary == result
|
||||
|
||||
def test_if_input_document_contains_parameters_to_delete_without_assign_symbol_and_any_values_and_sections_to_delete__the_document_object_contains_dictionary_with_item_to_delete(self):
|
||||
document_text = '''
|
||||
[-Added Associations]
|
||||
# Comment
|
||||
!application/illustrator=zzz-gimp.desktop
|
||||
!application/pdf=
|
||||
!application/rtf
|
||||
|
||||
[!Other Section]
|
||||
application/vnd.oasis.opendocument.spreadsheet=calculate-calc.desktop;
|
||||
'''
|
||||
|
||||
section_1 = OrderedDict({('!', 'application/illustrator'):
|
||||
['# Comment',
|
||||
'zzz-gimp.desktop'],
|
||||
('!', 'application/pdf'): [],
|
||||
('!', 'application/rtf'): []})
|
||||
|
||||
section_2 = OrderedDict({('', 'application/vnd.oasis.opendocument.spreadsheet'):
|
||||
["calculate-calc.desktop;"]})
|
||||
|
||||
result = OrderedDict({('-', 'Added Associations'): section_1,
|
||||
('!', 'Other Section'): section_2})
|
||||
|
||||
compiz_object = CompizFormat(document_text)
|
||||
assert compiz_object._document_dictionary == result
|
||||
|
||||
def test_joining_documents_1(self):
|
||||
with open('./tests/format/testfiles/compiz_original', 'r') as original_file:
|
||||
original_text = original_file.read()
|
||||
compiz_original_object = CompizFormat(original_text)
|
||||
|
||||
with open('./tests/format/testfiles/compiz_template', 'r') as template_file:
|
||||
template_text = template_file.read()
|
||||
compiz_template_object = CompizFormat(template_text,
|
||||
ignore_comments=True)
|
||||
|
||||
compiz_original_object.join_template(compiz_template_object)
|
||||
|
||||
with open('./tests/format/testfiles/compiz_result', 'r') as result_file:
|
||||
result_text = result_file.read()
|
||||
|
||||
assert compiz_original_object.get_document_text() == result_text
|
97
tests/format/test_diff.py
Normal file
97
tests/format/test_diff.py
Normal file
|
@ -0,0 +1,97 @@
|
|||
import pytest
|
||||
from calculate.templates.format.diff_format import DiffFormat
|
||||
from calculate.utils.files import Process
|
||||
from os import path
|
||||
import os
|
||||
|
||||
|
||||
@pytest.mark.diff
|
||||
class TestExecuteMethods:
|
||||
def test_if_diff_patch_used_for_patching_of_several_files__it_changes_patched_file_correctly(self):
|
||||
test_result = True
|
||||
root_path = path.join(os.getcwd(), 'tests/format/testfiles/')
|
||||
with open(path.join(root_path, 'diff_1.patch')) as patch_file:
|
||||
patch_text = patch_file.read()
|
||||
|
||||
diff_patch = DiffFormat(patch_text)
|
||||
print('Path:', root_path)
|
||||
output = diff_patch.execute_format(root_path=root_path)
|
||||
if output:
|
||||
print('Changed files:')
|
||||
for changed_file in diff_patch._changed_files_list:
|
||||
print(changed_file, ':', sep='')
|
||||
with open(path.join(diff_patch._root_path, changed_file)) as patched_file:
|
||||
patched_file_text = patched_file.read()
|
||||
print(patched_file_text)
|
||||
other_file_name = 'b' + changed_file[1:]
|
||||
with open(path.join(diff_patch._root_path,
|
||||
other_file_name)) as other_file:
|
||||
other_file_text = other_file.read()
|
||||
test_result = test_result and (other_file_text == patched_file_text)
|
||||
|
||||
return_patch_run = Process('patch', '-R',
|
||||
'-p{}'.format(diff_patch._last_level),
|
||||
cwd=root_path)
|
||||
return_patch_run.write(patch_text)
|
||||
output = return_patch_run.read()
|
||||
|
||||
if return_patch_run.success():
|
||||
print('[*] Changes was returned...')
|
||||
else:
|
||||
print('[!] Changes was not returned...')
|
||||
else:
|
||||
test_result = False
|
||||
assert test_result
|
||||
|
||||
def test_if_diff_patch_used_for_patching_of_directories__it_changes_files_in_directories_and_adds_ones(self):
|
||||
test_result = True
|
||||
root_path = path.join(os.getcwd(),
|
||||
'tests/format/testfiles/a1')
|
||||
patch_path = path.join(os.getcwd(),
|
||||
'tests/format/testfiles/diff_2.patch')
|
||||
with open(path.join(patch_path)) as patch_file:
|
||||
patch_text = patch_file.read()
|
||||
|
||||
diff_patch = DiffFormat(patch_text)
|
||||
print('Path:', root_path)
|
||||
output = diff_patch.execute_format(root_path=root_path)
|
||||
print('Output:')
|
||||
print(output)
|
||||
if output:
|
||||
print('Changed files:')
|
||||
for changed_file in diff_patch._changed_files_list:
|
||||
print(changed_file, ':', sep='')
|
||||
file_path = path.join(diff_patch._root_path, changed_file)
|
||||
with open(file_path) as patched_file:
|
||||
patched_file_text = patched_file.read()
|
||||
print(patched_file_text)
|
||||
other_file_path = os.path.join(path.dirname(root_path),
|
||||
'b1', changed_file)
|
||||
with open(other_file_path) as other_file:
|
||||
other_file_text = other_file.read()
|
||||
test_result = test_result and (other_file_text == patched_file_text)
|
||||
if not test_result:
|
||||
print('Differences:')
|
||||
try:
|
||||
diff_process = Process('diff', '-u',
|
||||
file_path,
|
||||
other_file_path)
|
||||
diff_result = diff_process.read()
|
||||
print(diff_result)
|
||||
except Exception as error:
|
||||
print('diff was not executed.')
|
||||
print('Reason:', str(error))
|
||||
|
||||
reverse_patch_run = Process('patch', '-R',
|
||||
'-p{}'.format(diff_patch._last_level),
|
||||
cwd=root_path)
|
||||
reverse_patch_run.write(patch_text)
|
||||
output = reverse_patch_run.read()
|
||||
|
||||
if reverse_patch_run.success():
|
||||
print('[*] Changes was returned...')
|
||||
else:
|
||||
print('[!] Changes was not returned...')
|
||||
else:
|
||||
test_result = False
|
||||
assert test_result
|
255
tests/format/test_dovecot.py
Normal file
255
tests/format/test_dovecot.py
Normal file
|
@ -0,0 +1,255 @@
|
|||
import pytest
|
||||
from collections import OrderedDict
|
||||
from calculate.templates.format.dovecot_format import DovecotFormat
|
||||
|
||||
|
||||
@pytest.mark.dovecot
|
||||
class TestParsingMethods:
|
||||
def test_if_input_document_contains_just_few_parameter_lines__the_initialised_object_contains_correct_dictionary(self):
|
||||
document_text = '''auth_default_realm = domain.com
|
||||
auth_mechanisms = plain login
|
||||
|
||||
!include conf.d/imap.conf
|
||||
!include_try passwords.conf
|
||||
|
||||
auth_realms = domain.com domain2.com
|
||||
'''
|
||||
|
||||
result = OrderedDict({('', 'auth_default_realm'):
|
||||
['domain.com'],
|
||||
('', 'auth_mechanisms'):
|
||||
['plain login'],
|
||||
('', '!include', 'conf.d/imap.conf'):
|
||||
[''],
|
||||
('', '!include_try', 'passwords.conf'):
|
||||
[''],
|
||||
('', 'auth_realms'):
|
||||
['domain.com domain2.com']
|
||||
})
|
||||
|
||||
dovecot_object = DovecotFormat(document_text)
|
||||
assert dovecot_object._document_dictionary == result
|
||||
|
||||
def test_if_input_document_contains_some_block_of_parameters__the_initialised_object_contains_correct_dictionary(self):
|
||||
document_text = '''
|
||||
section optional_name {
|
||||
section_setting_key = section_setting_value
|
||||
subsection optional_subname {
|
||||
subkey = subvalue
|
||||
}
|
||||
}
|
||||
|
||||
local 127.0.0.2 {
|
||||
key = 127.0.0.2
|
||||
}
|
||||
'''
|
||||
subsection = OrderedDict({('', 'subkey'): ['subvalue']})
|
||||
section = OrderedDict({('', 'section_setting_key'):
|
||||
['section_setting_value'],
|
||||
('', 'subsection', 'optional_subname'):
|
||||
subsection})
|
||||
local = OrderedDict({('', 'key'): ['127.0.0.2']})
|
||||
result = OrderedDict({('', 'section', 'optional_name'):
|
||||
section,
|
||||
('', 'local', '127.0.0.2'):
|
||||
local})
|
||||
|
||||
dovecot_object = DovecotFormat(document_text)
|
||||
assert dovecot_object._document_dictionary == result
|
||||
|
||||
def test_if_input_document_contains_some_blocks_with_similar_names__the_blocks_join_recursively(self):
|
||||
document_text = '''
|
||||
section optional_name {
|
||||
section_setting_key = section_setting_value
|
||||
subsection optional_subname {
|
||||
subkey = subvalue
|
||||
}
|
||||
}
|
||||
|
||||
local 127.0.0.2 {
|
||||
key = 127.0.0.2
|
||||
}
|
||||
|
||||
section optional_name {
|
||||
subsection optional_subname {
|
||||
otherkey = value
|
||||
}
|
||||
}
|
||||
|
||||
local 127.0.0.2 {
|
||||
key = 127.0.0.2
|
||||
subsect name {
|
||||
param = no
|
||||
}
|
||||
}
|
||||
'''
|
||||
|
||||
subsection = OrderedDict({('', 'subkey'): ['subvalue'],
|
||||
('', 'otherkey'): ['value']})
|
||||
section = OrderedDict({('', 'section_setting_key'):
|
||||
['section_setting_value'],
|
||||
('', 'subsection', 'optional_subname'):
|
||||
subsection})
|
||||
sub_sect = OrderedDict({('', 'param'): ['no']})
|
||||
local = OrderedDict({('', 'key'): ['127.0.0.2'],
|
||||
('', 'subsect', 'name'): sub_sect})
|
||||
result = OrderedDict({('', 'section', 'optional_name'):
|
||||
section,
|
||||
('', 'local', '127.0.0.2'):
|
||||
local})
|
||||
|
||||
dovecot_object = DovecotFormat(document_text)
|
||||
assert dovecot_object._document_dictionary == result
|
||||
|
||||
def test_if_input_document_contains_blocks_and_parameters_with_action_marks__the_key_tuples_of_object_s_dictionary_have_it_as_its_first_element(self):
|
||||
document_text = '''
|
||||
!auth_mechanisms = plain login
|
||||
|
||||
!!include conf.d/imap.conf
|
||||
|
||||
section optional_name {
|
||||
!section_setting_key = section_setting_value
|
||||
-subsection optional_subname {
|
||||
subkey = subvalue
|
||||
}
|
||||
}
|
||||
|
||||
!local 127.0.0.2 {
|
||||
key = 127.0.0.2
|
||||
}
|
||||
'''
|
||||
|
||||
subsection = OrderedDict({('', 'subkey'): ['subvalue']})
|
||||
section = OrderedDict({('!', 'section_setting_key'):
|
||||
['section_setting_value'],
|
||||
('-', 'subsection', 'optional_subname'):
|
||||
subsection})
|
||||
local = OrderedDict({('', 'key'): ['127.0.0.2']})
|
||||
result = OrderedDict({('!', 'auth_mechanisms'):
|
||||
['plain login'],
|
||||
('!', '!include', 'conf.d/imap.conf'):
|
||||
[''],
|
||||
('', 'section', 'optional_name'):
|
||||
section,
|
||||
('!', 'local', '127.0.0.2'):
|
||||
local})
|
||||
|
||||
dovecot_object = DovecotFormat(document_text)
|
||||
assert dovecot_object._document_dictionary == result
|
||||
|
||||
def test_if_parameters_and_blocks_in_input_document_has_some_comments__the_comments_will_be_collected_in_the_list_of_parameter_value_or_with_special_key_in_block_dictionary(self):
|
||||
document_text = '''
|
||||
# Comment 1
|
||||
auth_mechanisms = plain login
|
||||
|
||||
# Comment 2
|
||||
!include conf.d/imap.conf
|
||||
|
||||
# Comment 3
|
||||
section optional_name {
|
||||
section_setting_key = section_setting_value
|
||||
# Comment in the block.
|
||||
subsection optional_subname {
|
||||
# Comment
|
||||
subkey = subvalue
|
||||
}
|
||||
}
|
||||
'''
|
||||
|
||||
subsection = OrderedDict({'#': ['# Comment in the block.'],
|
||||
('', 'subkey'): ['# Comment', 'subvalue']})
|
||||
section = OrderedDict({'#': ['# Comment 3'],
|
||||
('', 'section_setting_key'):
|
||||
['section_setting_value'],
|
||||
('', 'subsection', 'optional_subname'):
|
||||
subsection})
|
||||
result = OrderedDict({('', 'auth_mechanisms'):
|
||||
['# Comment 1', 'plain login'],
|
||||
('', '!include', 'conf.d/imap.conf'):
|
||||
['# Comment 2', ''],
|
||||
('', 'section', 'optional_name'):
|
||||
section})
|
||||
|
||||
dovecot_object = DovecotFormat(document_text)
|
||||
assert dovecot_object._document_dictionary == result
|
||||
|
||||
def test_if_the_IgnoreComments_flag_is_set__the_parser_ignores_all_comments(self):
|
||||
document_text = '''
|
||||
# Comment 1
|
||||
auth_mechanisms = plain login
|
||||
|
||||
# Comment 2
|
||||
!include conf.d/imap.conf
|
||||
|
||||
# Comment 3
|
||||
section optional_name {
|
||||
section_setting_key = section_setting_value
|
||||
# Comment in the block.
|
||||
subsection optional_subname {
|
||||
# Comment
|
||||
subkey = subvalue
|
||||
}
|
||||
}
|
||||
'''
|
||||
|
||||
subsection = OrderedDict({('', 'subkey'): ['subvalue']})
|
||||
section = OrderedDict({('', 'section_setting_key'):
|
||||
['section_setting_value'],
|
||||
('', 'subsection', 'optional_subname'):
|
||||
subsection})
|
||||
result = OrderedDict({('', 'auth_mechanisms'):
|
||||
['plain login'],
|
||||
('', '!include', 'conf.d/imap.conf'):
|
||||
[''],
|
||||
('', 'section', 'optional_name'):
|
||||
section})
|
||||
|
||||
dovecot_object = DovecotFormat(document_text, ignore_comments=True)
|
||||
assert dovecot_object._document_dictionary == result
|
||||
|
||||
def test_if_input_document_contains_parameters_to_delete_without_values_or_with_empty_block__the_document_object_contains_dictionary_with_item_to_delete(self):
|
||||
document_text = '''
|
||||
!auth_mechanisms
|
||||
!auth_realms =
|
||||
|
||||
section optional_name {
|
||||
!section_setting_key
|
||||
!subsection optional_subname {
|
||||
}
|
||||
}
|
||||
|
||||
!local 127.0.0.2 {
|
||||
}
|
||||
'''
|
||||
|
||||
section = OrderedDict({('!', 'section_setting_key'): [''],
|
||||
('!', 'subsection', 'optional_subname'):
|
||||
OrderedDict()})
|
||||
result = OrderedDict({('!', 'auth_mechanisms'):
|
||||
[''],
|
||||
('!', 'auth_realms'):
|
||||
[''],
|
||||
('', 'section', 'optional_name'):
|
||||
section,
|
||||
('!', 'local', '127.0.0.2'):
|
||||
OrderedDict()})
|
||||
|
||||
dovecot_object = DovecotFormat(document_text)
|
||||
assert dovecot_object._document_dictionary == result
|
||||
|
||||
def test_joining_documents_1(self):
|
||||
with open('./tests/format/testfiles/dovecot_original.conf', 'r') as original_file:
|
||||
original_text = original_file.read()
|
||||
dovecot_original_object = DovecotFormat(original_text)
|
||||
|
||||
with open('./tests/format/testfiles/dovecot_template.conf', 'r') as template_file:
|
||||
template_text = template_file.read()
|
||||
dovecot_template_object = DovecotFormat(template_text,
|
||||
ignore_comments=True)
|
||||
|
||||
dovecot_original_object.join_template(dovecot_template_object)
|
||||
|
||||
with open('./tests/format/testfiles/dovecot_result.conf', 'r') as result_file:
|
||||
result_text = result_file.read()
|
||||
|
||||
assert dovecot_original_object.get_document_text() == result_text
|
44
tests/format/test_json.py
Normal file
44
tests/format/test_json.py
Normal file
|
@ -0,0 +1,44 @@
|
|||
import pytest
|
||||
from collections import OrderedDict
|
||||
from calculate.templates.format.json_format import JSONFormat
|
||||
|
||||
|
||||
@pytest.mark.json
|
||||
class TestParsingMethods:
|
||||
def test_if_input_document_contains_just_few_parameters_and_parameter_blocks__the_initialised_object_contains_correct_dictionary(self):
|
||||
documentText = '''
|
||||
{
|
||||
"Param1":"ParamValue1",
|
||||
"Param2": 1,
|
||||
"BlockParam1":{
|
||||
"BlockParam1":1,
|
||||
"BlockParam2":0
|
||||
},
|
||||
"Param3": true
|
||||
}
|
||||
'''
|
||||
|
||||
blockContent = OrderedDict({"BlockParam1": 1, "BlockParam2": 0})
|
||||
result = OrderedDict({'Param1': 'ParamValue1',
|
||||
'Param2': 1,
|
||||
'BlockParam1': blockContent,
|
||||
'Param3': True})
|
||||
|
||||
jsonObject = JSONFormat(documentText)
|
||||
assert jsonObject._document_dictionary == result
|
||||
|
||||
def test_joining_documents_1(self):
|
||||
with open('./tests/format/testfiles/json_original.json', 'r') as originalFile:
|
||||
originalText = originalFile.read()
|
||||
jsonOriginalObject = JSONFormat(originalText)
|
||||
|
||||
with open('./tests/format/testfiles/json_template.json', 'r') as templateFile:
|
||||
templateText = templateFile.read()
|
||||
jsonTemplateObject = JSONFormat(templateText)
|
||||
|
||||
jsonOriginalObject.join_template(jsonTemplateObject)
|
||||
|
||||
with open('./tests/format/testfiles/json_result.json', 'r') as resultFile:
|
||||
resultText = resultFile.read()
|
||||
|
||||
assert jsonOriginalObject.get_document_text() == resultText
|
222
tests/format/test_kde.py
Normal file
222
tests/format/test_kde.py
Normal file
|
@ -0,0 +1,222 @@
|
|||
import pytest
|
||||
from collections import OrderedDict
|
||||
from calculate.templates.format.kde_format import KDEFormat
|
||||
|
||||
|
||||
@pytest.mark.kde
|
||||
class TestParsingMethods:
|
||||
def test_if_input_document_contains_just_few_parameter_lines__the_initialised_object_contains_correct_dictionary(self):
|
||||
document_text = '''[section name][first][second]
|
||||
parameter name = /home/divanov/Home
|
||||
other parameter = yes'''
|
||||
|
||||
param_line_1 = OrderedDict({('', 'parameter name'): ['/home/divanov/Home']})
|
||||
param_line_2 = OrderedDict({('', 'other parameter'): ['yes']})
|
||||
|
||||
result = OrderedDict({('', 'section name', 'first', 'second'):
|
||||
OrderedDict(**param_line_1,
|
||||
**param_line_2)})
|
||||
|
||||
kde_object = KDEFormat(document_text)
|
||||
assert kde_object._document_dictionary == result
|
||||
|
||||
def test_if_input_document_contains_parameters_with_values_with_unicode_symbols__the_initialized_object_contains_correct_dictionary(self):
|
||||
document_text = '''
|
||||
[Desktop Entry][val]
|
||||
GenericName=IRC Client
|
||||
GenericName[ar]=عميل IRC
|
||||
GenericName[be]=Кліент IRC
|
||||
GenericName[bg]=IRC клиент
|
||||
GenericName[bs]=IRC klijent
|
||||
GenericName[ca]=Client d'IRC
|
||||
GenericName[ca@valencia]=Client d'IRC'''
|
||||
|
||||
section = OrderedDict({('', 'GenericName'): ['IRC Client'],
|
||||
('', 'GenericName[ar]'): ['عميل IRC'],
|
||||
('', 'GenericName[be]'): ['Кліент IRC'],
|
||||
('', 'GenericName[bg]'): ['IRC клиент'],
|
||||
('', 'GenericName[bs]'): ['IRC klijent'],
|
||||
('', 'GenericName[ca]'): ["Client d'IRC"],
|
||||
('', 'GenericName[ca@valencia]'): ["Client d'IRC"]})
|
||||
|
||||
result = OrderedDict({('', 'Desktop Entry', 'val'): section})
|
||||
|
||||
kde_object = KDEFormat(document_text)
|
||||
assert kde_object._document_dictionary == result
|
||||
|
||||
def test_if_input_document_contains_few_parameter_lines_and_some_empty_lines__the_initialized_object_contains_correct_dictionary(self):
|
||||
document_text = '''
|
||||
[PlasmaViews][Panel 69][Horizontal2048]
|
||||
alignment=132
|
||||
|
||||
length=674
|
||||
|
||||
|
||||
thickness = 56
|
||||
|
||||
[Desktop Entry]
|
||||
|
||||
Exec=konversation -qwindowtitle %c %u
|
||||
'''
|
||||
|
||||
section1Content = OrderedDict({('', 'alignment'): ['132'],
|
||||
('', 'length'): ['674'],
|
||||
('', 'thickness'): ['56']})
|
||||
|
||||
section_2_content = OrderedDict({('', 'Exec'): ['konversation -qwindowtitle %c %u']})
|
||||
|
||||
result = OrderedDict({('', 'PlasmaViews', 'Panel 69', 'Horizontal2048'): section1Content,
|
||||
('', 'Desktop Entry'): section_2_content})
|
||||
|
||||
kde_object = KDEFormat(document_text)
|
||||
assert kde_object._document_dictionary == result
|
||||
|
||||
def test_if_input_document_contains_sections_with_different_names_but_different_parameters__the_parameters_merged_in_one_section(self):
|
||||
document_text = '''
|
||||
[PlasmaViews][Panel 69][Horizontal2048]
|
||||
alignment=132
|
||||
|
||||
length=674
|
||||
|
||||
[PlasmaViews][Panel 69][Horizontal2048]
|
||||
|
||||
thickness = 56
|
||||
|
||||
'''
|
||||
|
||||
section1Content = OrderedDict({('', 'alignment'): ['132'],
|
||||
('', 'length'): ['674'],
|
||||
('', 'thickness'): ['56']})
|
||||
|
||||
result = OrderedDict({('', 'PlasmaViews', 'Panel 69', 'Horizontal2048'): section1Content})
|
||||
|
||||
kde_object = KDEFormat(document_text)
|
||||
assert kde_object._document_dictionary == result
|
||||
|
||||
def test_if_input_document_contains_sections_with_parameters_with_action_marks__the_key_tuples_of_object_s_dictionary_have_it_as_its_first_element(self):
|
||||
document_text = '''
|
||||
[PlasmaViews][Panel 69][Horizontal2048]
|
||||
!alignment=132
|
||||
length=674
|
||||
-thickness = 56
|
||||
'''
|
||||
|
||||
section1Content = OrderedDict({('!', 'alignment'): ['132'],
|
||||
('', 'length'): ['674'],
|
||||
('-', 'thickness'): ['56']})
|
||||
|
||||
result = OrderedDict({('', 'PlasmaViews', 'Panel 69', 'Horizontal2048'): section1Content})
|
||||
|
||||
kde_object = KDEFormat(document_text)
|
||||
assert kde_object._document_dictionary == result
|
||||
|
||||
def test_if_parameter_in_input_document_has_some_comments__the_comments_will_be_collected_in_the_list_of_parameter_value(self):
|
||||
document_text = '''
|
||||
# Comment to section
|
||||
[PlasmaViews][Panel 69][Horizontal2048]
|
||||
# Comment 1
|
||||
alignment=132
|
||||
length=674
|
||||
|
||||
# Comment 2
|
||||
#Comment 3
|
||||
thickness = 56
|
||||
|
||||
[Desktop Entry]
|
||||
# Comment
|
||||
|
||||
Exec=konversation -qwindowtitle %c %u
|
||||
'''
|
||||
|
||||
section_1_content = OrderedDict({'#': ['# Comment to section'],
|
||||
('', 'alignment'): ['# Comment 1',
|
||||
'132'],
|
||||
('', 'length'): ['674'],
|
||||
('', 'thickness'): ['# Comment 2',
|
||||
'#Comment 3',
|
||||
'56']})
|
||||
|
||||
section_2_content = OrderedDict({('', 'Exec'): ['# Comment',
|
||||
'konversation -qwindowtitle %c %u']})
|
||||
|
||||
result = OrderedDict({('', 'PlasmaViews', 'Panel 69', 'Horizontal2048'): section_1_content,
|
||||
('', 'Desktop Entry'): section_2_content})
|
||||
|
||||
kde_object = KDEFormat(document_text)
|
||||
assert kde_object._document_dictionary == result
|
||||
|
||||
def test_if_the_IgnoreComments_flag_is_set__the_parser_ignores_all_comments(self):
|
||||
document_text = '''
|
||||
# Comment to section
|
||||
[PlasmaViews][Panel 69][Horizontal2048]
|
||||
# Comment 1
|
||||
alignment=132
|
||||
length=674
|
||||
|
||||
# Comment 2
|
||||
#Comment 3
|
||||
thickness = 56
|
||||
|
||||
[Desktop Entry]
|
||||
# Comment
|
||||
|
||||
Exec=konversation -qwindowtitle %c %u
|
||||
'''
|
||||
|
||||
section_1_content = OrderedDict({('', 'alignment'): ['132'],
|
||||
('', 'length'): ['674'],
|
||||
('', 'thickness'): ['56']})
|
||||
|
||||
section_2_content = OrderedDict({('', 'Exec'): ['konversation -qwindowtitle %c %u']})
|
||||
|
||||
result = OrderedDict({('', 'PlasmaViews', 'Panel 69', 'Horizontal2048'): section_1_content,
|
||||
('', 'Desktop Entry'): section_2_content})
|
||||
|
||||
kde_object = KDEFormat(document_text, ignore_comments=True)
|
||||
assert kde_object._document_dictionary == result
|
||||
|
||||
def test_if_input_document_contains_parameters_to_delete_without_assign_symbol_and_any_values_and_sections_to_delete__the_document_object_contains_dictionary_with_item_to_delete(self):
|
||||
document_text = '''
|
||||
[PlasmaViews][Panel 69][Horizontal2048]
|
||||
alignment=132
|
||||
!length =
|
||||
!thickness
|
||||
[!PlasmaViews][Panel 69]
|
||||
alignment=132
|
||||
panelVisibility=1
|
||||
[-Desktop Entry]
|
||||
Exec=konversation -qwindowtitle %c %u
|
||||
'''
|
||||
|
||||
section_1_content = OrderedDict({('', 'alignment'): ['132'],
|
||||
('!', 'length'): [],
|
||||
('!', 'thickness'): []})
|
||||
|
||||
section_2_content = OrderedDict({('', 'alignment'): ['132'],
|
||||
('', 'panelVisibility'): ['1']})
|
||||
|
||||
section3Content = OrderedDict({('', 'Exec'): ['konversation -qwindowtitle %c %u']})
|
||||
|
||||
result = OrderedDict({('', 'PlasmaViews', 'Panel 69', 'Horizontal2048'): section_1_content,
|
||||
('!', 'PlasmaViews', 'Panel 69'): section_2_content,
|
||||
('-', 'Desktop Entry'): section3Content})
|
||||
|
||||
kde_object = KDEFormat(document_text)
|
||||
assert kde_object._document_dictionary == result
|
||||
|
||||
def test_joining_documents_1(self):
|
||||
with open('./tests/format/testfiles/kde_original', 'r') as original_file:
|
||||
original_text = original_file.read()
|
||||
kde_original_object = KDEFormat(original_text)
|
||||
|
||||
with open('./tests/format/testfiles/kde_template', 'r') as template_file:
|
||||
template_text = template_file.read()
|
||||
kde_template_object = KDEFormat(template_text,
|
||||
ignore_comments=True)
|
||||
|
||||
kde_original_object.join_template(kde_template_object)
|
||||
|
||||
with open('./tests/format/testfiles/kde_result', 'r') as result_file:
|
||||
result_text = result_file.read()
|
||||
|
||||
assert kde_original_object.get_document_text() == result_text
|
112
tests/format/test_kernel.py
Normal file
112
tests/format/test_kernel.py
Normal file
|
@ -0,0 +1,112 @@
|
|||
import pytest
|
||||
from collections import OrderedDict
|
||||
from calculate.templates.format.kernel_format import KernelFormat
|
||||
|
||||
|
||||
@pytest.mark.kernel
|
||||
class TestParsingMethods:
|
||||
def test_if_input_document_contains_just_few_parameter_lines__the_initialised_object_contains_correct_dictionary(self):
|
||||
document_text = '''
|
||||
CONFIG_CC_IS_GCC=y
|
||||
CONFIG_GCC_VERSION=90200
|
||||
'''
|
||||
|
||||
result = OrderedDict({('', 'CONFIG_CC_IS_GCC'): ['y'],
|
||||
('', 'CONFIG_GCC_VERSION'): ['90200']})
|
||||
|
||||
kernel_object = KernelFormat(document_text)
|
||||
assert kernel_object._document_dictionary == result
|
||||
|
||||
def test_if_input_document_contains_few_parameter_lines_and_some_empty_lines__the_initialized_object_contains_correct_dictionary(self):
|
||||
document_text = '''
|
||||
CONFIG_CLANG_VERSION=0
|
||||
|
||||
|
||||
|
||||
|
||||
CONFIG_CC_HAS_ASM_GOTO=y
|
||||
|
||||
|
||||
CONFIG_IRQ_WORK=y
|
||||
'''
|
||||
|
||||
result = OrderedDict({('', 'CONFIG_CLANG_VERSION'): ['0'],
|
||||
('', 'CONFIG_CC_HAS_ASM_GOTO'): ['y'],
|
||||
('', 'CONFIG_IRQ_WORK'): ['y']})
|
||||
|
||||
kernel_object = KernelFormat(document_text)
|
||||
assert kernel_object._document_dictionary == result
|
||||
|
||||
def test_if_input_document_contains_parameters_with_action_marks__the_key_tuples_of_object_s_dictionary_have_it_as_its_first_element(self):
|
||||
document_text = '''
|
||||
-CONFIG_REISERFS_FS=y
|
||||
CONFIG_CC_IS_GCC=y
|
||||
!CONFIG_IRQ_WORK=y
|
||||
'''
|
||||
|
||||
result = OrderedDict({('-', 'CONFIG_REISERFS_FS'): ['y'],
|
||||
('', 'CONFIG_CC_IS_GCC'): ['y'],
|
||||
('!', 'CONFIG_IRQ_WORK'): ['y']})
|
||||
|
||||
kernel_object = KernelFormat(document_text)
|
||||
assert kernel_object._document_dictionary == result
|
||||
|
||||
def test_if_parameter_in_input_document_has_some_comments__the_comments_will_be_collected_in_the_list_of_parameter_value(self):
|
||||
document_text = '''# Comment1
|
||||
CONFIG_DEFAULT_HOSTNAME="calculate"
|
||||
|
||||
CONFIG_SWAP=y
|
||||
|
||||
|
||||
# Comment2
|
||||
# Comment3
|
||||
CONFIG_SYSVIPC=y
|
||||
CONFIG_SYSVIPC_SYSCTL=y
|
||||
|
||||
# Очень важный комментарий, который нужно удалить.
|
||||
!CONFIG_CROSS_MEMORY_ATTACH=y
|
||||
'''
|
||||
|
||||
result = OrderedDict({('', 'CONFIG_DEFAULT_HOSTNAME'):
|
||||
['# Comment1', '"calculate"'],
|
||||
('', 'CONFIG_SWAP'):
|
||||
['y'],
|
||||
('', 'CONFIG_SYSVIPC'):
|
||||
['# Comment2', '# Comment3', 'y'],
|
||||
('', 'CONFIG_SYSVIPC_SYSCTL'): ['y'],
|
||||
('!', 'CONFIG_CROSS_MEMORY_ATTACH'):
|
||||
['# Очень важный комментарий, который нужно удалить.','y']})
|
||||
|
||||
kernel_object = KernelFormat(document_text)
|
||||
assert kernel_object._document_dictionary == result
|
||||
|
||||
def test_if_input_document_contains_parameters_to_delete_without_assign_symbol_and_any_values__the_document_object_contains_dictionary_with_item_to_delete(self):
|
||||
document_text = '''
|
||||
!CONFIG_REISERFS_FS=y
|
||||
!CONFIG_EXT3_FS_POSIX_ACL=
|
||||
!CONFIG_EXT3_FS_SECURITY
|
||||
'''
|
||||
|
||||
result = OrderedDict({('!', 'CONFIG_REISERFS_FS'): ['y'],
|
||||
('!', 'CONFIG_EXT3_FS_POSIX_ACL'): [],
|
||||
('!', 'CONFIG_EXT3_FS_SECURITY'): []})
|
||||
|
||||
kernel_object = KernelFormat(document_text)
|
||||
assert kernel_object._document_dictionary == result
|
||||
|
||||
def test_joining_documents_1(self):
|
||||
with open('./tests/format/testfiles/kernel_original', 'r') as original_file:
|
||||
original_text = original_file.read()
|
||||
kernel_original_object = KernelFormat(original_text)
|
||||
|
||||
with open('./tests/format/testfiles/kernel_template', 'r') as template_file:
|
||||
template_text = template_file.read()
|
||||
kernel_template_object = KernelFormat(template_text,
|
||||
ignore_comments=True)
|
||||
|
||||
kernel_original_object.join_template(kernel_template_object)
|
||||
|
||||
with open('./tests/format/testfiles/kernel_result', 'r') as result_file:
|
||||
result_text = result_file.read()
|
||||
|
||||
assert kernel_original_object.get_document_text() == result_text
|
364
tests/format/test_ldap.py
Normal file
364
tests/format/test_ldap.py
Normal file
|
@ -0,0 +1,364 @@
|
|||
import pytest
|
||||
from collections import OrderedDict
|
||||
from calculate.templates.format.ldap_format import LDAPFormat
|
||||
|
||||
|
||||
@pytest.mark.ldap
|
||||
class TestParsingMethods:
|
||||
def test_if_logiclines_method_takes_text_with_lines_that_starts_whit_space_symbols__it_returns_joined_lines(self):
|
||||
with open('./tests/format/testfiles/ldap_logic_lines_test.txt', 'r') as input_file:
|
||||
input_text = input_file.read()
|
||||
|
||||
output_lines = ['First string of test file.',
|
||||
'Second string of test file.',
|
||||
'Third string of test file.',
|
||||
'Fourth string of test file.']
|
||||
|
||||
ldap_object = LDAPFormat('')
|
||||
input_lines = ldap_object._get_list_of_logic_lines(input_text)
|
||||
assert input_lines == output_lines
|
||||
|
||||
def test_if_input_doc_contains_some_type_sections_with_plain_directives__object_dictionary_contains_correct_dictionary_with_directives_values_and_comments(self):
|
||||
document_text = '''
|
||||
include /etc/openldap/schema/samba.schema
|
||||
include /etc/openldap/schema/mail.schema
|
||||
|
||||
loglevel 0
|
||||
allow bind_v2
|
||||
modulepath /usr/lib/openldap/openldap
|
||||
|
||||
database bdb
|
||||
|
||||
checkpoint 1024 5
|
||||
suffix "dc=calculate"
|
||||
cachesize 10000
|
||||
sizelimit unlimited
|
||||
directory /var/lib/openldap-data
|
||||
rootdn "cn=ldaproot,dc=calculate"'''
|
||||
|
||||
global_section = OrderedDict({'#': [],
|
||||
('', 'include', '/etc/openldap/schema/samba.schema'):
|
||||
[''],
|
||||
('', 'include', '/etc/openldap/schema/mail.schema'):
|
||||
[''],
|
||||
('', 'loglevel'): ['0'],
|
||||
('', 'allow'): ['bind_v2'],
|
||||
('', 'modulepath'):
|
||||
['/usr/lib/openldap/openldap']})
|
||||
|
||||
database_section = OrderedDict({('', 'checkpoint'): ['1024 5'],
|
||||
('', 'suffix'): ['"dc=calculate"'],
|
||||
('', 'cachesize'): ['10000'],
|
||||
('', 'sizelimit'): ['unlimited'],
|
||||
('', 'directory'):
|
||||
['/var/lib/openldap-data'],
|
||||
('', 'rootdn'):
|
||||
['"cn=ldaproot,dc=calculate"']})
|
||||
|
||||
result = OrderedDict({('', 'global'): global_section,
|
||||
('', 'database', 'bdb'): database_section})
|
||||
|
||||
ldap_object = LDAPFormat(document_text)
|
||||
assert ldap_object._document_dictionary == result
|
||||
|
||||
def test_if_input_document_contains_access_to_directive__the_object_s_dictionary_contains_correct_dictionary_with_list_of_access_to_parameters_and_comments(self):
|
||||
document_text = '''
|
||||
database bdb
|
||||
# Comment1
|
||||
# Comment2
|
||||
access to attrs=userPassword
|
||||
by dn="cn=ldapadmin,dc=calculate" write
|
||||
by dn="ou=Samba,ou=Services,dc=calculate" write
|
||||
by self read
|
||||
by * auth
|
||||
|
||||
# Comment3
|
||||
access to * by * read
|
||||
'''
|
||||
access_1 = OrderedDict({'#': ['# Comment1', '# Comment2'],
|
||||
('', '*'):
|
||||
['auth'],
|
||||
('', 'self'):
|
||||
['read'],
|
||||
('', 'dn="ou=Samba,ou=Services,dc=calculate"'):
|
||||
['write'],
|
||||
('', 'dn="cn=ldapadmin,dc=calculate"'):
|
||||
['write']})
|
||||
|
||||
access_2 = OrderedDict({'#': ['# Comment3'],
|
||||
('', '*'): ['read']})
|
||||
|
||||
database_section = OrderedDict({('', 'access to', 'attrs=userPassword'):
|
||||
access_1,
|
||||
('', 'access to', '*'):
|
||||
access_2})
|
||||
|
||||
result = OrderedDict({('', 'global'): OrderedDict(),
|
||||
('', 'database', 'bdb'): database_section})
|
||||
|
||||
ldap_object = LDAPFormat(document_text)
|
||||
assert ldap_object._document_dictionary == result
|
||||
|
||||
def test_if_input_document_contains_syncrepl_directive__the_object_s_dictionary_contains_correct_dictionary_with_list_of_syncrepl_parameters_and_comments(self):
|
||||
document_text = '''
|
||||
# Comment1
|
||||
# Comment2
|
||||
syncrepl rid=123
|
||||
provider=ldap://provider.example.com:389
|
||||
type=refreshOnly
|
||||
interval=01:00:00:00
|
||||
searchbase="dc=example,dc=com"
|
||||
'''
|
||||
|
||||
syncrepl_dictionary = OrderedDict({('', 'provider'):
|
||||
['ldap://provider.example.com:389'],
|
||||
('', 'type'):
|
||||
['refreshOnly'],
|
||||
('', 'interval'):
|
||||
['01:00:00:00'],
|
||||
('', 'searchbase'):
|
||||
['"dc=example,dc=com"']})
|
||||
|
||||
global_section = OrderedDict({'#': ['# Comment1', '# Comment2'],
|
||||
('', 'syncrepl', 'rid=123'):
|
||||
syncrepl_dictionary})
|
||||
|
||||
result = OrderedDict({('', 'global'): global_section})
|
||||
|
||||
ldap_object = LDAPFormat(document_text)
|
||||
assert ldap_object._document_dictionary == result
|
||||
|
||||
def test_if_input_document_contains_index_directives__the_object_s_dictionary_contains_correct_dictionary_with_index_elements_and_comments(self):
|
||||
document_text = '''
|
||||
# Comment for global
|
||||
|
||||
index objectClass eq
|
||||
# Comment for index
|
||||
index cn pres,sub,eq
|
||||
index sn pres,sub,eq
|
||||
index uid pres,sub,eq
|
||||
|
||||
database bdb
|
||||
# Comment1
|
||||
# Comment2
|
||||
index uidNumber eq
|
||||
index gidNumber eq
|
||||
index default sub'''
|
||||
|
||||
global_section = OrderedDict({'#': ['# Comment for global'],
|
||||
('', 'index', 'objectClass'): ['eq'],
|
||||
('', 'index', 'cn'):
|
||||
['# Comment for index', 'pres,sub,eq'],
|
||||
('', 'index', 'sn'): ['pres,sub,eq'],
|
||||
('', 'index', 'uid'): ['pres,sub,eq']})
|
||||
|
||||
database_section = OrderedDict({('', 'index', 'uidNumber'):
|
||||
['# Comment1', '# Comment2', 'eq'],
|
||||
('', 'index', 'gidNumber'): ['eq'],
|
||||
('', 'index', 'default'): ['sub']})
|
||||
|
||||
result = OrderedDict({('', 'global'): global_section,
|
||||
('', 'database', 'bdb'): database_section})
|
||||
|
||||
ldap_object = LDAPFormat(document_text)
|
||||
assert ldap_object._document_dictionary == result
|
||||
|
||||
def test_if_input_document_contains_comments_to_type_sections__the_object_s_dictionary_collect_them(self):
|
||||
document_text = '''
|
||||
# Comment1
|
||||
loglevel 0
|
||||
allow bind_v2
|
||||
modulepath /usr/lib/openldap/openldap
|
||||
|
||||
# Comment2
|
||||
database bdb
|
||||
# Comment3
|
||||
checkpoint 1024 5
|
||||
suffix "dc=calculate"
|
||||
cachesize 10000'''
|
||||
|
||||
global_section = OrderedDict({'#': ['# Comment1'],
|
||||
('', 'loglevel'): ['0'],
|
||||
('', 'allow'): ['bind_v2'],
|
||||
('', 'modulepath'):
|
||||
['/usr/lib/openldap/openldap']})
|
||||
|
||||
database_section = OrderedDict({'#': ['# Comment2'],
|
||||
('', 'checkpoint'):
|
||||
['# Comment3',
|
||||
'1024 5'],
|
||||
('', 'suffix'): ['"dc=calculate"'],
|
||||
('', 'cachesize'): ['10000']})
|
||||
|
||||
result = OrderedDict({('', 'global'): global_section,
|
||||
('', 'database', 'bdb'): database_section})
|
||||
|
||||
ldap_object = LDAPFormat(document_text)
|
||||
assert ldap_object._document_dictionary == result
|
||||
|
||||
def test_if_input_doc_contains_some_type_sections_with_plain_directives_and_action_marks__object_dictionary_contains_correct_dictionary_with_directives_values_and_comments(self):
|
||||
document_text = '''
|
||||
!include /etc/openldap/schema/samba.schema
|
||||
-include /etc/openldap/schema/mail.schema
|
||||
|
||||
-backend hdb
|
||||
modulepath /usr/lib/openldap/openldap
|
||||
|
||||
!database bdb
|
||||
|
||||
checkpoint 1024 5
|
||||
!directory /var/lib/openldap-data
|
||||
!rootdn
|
||||
-allow
|
||||
|
||||
# Comment1
|
||||
!index uidNumber eq
|
||||
-index gidNumber eq
|
||||
|
||||
# Comment for index
|
||||
!index cn
|
||||
!index sn
|
||||
|
||||
'''
|
||||
|
||||
global_section = OrderedDict({'#': [],
|
||||
('!', 'include', '/etc/openldap/schema/samba.schema'):
|
||||
[''],
|
||||
('-', 'include', '/etc/openldap/schema/mail.schema'):
|
||||
['']})
|
||||
|
||||
backend_section = OrderedDict({('', 'modulepath'):
|
||||
['/usr/lib/openldap/openldap']})
|
||||
|
||||
database_section = OrderedDict({('', 'checkpoint'): ['1024 5'],
|
||||
('!', 'directory'):
|
||||
['/var/lib/openldap-data'],
|
||||
('!', 'rootdn'): [],
|
||||
('!', 'index', 'uidNumber'):
|
||||
['# Comment1', 'eq'],
|
||||
('-', 'index', 'gidNumber'): ['eq'],
|
||||
('!', 'index', 'cn'):
|
||||
['# Comment for index'],
|
||||
('!', 'index', 'sn'):
|
||||
[]})
|
||||
|
||||
result = OrderedDict({('', 'global'): global_section,
|
||||
('-', 'backend', 'hdb'): backend_section,
|
||||
('!', 'database', 'bdb'): database_section})
|
||||
|
||||
ldap_object = LDAPFormat(document_text)
|
||||
assert ldap_object._document_dictionary == result
|
||||
|
||||
def test_if_template_text_contains_some_access_to_constuctions_with_same_what_value_and_without_action_marks_for_whole_constructions__they_join_in_one_access_to_construction(self):
|
||||
document_text = '''
|
||||
# Unix
|
||||
access to attrs=sambaLMPassword,sambaNTPassword
|
||||
by dn="ou=Unix,ou=Services,dc=calculate" write
|
||||
|
||||
# Newval
|
||||
access to attrs=sambaLMPassword,sambaNTPassword
|
||||
by dn="cn=newval, dc=calculate" read
|
||||
|
||||
# Mail
|
||||
access to attrs=sambaLMPassword,sambaNTPassword
|
||||
by dn="ou=Mail,ou=Services,dc=calculate" read
|
||||
|
||||
# Jabber
|
||||
access to attrs=sambaLMPassword,sambaNTPassword
|
||||
by dn="ou=Jabber,ou=Services,dc=calculate" read
|
||||
'''
|
||||
|
||||
access = OrderedDict({('', 'dn="ou=Unix,ou=Services,dc=calculate"'):
|
||||
['write'],
|
||||
('', 'dn="cn=newval, dc=calculate"'):
|
||||
['read'],
|
||||
('', 'dn="ou=Mail,ou=Services,dc=calculate"'):
|
||||
['read'],
|
||||
('', 'dn="ou=Jabber,ou=Services,dc=calculate"'):
|
||||
['read']})
|
||||
|
||||
global_section = OrderedDict({('', 'access to',
|
||||
'attrs=sambaLMPassword,sambaNTPassword'):
|
||||
access})
|
||||
|
||||
result = OrderedDict({('', 'global'): global_section})
|
||||
|
||||
ldap_object = LDAPFormat(document_text, ignore_comments=True)
|
||||
assert ldap_object._document_dictionary == result
|
||||
|
||||
def test_if_input_document_contains_syncrepl_and_access_to_constructions_with_action_marks__object_dictionary_contains_correct_dictionary_with_action_marks(self):
|
||||
document_text = '''
|
||||
# Comment
|
||||
!syncrepl rid=123
|
||||
provider=ldap://provider.example.com:389
|
||||
type=refreshOnly
|
||||
interval=01:00:00:00
|
||||
searchbase="dc=example,dc=com"
|
||||
|
||||
# Comment1
|
||||
!syncrepl rid=001
|
||||
|
||||
database bdb
|
||||
# Comment2
|
||||
!access to attrs=userPassword
|
||||
by dn="cn=ldapadmin,dc=calculate" write
|
||||
by !dn="ou=Samba,ou=Services,dc=calculate" write
|
||||
by self read
|
||||
by * auth
|
||||
|
||||
# Comment3
|
||||
!access to dn.base="cn=proxyuser,dc=calculate"
|
||||
'''
|
||||
|
||||
access_1 = OrderedDict({'#': ['# Comment2'],
|
||||
('', '*'):
|
||||
['auth'],
|
||||
('', 'self'):
|
||||
['read'],
|
||||
('!', 'dn="ou=Samba,ou=Services,dc=calculate"'):
|
||||
['write'],
|
||||
('', 'dn="cn=ldapadmin,dc=calculate"'):
|
||||
['write']})
|
||||
|
||||
syncrepl_dictionary = OrderedDict({('', 'provider'):
|
||||
['ldap://provider.example.com:389'],
|
||||
('', 'type'):
|
||||
['refreshOnly'],
|
||||
('', 'interval'):
|
||||
['01:00:00:00'],
|
||||
('', 'searchbase'):
|
||||
['"dc=example,dc=com"']})
|
||||
|
||||
global_section = OrderedDict({'#': ['# Comment'],
|
||||
('!', 'syncrepl', 'rid=123'):
|
||||
syncrepl_dictionary,
|
||||
('!', 'syncrepl', 'rid=001'):
|
||||
OrderedDict({'#': ['# Comment1']})})
|
||||
|
||||
database_section = OrderedDict({('!', 'access to', 'attrs=userPassword'):
|
||||
access_1,
|
||||
('!', 'access to', 'dn.base="cn=proxyuser,dc=calculate"'):
|
||||
OrderedDict({'#': ['# Comment3']})})
|
||||
|
||||
result = OrderedDict({('', 'global'): global_section,
|
||||
('', 'database', 'bdb'): database_section})
|
||||
|
||||
ldap_object = LDAPFormat(document_text)
|
||||
assert ldap_object._document_dictionary == result
|
||||
|
||||
def test_joining_documents_1(self):
|
||||
with open('./tests/format/testfiles/ldap_original.conf', 'r') as original_file:
|
||||
original_text = original_file.read()
|
||||
ldap_original_object = LDAPFormat(original_text)
|
||||
|
||||
with open('./tests/format/testfiles/ldap_template.conf', 'r') as template_file:
|
||||
template_text = template_file.read()
|
||||
ldap_template_object = LDAPFormat(template_text,
|
||||
ignore_comments=True)
|
||||
|
||||
ldap_original_object.join_template(ldap_template_object)
|
||||
|
||||
with open('./tests/format/testfiles/ldap_result.conf', 'r') as result_file:
|
||||
result_text = result_file.read()
|
||||
|
||||
assert ldap_original_object.get_document_text() == result_text
|
146
tests/format/test_openrc.py
Normal file
146
tests/format/test_openrc.py
Normal file
|
@ -0,0 +1,146 @@
|
|||
import pytest
|
||||
from collections import OrderedDict
|
||||
from calculate.templates.format.openrc_format import OpenRCFormat
|
||||
|
||||
|
||||
@pytest.mark.openrc
|
||||
class TestParsingMethods:
|
||||
def test_if_input_document_contains_just_few_parameter_lines__the_initialised_object_contains_correct_dictionary(self):
|
||||
document_text = '''
|
||||
rc_interactive="NO"
|
||||
INSTANCE="openldap${SVCNAME#slapd}"
|
||||
OPTS_CONF="-f /etc/${INSTANCE}/slapd.conf"
|
||||
OPTS="${OPTS_CONF} -h 'ldaps:// ldap:// ldapi://%2fvar%2frun%2fopenldap%2fslapd.sock'"
|
||||
'''
|
||||
|
||||
result = OrderedDict({('', 'rc_interactive'): ['"NO"'],
|
||||
('', 'instance'): ['"openldap${SVCNAME#slapd}"'],
|
||||
('', 'opts_conf'): ['"-f /etc/${INSTANCE}/slapd.conf"'],
|
||||
('', 'opts'): ['"${OPTS_CONF} -h \'ldaps:// ldap:// ldapi://%2fvar%2frun%2fopenldap%2fslapd.sock\'"']})
|
||||
|
||||
openrc_object = OpenRCFormat(document_text)
|
||||
assert openrc_object._document_dictionary == result
|
||||
|
||||
def test_if_input_document_contains_few_parameter_lines_and_some_empty_lines__the_initialized_object_contains_correct_dictionary(self):
|
||||
document_text = '''
|
||||
rc_interactive="NO"
|
||||
|
||||
|
||||
INSTANCE="openldap${SVCNAME#slapd}"
|
||||
|
||||
OPTS_CONF="-f /etc/${INSTANCE}/slapd.conf"
|
||||
|
||||
|
||||
OPTS="${OPTS_CONF} -h 'ldaps:// ldap:// ldapi://%2fvar%2frun%2fopenldap%2fslapd.sock'"
|
||||
'''
|
||||
|
||||
result = OrderedDict({('', 'rc_interactive'): ['"NO"'],
|
||||
('', 'instance'): ['"openldap${SVCNAME#slapd}"'],
|
||||
('', 'opts_conf'): ['"-f /etc/${INSTANCE}/slapd.conf"'],
|
||||
('', 'opts'): ['"${OPTS_CONF} -h \'ldaps:// ldap:// ldapi://%2fvar%2frun%2fopenldap%2fslapd.sock\'"']})
|
||||
|
||||
openrc_object = OpenRCFormat(document_text)
|
||||
assert openrc_object._document_dictionary == result
|
||||
|
||||
def test_if_input_document_contains_parameters_with_action_marks__the_key_tuples_of_object_s_dictionary_have_it_as_its_first_element(self):
|
||||
document_text = '''
|
||||
!rc_interactive="NO"
|
||||
-INSTANCE="openldap${SVCNAME#slapd}"
|
||||
OPTS_CONF="-f /etc/${INSTANCE}/slapd.conf"
|
||||
!OPTS="${OPTS_CONF} -h 'ldaps:// ldap:// ldapi://%2fvar%2frun%2fopenldap%2fslapd.sock'"
|
||||
'''
|
||||
|
||||
result = OrderedDict({('!', 'rc_interactive'): ['"NO"'],
|
||||
('-', 'instance'): ['"openldap${SVCNAME#slapd}"'],
|
||||
('', 'opts_conf'): ['"-f /etc/${INSTANCE}/slapd.conf"'],
|
||||
('!', 'opts'): ['"${OPTS_CONF} -h \'ldaps:// ldap:// ldapi://%2fvar%2frun%2fopenldap%2fslapd.sock\'"']})
|
||||
|
||||
openrc_object = OpenRCFormat(document_text)
|
||||
assert openrc_object._document_dictionary == result
|
||||
|
||||
def test_if_parameter_in_input_document_has_some_comments__the_comments_will_be_collected_in_the_list_of_parameter_value(self):
|
||||
document_text = '''
|
||||
# If you have multiple slapd instances per #376699, this will provide a default config
|
||||
rc_interactive="NO"
|
||||
INSTANCE="openldap${SVCNAME#slapd}"
|
||||
|
||||
# Comment1
|
||||
# Comment2
|
||||
|
||||
OPTS_CONF="-f /etc/${INSTANCE}/slapd.conf"
|
||||
|
||||
|
||||
OPTS="${OPTS_CONF} -h 'ldaps:// ldap:// ldapi://%2fvar%2frun%2fopenldap%2fslapd.sock'"
|
||||
'''
|
||||
|
||||
result = OrderedDict({('', 'rc_interactive'):
|
||||
['# If you have multiple slapd instances per #376699, this will provide a default config', '"NO"'],
|
||||
('', 'instance'):
|
||||
['"openldap${SVCNAME#slapd}"'],
|
||||
('', 'opts_conf'):
|
||||
['# Comment1',
|
||||
'# Comment2',
|
||||
'"-f /etc/${INSTANCE}/slapd.conf"'],
|
||||
('', 'opts'):
|
||||
['"${OPTS_CONF} -h \'ldaps:// ldap:// ldapi://%2fvar%2frun%2fopenldap%2fslapd.sock\'"']})
|
||||
|
||||
openrc_object = OpenRCFormat(document_text)
|
||||
assert openrc_object._document_dictionary == result
|
||||
|
||||
def test_if_the_IgnoreComments_flag_is_set__the_parser_ignores_all_comments(self):
|
||||
document_text = '''
|
||||
# If you have multiple slapd instances per #376699, this will provide a default config
|
||||
rc_interactive="NO"
|
||||
INSTANCE="openldap${SVCNAME#slapd}"
|
||||
|
||||
# Comment1
|
||||
# Comment2
|
||||
|
||||
OPTS_CONF="-f /etc/${INSTANCE}/slapd.conf"
|
||||
|
||||
|
||||
OPTS="${OPTS_CONF} -h 'ldaps:// ldap:// ldapi://%2fvar%2frun%2fopenldap%2fslapd.sock'"
|
||||
'''
|
||||
|
||||
result = OrderedDict({('', 'rc_interactive'):
|
||||
['"NO"'],
|
||||
('', 'instance'):
|
||||
['"openldap${SVCNAME#slapd}"'],
|
||||
('', 'opts_conf'):
|
||||
['"-f /etc/${INSTANCE}/slapd.conf"'],
|
||||
('', 'opts'):
|
||||
['"${OPTS_CONF} -h \'ldaps:// ldap:// ldapi://%2fvar%2frun%2fopenldap%2fslapd.sock\'"']})
|
||||
|
||||
openrc_object = OpenRCFormat(document_text, ignore_comments=True)
|
||||
assert openrc_object._document_dictionary == result
|
||||
|
||||
def test_if_input_document_contains_parameters_to_delete_without_assign_symbol_and_any_values__the_document_object_contains_dictionary_with_item_to_delete(self):
|
||||
document_text = '''
|
||||
!rc_interactive="NO"
|
||||
!INSTANCE=
|
||||
!OPTS_CONF
|
||||
'''
|
||||
|
||||
result = OrderedDict({('!', 'rc_interactive'): ['"NO"'],
|
||||
('!', 'instance'): [],
|
||||
('!', 'opts_conf'): []})
|
||||
|
||||
openrc_object = OpenRCFormat(document_text)
|
||||
assert openrc_object._document_dictionary == result
|
||||
|
||||
def test_joining_documents_1(self):
|
||||
with open('./tests/format/testfiles/openrc_original', 'r') as original_file:
|
||||
original_text = original_file.read()
|
||||
openrc_original_object = OpenRCFormat(original_text)
|
||||
|
||||
with open('./tests/format/testfiles/openrc_template', 'r') as template_file:
|
||||
template_text = template_file.read()
|
||||
openrc_template_object = OpenRCFormat(template_text,
|
||||
ignore_comments=True)
|
||||
|
||||
openrc_original_object.join_template(openrc_template_object)
|
||||
|
||||
with open('./tests/format/testfiles/openrc_result', 'r') as result_file:
|
||||
result_text = result_file.read()
|
||||
|
||||
assert openrc_original_object.get_document_text() == result_text
|
80
tests/format/test_patch.py
Normal file
80
tests/format/test_patch.py
Normal file
|
@ -0,0 +1,80 @@
|
|||
import pytest
|
||||
from collections import OrderedDict
|
||||
from calculate.templates.format.patch_format import PatchFormat
|
||||
|
||||
|
||||
@pytest.mark.patch
|
||||
class TestParsingMethods:
|
||||
def test_if_input_patch_document_contains_only_regular_expressions_without_any_regex_flags__it_correctly_patches_input_document(self):
|
||||
input_text = '''
|
||||
First line
|
||||
Another meaningless line.
|
||||
TEXT&DATA
|
||||
ParameterName = Value
|
||||
Another line of endless sadness.
|
||||
'''
|
||||
|
||||
output_text = '''
|
||||
First line
|
||||
Another meaningless line.
|
||||
TEXT_CONFIG
|
||||
ParameterName = NewValue
|
||||
Another line of endless sadness.
|
||||
'''
|
||||
|
||||
patch_text = '''<reg>TEXT&DATA</reg>
|
||||
<text>TEXT_CONFIG</text>
|
||||
<reg>ParameterName\\s*=\\s*[a-zA-Z_][a-zA-Z_0-9]*</reg>
|
||||
<text>ParameterName = NewValue</text>
|
||||
'''
|
||||
|
||||
patch = PatchFormat(patch_text)
|
||||
patch_result = patch.execute_format(input_text)
|
||||
|
||||
assert patch_result == output_text
|
||||
|
||||
def test_if_input_patch_document_contains_regular_expressions_with_global_regex_flags_and_flags_as_attributes__it_correctly_patches_input_document_using_regex_flags(self):
|
||||
input_text = '''
|
||||
#============================== Share Definitions =============================
|
||||
[homes]
|
||||
comment = Home Directories
|
||||
browseable = no
|
||||
writable = yes
|
||||
|
||||
# Un-comment the following and create the netlogon directory for Domain Logons
|
||||
[netlogon]
|
||||
comment = Network Logon Service
|
||||
path = /var/lib/samba/netlogon
|
||||
guest ok = yes
|
||||
writable = no
|
||||
share modes = no
|
||||
'''
|
||||
|
||||
output_text = '''
|
||||
#============================== Share Definitions =============================
|
||||
[homes]
|
||||
comment = Home Directories
|
||||
browseable = who knows
|
||||
writable = yes
|
||||
|
||||
# Un-comment the following and create the netlogon directory for Domain Logons
|
||||
[netlogon]
|
||||
comment = Network Logon Service
|
||||
path = /var/lib/samba/netlogon
|
||||
writable = yes
|
||||
share modes = no
|
||||
'''
|
||||
|
||||
patch_text = '''
|
||||
<reg dotall="1" multiline="0">(\\[netlogon\\].*)writable\\s*=\\s*[a-zA-Z_][a-zA-Z_0-9]*</reg>
|
||||
<text>\\1writable = yes</text>
|
||||
<reg multiline="false" dotall="True">(\\[homes\\].*)browseable\\s*=\\s*[a-zA-Z_][a-zA-Z_0-9]*</reg>
|
||||
<text>\\1browseable = who knows</text>
|
||||
<reg>(\\[netlogon\\].*)^\\s*guest ok\\s*=\\s*[a-zA-Z_][a-zA-Z_0-9]*\\n</reg>
|
||||
<text>\\1</text>
|
||||
'''
|
||||
|
||||
patch = PatchFormat(patch_text, multiline=True, dotall=True)
|
||||
patch_result = patch.execute_format(input_text)
|
||||
|
||||
assert patch_result == output_text
|
124
tests/format/test_postfix.py
Normal file
124
tests/format/test_postfix.py
Normal file
|
@ -0,0 +1,124 @@
|
|||
import pytest
|
||||
from collections import OrderedDict
|
||||
from calculate.templates.format.postfix_format import PostfixFormat
|
||||
|
||||
|
||||
@pytest.mark.postfix
|
||||
class TestParsingMethods:
|
||||
def test_if_input_document_contains_just_few_parameter_lines__the_initialised_object_contains_correct_dictionary(self):
|
||||
document_text = '''parameter_name = /home/divanov/Home
|
||||
other_parameter = yes'''
|
||||
|
||||
result = OrderedDict({('', 'parameter_name'): ['/home/divanov/Home'],
|
||||
('', 'other_parameter'): ['yes']})
|
||||
|
||||
postfix_object = PostfixFormat(document_text)
|
||||
assert postfix_object._document_dictionary == result
|
||||
|
||||
def test_if_input_document_contains_few_parameter_lines_and_some_empty_lines__the_initialized_object_contains_correct_dictionary(self):
|
||||
document_text = '''parameter_name = /home/divanov/Home
|
||||
|
||||
|
||||
other_parameter = yes
|
||||
|
||||
another_parameter = none
|
||||
'''
|
||||
|
||||
result = OrderedDict({('', 'parameter_name'): ['/home/divanov/Home'],
|
||||
('', 'other_parameter'): ['yes'],
|
||||
('', 'another_parameter'): ['none']})
|
||||
|
||||
postfix_object = PostfixFormat(document_text)
|
||||
assert postfix_object._document_dictionary == result
|
||||
|
||||
def test_if_input_document_contains_parameters_with_action_marks__the_key_tuples_of_object_s_dictionary_have_it_as_its_first_element(self):
|
||||
document_text = '''-parameter_name = /home/divanov/Home
|
||||
other_parameter = yes
|
||||
!another_parameter = 1'''
|
||||
|
||||
result = OrderedDict({('-', 'parameter_name'): ['/home/divanov/Home'],
|
||||
('', 'other_parameter'): ['yes'],
|
||||
('!', 'another_parameter'): ['1']})
|
||||
|
||||
postfix_object = PostfixFormat(document_text)
|
||||
assert postfix_object._document_dictionary == result
|
||||
|
||||
def test_if_parameter_in_input_document_has_some_comments__the_comments_will_be_collected_in_the_list_of_parameter_value(self):
|
||||
document_text = '''# Comment1
|
||||
parameter_name = /home/divanov/Home
|
||||
|
||||
# Comment2
|
||||
# Comment3
|
||||
other_parameter = yes
|
||||
smtp_tls_note_starttls_offer = yes
|
||||
tls_random_source = dev:/dev/urandom
|
||||
|
||||
# Очень важный комментарий, который нужно удалить.
|
||||
!another_parameter = 1'''
|
||||
|
||||
result = OrderedDict({('', 'parameter_name'):
|
||||
['# Comment1', '/home/divanov/Home'],
|
||||
('', 'other_parameter'):
|
||||
['# Comment2', '# Comment3', 'yes'],
|
||||
('', 'smtp_tls_note_starttls_offer'): ['yes'],
|
||||
('', 'tls_random_source'): ['dev:/dev/urandom'],
|
||||
('!', 'another_parameter'):
|
||||
['# Очень важный комментарий, который нужно удалить.','1']})
|
||||
|
||||
postfix_object = PostfixFormat(document_text)
|
||||
assert postfix_object._document_dictionary == result
|
||||
|
||||
def test_if_the_IgnoreComments_flag_is_set__the_parser_ignores_all_comments(self):
|
||||
document_text = '''# Comment1
|
||||
parameter_name = /home/divanov/Home
|
||||
|
||||
# Comment2
|
||||
# Comment3
|
||||
other_parameter = yes
|
||||
smtp_tls_note_starttls_offer = yes
|
||||
tls_random_source = dev:/dev/urandom
|
||||
|
||||
# Очень важный комментарий, который нужно удалить.
|
||||
!another_parameter = 1'''
|
||||
|
||||
result = OrderedDict({('', 'parameter_name'):
|
||||
['/home/divanov/Home'],
|
||||
('', 'other_parameter'):
|
||||
['yes'],
|
||||
('', 'smtp_tls_note_starttls_offer'): ['yes'],
|
||||
('', 'tls_random_source'): ['dev:/dev/urandom'],
|
||||
('!', 'another_parameter'):
|
||||
['1']})
|
||||
|
||||
postfix_object = PostfixFormat(document_text, ignore_comments=True)
|
||||
assert postfix_object._document_dictionary == result
|
||||
|
||||
def test_if_input_document_contains_parameters_to_delete_without_assign_symbol_and_any_values__the_document_object_contains_dictionary_with_item_to_delete(self):
|
||||
document_text = '''!parameter_name = /home/divanov/Home
|
||||
!other_parameter =
|
||||
-ignored_line
|
||||
!another_parameter'''
|
||||
|
||||
result = OrderedDict({('!', 'parameter_name'): ['/home/divanov/Home'],
|
||||
('!', 'other_parameter'): [],
|
||||
('!', 'another_parameter'): []})
|
||||
|
||||
postfix_object = PostfixFormat(document_text)
|
||||
assert postfix_object._document_dictionary == result
|
||||
|
||||
def test_joining_documents_1(self):
|
||||
with open('./tests/format/testfiles/postfix_original', 'r') as original_file:
|
||||
original_text = original_file.read()
|
||||
postfix_original_object = PostfixFormat(original_text)
|
||||
|
||||
with open('./tests/format/testfiles/postfix_template', 'r') as template_file:
|
||||
template_text = template_file.read()
|
||||
postfix_template_object = PostfixFormat(template_text,
|
||||
ignore_comments=True)
|
||||
|
||||
postfix_original_object.join_template(postfix_template_object)
|
||||
|
||||
with open('./tests/format/testfiles/postfix_result', 'r') as result_file:
|
||||
result_text = result_file.read()
|
||||
|
||||
assert postfix_original_object.get_document_text() == result_text
|
130
tests/format/test_procmail.py
Normal file
130
tests/format/test_procmail.py
Normal file
|
@ -0,0 +1,130 @@
|
|||
import pytest
|
||||
from collections import OrderedDict
|
||||
from calculate.templates.format.procmail_format import ProcmailFormat
|
||||
|
||||
|
||||
@pytest.mark.procmail
|
||||
class TestParsingMethods:
|
||||
def test_if_input_document_contains_just_few_parameter_lines__the_initialised_object_contains_correct_dictionary(self):
|
||||
document_text = '''
|
||||
net.ipv4.ip_forward = 0
|
||||
parameter_name = /home/divanov/Home
|
||||
other_parameter = yes'''
|
||||
|
||||
result = OrderedDict({('', 'net.ipv4.ip_forward'): ['0'],
|
||||
('', 'parameter_name'): ['/home/divanov/Home'],
|
||||
('', 'other_parameter'): ['yes']})
|
||||
|
||||
procmail_object = ProcmailFormat(document_text)
|
||||
assert procmail_object._document_dictionary == result
|
||||
|
||||
def test_if_input_document_contains_few_parameter_lines_and_some_empty_lines__the_initialized_object_contains_correct_dictionary(self):
|
||||
document_text = '''
|
||||
net.ipv4.ip_forward = 0
|
||||
|
||||
|
||||
parameter_name = /home/divanov/Home
|
||||
|
||||
other_parameter = yes'''
|
||||
|
||||
result = OrderedDict({('', 'net.ipv4.ip_forward'): ['0'],
|
||||
('', 'parameter_name'): ['/home/divanov/Home'],
|
||||
('', 'other_parameter'): ['yes']})
|
||||
|
||||
procmail_object = ProcmailFormat(document_text)
|
||||
assert procmail_object._document_dictionary == result
|
||||
|
||||
def test_if_input_document_contains_parameters_with_action_marks__the_key_tuples_of_object_s_dictionary_have_it_as_its_first_element(self):
|
||||
document_text = '''
|
||||
!net.ipv4.ip_forward = 0
|
||||
|
||||
|
||||
local_recipient_maps = ldap:/etc/postfix/ldap-recipient.cf, ldap:/etc/postfix/ldap-recipient-gr.cf, ldap:/etc/postfix/ldap-recipient-repl.cf
|
||||
parameter_name = /home/divanov/Home
|
||||
|
||||
-other_parameter = yes'''
|
||||
|
||||
result = OrderedDict({('!', 'net.ipv4.ip_forward'): ['0'],
|
||||
('', 'local_recipient_maps'):
|
||||
['ldap:/etc/postfix/ldap-recipient.cf, ldap:/etc/postfix/ldap-recipient-gr.cf, ldap:/etc/postfix/ldap-recipient-repl.cf'],
|
||||
('', 'parameter_name'): ['/home/divanov/Home'],
|
||||
('-', 'other_parameter'): ['yes']})
|
||||
|
||||
procmail_object = ProcmailFormat(document_text)
|
||||
assert procmail_object._document_dictionary == result
|
||||
|
||||
def test_if_parameter_in_input_document_has_some_comments__the_comments_will_be_collected_in_the_list_of_parameter_value(self):
|
||||
document_text = '''
|
||||
# Comment1
|
||||
net.ipv4.ip_forward = 0
|
||||
|
||||
|
||||
# Comment2
|
||||
# Comment3
|
||||
parameter_name = /home/divanov/Home
|
||||
|
||||
# Comment
|
||||
!other_parameter = yes'''
|
||||
|
||||
result = OrderedDict({('', 'net.ipv4.ip_forward'): ['# Comment1', '0'],
|
||||
('', 'parameter_name'): ['# Comment2',
|
||||
'# Comment3',
|
||||
'/home/divanov/Home'],
|
||||
('!', 'other_parameter'): ['# Comment',
|
||||
'yes']})
|
||||
|
||||
procmail_object = ProcmailFormat(document_text)
|
||||
assert procmail_object._document_dictionary == result
|
||||
|
||||
def test_if_the_IgnoreComments_flag_is_set__the_parser_ignores_all_comments(self):
|
||||
document_text = '''
|
||||
# Comment1
|
||||
net.ipv4.ip_forward = 0
|
||||
|
||||
|
||||
# Comment2
|
||||
# Comment3
|
||||
parameter_name = /home/divanov/Home
|
||||
|
||||
# Comment
|
||||
!other_parameter = yes'''
|
||||
|
||||
result = OrderedDict({('', 'net.ipv4.ip_forward'): ['0'],
|
||||
('', 'parameter_name'): ['/home/divanov/Home'],
|
||||
('!', 'other_parameter'): ['yes']})
|
||||
|
||||
procmail_object = ProcmailFormat(document_text, ignore_comments=True)
|
||||
assert procmail_object._document_dictionary == result
|
||||
|
||||
def test_if_input_document_contains_parameters_to_delete_without_assign_symbol_and_any_values__the_document_object_contains_dictionary_with_item_to_delete(self):
|
||||
document_text = '''
|
||||
!net.ipv4.ip_forward = 0
|
||||
|
||||
|
||||
!parameter_name =
|
||||
|
||||
!other_parameter'''
|
||||
|
||||
result = OrderedDict({('!', 'net.ipv4.ip_forward'): ['0'],
|
||||
('!', 'parameter_name'): [],
|
||||
('!', 'other_parameter'): []})
|
||||
|
||||
procmail_object = ProcmailFormat(document_text)
|
||||
assert procmail_object._document_dictionary == result
|
||||
|
||||
def test_joining_documents_1(self):
|
||||
with open('./tests/format/testfiles/procmail_original', 'r') as original_file:
|
||||
original_text = original_file.read()
|
||||
procmail_original_object = ProcmailFormat(original_text)
|
||||
|
||||
with open('./tests/format/testfiles/procmail_template', 'r') as template_file:
|
||||
template_text = template_file.read()
|
||||
procmail_template_object = ProcmailFormat(template_text,
|
||||
ignore_comments=True)
|
||||
|
||||
procmail_original_object.join_template(procmail_template_object)
|
||||
|
||||
with open('./tests/format/testfiles/procmail_result', 'r') as result_file:
|
||||
result_text = result_file.read()
|
||||
|
||||
assert procmail_original_object.get_document_text() == result_text
|
237
tests/format/test_proftpd.py
Normal file
237
tests/format/test_proftpd.py
Normal file
|
@ -0,0 +1,237 @@
|
|||
import pytest
|
||||
from collections import OrderedDict
|
||||
from calculate.templates.format.proftpd_format import ProFTPDFormat
|
||||
|
||||
|
||||
@pytest.mark.proftpd
|
||||
class TestParsingMethods:
|
||||
def test_if_input_document_contains_just_few_parameter_lines__the_initialised_object_contains_correct_dictionary(self):
|
||||
document_text = '''
|
||||
ServerName "ProFTPD Anonymous Server"
|
||||
ServerType standalone
|
||||
DefaultServer on
|
||||
MaxInstances 30
|
||||
'''
|
||||
|
||||
result = OrderedDict({('', '', 'ServerName'):
|
||||
['"ProFTPD Anonymous Server"'],
|
||||
('', '', 'ServerType'):
|
||||
['standalone'],
|
||||
('', '', 'DefaultServer'):
|
||||
['on'],
|
||||
('', '', 'MaxInstances'):
|
||||
['30']})
|
||||
|
||||
proftpd_object = ProFTPDFormat(document_text)
|
||||
assert proftpd_object._document_dictionary == result
|
||||
|
||||
def test_if_input_document_contains_some_block_of_parameters__the_initialised_object_contains_correct_dictionary(self):
|
||||
document_text = '''
|
||||
ServerName "ProFTPD Anonymous Server"
|
||||
ServerType standalone
|
||||
|
||||
<Anonymous ~ftp>
|
||||
<Limit LOGIN>
|
||||
DisplayLogin welcome.msg
|
||||
DisplayFirstChdir .message
|
||||
</Limit>
|
||||
|
||||
User bob
|
||||
Group bobs
|
||||
UserAlias anonymous ftp
|
||||
|
||||
<Limit WRITE>
|
||||
Order allow,deny
|
||||
Allow from 10.0.0
|
||||
Deny from all
|
||||
</Limit>
|
||||
</Anonymous>
|
||||
'''
|
||||
|
||||
result = OrderedDict({('', '', 'ServerName'):
|
||||
['"ProFTPD Anonymous Server"'],
|
||||
('', '', 'ServerType'):
|
||||
['standalone'],
|
||||
('', (('Anonymous', '~ftp'), ('Limit', 'LOGIN')),
|
||||
'DisplayLogin'): ['welcome.msg'],
|
||||
('', (('Anonymous', '~ftp'), ('Limit', 'LOGIN')),
|
||||
'DisplayFirstChdir'): ['.message'],
|
||||
('', (('Anonymous', '~ftp'), ),
|
||||
'User'): ['bob'],
|
||||
('', (('Anonymous', '~ftp'), ),
|
||||
'Group'): ['bobs'],
|
||||
('', (('Anonymous', '~ftp'), ),
|
||||
'UserAlias', 'anonymous', 'ftp'): [''],
|
||||
('', (('Anonymous', '~ftp'), ('Limit', 'WRITE')),
|
||||
'Order'): ['allow,deny'],
|
||||
('', (('Anonymous', '~ftp'), ('Limit', 'WRITE')),
|
||||
'Allow from', '10.0.0'): [''],
|
||||
('', (('Anonymous', '~ftp'), ('Limit', 'WRITE')),
|
||||
'Deny from', 'all'): ['']})
|
||||
|
||||
proftpd_object = ProFTPDFormat(document_text)
|
||||
assert proftpd_object._document_dictionary == result
|
||||
|
||||
def test_if_input_document_contains_blocks_and_parameters_with_action_marks__the_key_tuples_of_parameters_s_have_it_as_its_first_element_inherited(self):
|
||||
document_text = '''
|
||||
!ServerName "ProFTPD Anonymous Server"
|
||||
|
||||
<!Anonymous ~ftp>
|
||||
<-Limit LOGIN>
|
||||
DisplayLogin welcome.msg
|
||||
DisplayFirstChdir .message
|
||||
</Limit>
|
||||
</Anonymous>
|
||||
|
||||
<!Limit WRITE>
|
||||
Order allow,deny
|
||||
Allow from 10.0.0
|
||||
-Deny from all
|
||||
</Limit>
|
||||
'''
|
||||
|
||||
result = OrderedDict({('!', '', 'ServerName'):
|
||||
['"ProFTPD Anonymous Server"'],
|
||||
('!', (('Anonymous', '~ftp'),
|
||||
('Limit', 'LOGIN')),
|
||||
'DisplayLogin'): ['welcome.msg'],
|
||||
('!', (('Anonymous', '~ftp'),
|
||||
('Limit', 'LOGIN')),
|
||||
'DisplayFirstChdir'): ['.message'],
|
||||
('!', (('Limit', 'WRITE'), ),
|
||||
'Order'): ['allow,deny'],
|
||||
('!', (('Limit', 'WRITE'), ),
|
||||
'Allow from', '10.0.0'): [''],
|
||||
('!', (('Limit', 'WRITE'), ),
|
||||
'Deny from', 'all'): ['']})
|
||||
|
||||
proftpd_object = ProFTPDFormat(document_text)
|
||||
assert proftpd_object._document_dictionary == result
|
||||
|
||||
def test_if_parameters_and_blocks_in_input_document_has_some_comments__the_comments_will_be_collected_in_the_list_of_parameter_value_or_with_special_key_in_block_dictionary(self):
|
||||
document_text = '''
|
||||
# Comment 1
|
||||
!ServerName "ProFTPD Anonymous Server"
|
||||
|
||||
# Comment 2
|
||||
# Comment 3
|
||||
<!Anonymous ~ftp>
|
||||
<-Limit LOGIN>
|
||||
DisplayLogin welcome.msg
|
||||
DisplayFirstChdir .message
|
||||
</Limit>
|
||||
</Anonymous>
|
||||
|
||||
<!Limit WRITE>
|
||||
Order allow,deny
|
||||
Allow from 10.0.0
|
||||
# Comment 4
|
||||
-Deny from all
|
||||
</Limit>
|
||||
'''
|
||||
|
||||
result = OrderedDict({('!', '', 'ServerName'):
|
||||
['# Comment 1', '"ProFTPD Anonymous Server"'],
|
||||
('!', (('Anonymous', '~ftp'),
|
||||
('Limit', 'LOGIN')),
|
||||
'DisplayLogin'): ['# Comment 2',
|
||||
'# Comment 3',
|
||||
'welcome.msg'],
|
||||
('!', (('Anonymous', '~ftp'),
|
||||
('Limit', 'LOGIN')),
|
||||
'DisplayFirstChdir'): ['.message'],
|
||||
('!', (('Limit', 'WRITE'), ),
|
||||
'Order'): ['allow,deny'],
|
||||
('!', (('Limit', 'WRITE'), ),
|
||||
'Allow from', '10.0.0'): [''],
|
||||
('!', (('Limit', 'WRITE'), ),
|
||||
'Deny from', 'all'): ['# Comment 4', '']})
|
||||
|
||||
proftpd_object = ProFTPDFormat(document_text)
|
||||
assert proftpd_object._document_dictionary == result
|
||||
|
||||
def test_if_the_ignoreComments_flag_is_set__the_parser_ignores_all_comments(self):
|
||||
document_text = '''
|
||||
# Comment 1
|
||||
ServerName "ProFTPD Anonymous Server"
|
||||
|
||||
# Comment 2
|
||||
# Comment 3
|
||||
<!Anonymous ~ftp>
|
||||
<-Limit LOGIN>
|
||||
DisplayLogin welcome.msg
|
||||
DisplayFirstChdir .message
|
||||
</Limit>
|
||||
</Anonymous>
|
||||
|
||||
<Limit WRITE>
|
||||
Order allow,deny
|
||||
Allow from 10.0.0
|
||||
# Comment 4
|
||||
!Deny from all
|
||||
</Limit>
|
||||
'''
|
||||
|
||||
result = OrderedDict({('', '', 'ServerName'):
|
||||
['"ProFTPD Anonymous Server"'],
|
||||
('!', (('Anonymous', '~ftp'),
|
||||
('Limit', 'LOGIN')),
|
||||
'DisplayLogin'): ['welcome.msg'],
|
||||
('!', (('Anonymous', '~ftp'),
|
||||
('Limit', 'LOGIN')),
|
||||
'DisplayFirstChdir'): ['.message'],
|
||||
('', (('Limit', 'WRITE'), ),
|
||||
'Order'): ['allow,deny'],
|
||||
('', (('Limit', 'WRITE'), ),
|
||||
'Allow from', '10.0.0'): [''],
|
||||
('!', (('Limit', 'WRITE'), ),
|
||||
'Deny from', 'all'): ['']})
|
||||
|
||||
proftpd_object = ProFTPDFormat(document_text, ignore_comments=True)
|
||||
assert proftpd_object._document_dictionary == result
|
||||
|
||||
def test_if_input_document_contains_parameters_to_delete_without_any_values_the_document_object_contains_dictionary_with_this_items_to_delete(self):
|
||||
document_text = '''
|
||||
!SQLLog PASS
|
||||
|
||||
<Anonymous ~ftp>
|
||||
<Limit LOGIN>
|
||||
!DisplayLogin
|
||||
DisplayFirstChdir .message
|
||||
</Limit>
|
||||
</Anonymous>
|
||||
|
||||
<Limit WRITE>
|
||||
!Allow from 10.0.0
|
||||
</Limit>
|
||||
'''
|
||||
|
||||
result = OrderedDict({('!', '', 'SQLLog', 'PASS'): [''],
|
||||
('!', (('Anonymous', '~ftp'),
|
||||
('Limit', 'LOGIN')),
|
||||
'DisplayLogin'): [''],
|
||||
('', (('Anonymous', '~ftp'),
|
||||
('Limit', 'LOGIN')),
|
||||
'DisplayFirstChdir'): ['.message'],
|
||||
('!', (('Limit', 'WRITE'), ),
|
||||
'Allow from', '10.0.0'): ['']})
|
||||
|
||||
proftpd_object = ProFTPDFormat(document_text, ignore_comments=True)
|
||||
assert proftpd_object._document_dictionary == result
|
||||
|
||||
def test_joining_documents_1(self):
|
||||
with open('./tests/format/testfiles/proftpd_original.conf', 'r') as original_file:
|
||||
original_text = original_file.read()
|
||||
proftpd_original_object = ProFTPDFormat(original_text)
|
||||
|
||||
with open('./tests/format/testfiles/proftpd_template.conf', 'r') as template_file:
|
||||
template_text = template_file.read()
|
||||
proftpd_template_object = ProFTPDFormat(template_text,
|
||||
ignore_comments=True)
|
||||
|
||||
proftpd_original_object.join_template(proftpd_template_object)
|
||||
|
||||
with open('./tests/format/testfiles/proftpd_result.conf', 'r') as result_file:
|
||||
result_text = result_file.read()
|
||||
|
||||
assert proftpd_original_object.get_document_text() == result_text
|
229
tests/format/test_samba.py
Normal file
229
tests/format/test_samba.py
Normal file
|
@ -0,0 +1,229 @@
|
|||
import pytest
|
||||
from collections import OrderedDict
|
||||
from calculate.templates.format.samba_format import SambaFormat
|
||||
|
||||
|
||||
@pytest.mark.samba
|
||||
class TestParsingMethods:
|
||||
def test_if_input_document_contains_just_few_parameter_lines__the_initialised_object_contains_correct_dictionary(self):
|
||||
document_text = '''[section name]
|
||||
parameter name = /home/divanov/Home
|
||||
other parameter = yes'''
|
||||
|
||||
param_line_1 = OrderedDict({('', 'parameter name'): ['/home/divanov/Home']})
|
||||
param_line_2 = OrderedDict({('', 'other parameter'): ['yes']})
|
||||
|
||||
result = OrderedDict({('', 'section name'): OrderedDict(**param_line_1,
|
||||
**param_line_2)})
|
||||
|
||||
samba_object = SambaFormat(document_text)
|
||||
assert samba_object._document_dictionary == result
|
||||
|
||||
def test_if_input_document_contains_few_parameter_lines_and_some_empty_lines__the_initialized_object_contains_correct_dictionary(self):
|
||||
document_text = '''
|
||||
[section name1]
|
||||
parameter name = /home/divanov/Home
|
||||
|
||||
other parameter = yes
|
||||
|
||||
|
||||
second parameter = 1
|
||||
|
||||
[section name2]
|
||||
|
||||
other parameter = yes
|
||||
|
||||
'''
|
||||
|
||||
section_1_content = OrderedDict({('', 'parameter name'): ['/home/divanov/Home'],
|
||||
('', 'other parameter'): ['yes'],
|
||||
('', 'second parameter'): ['1']})
|
||||
|
||||
section_2_content = OrderedDict({('', 'other parameter'): ['yes']})
|
||||
|
||||
result = OrderedDict({('', 'section name1'): section_1_content,
|
||||
('', 'section name2'): section_2_content})
|
||||
|
||||
samba_object = SambaFormat(document_text)
|
||||
assert samba_object._document_dictionary == result
|
||||
|
||||
def test_if_input_document_contains_sections_with_similar_names_but_different_parameters__the_parameters_merged_in_one_section(self):
|
||||
document_text = '''[section name]
|
||||
parameter name = /home/divanov/Home
|
||||
other parameter = yes
|
||||
|
||||
[section name]
|
||||
another parameter = 1'''
|
||||
|
||||
section_content = OrderedDict({('', 'parameter name'): ['/home/divanov/Home'],
|
||||
('', 'other parameter'): ['yes'],
|
||||
('', 'another parameter'): ['1']})
|
||||
result = OrderedDict({('', 'section name'): section_content})
|
||||
|
||||
samba_object = SambaFormat(document_text)
|
||||
assert samba_object._document_dictionary == result
|
||||
|
||||
def test_if_input_document_contains_sections_with_parameters_with_action_marks__the_key_tuples_of_object_s_dictionary_have_it_as_its_first_element(self):
|
||||
document_text = '''[section name]
|
||||
-parameter name = /home/divanov/Home
|
||||
other parameter = yes
|
||||
!another parameter = 1'''
|
||||
|
||||
section_content = OrderedDict({('-', 'parameter name'): ['/home/divanov/Home'],
|
||||
('', 'other parameter'): ['yes'],
|
||||
('!', 'another parameter'): ['1']})
|
||||
result = OrderedDict({('', 'section name'): section_content})
|
||||
|
||||
samba_object = SambaFormat(document_text)
|
||||
assert samba_object._document_dictionary == result
|
||||
|
||||
def test_if_parameter_in_input_document_has_some_comments__the_comments_will_be_collected_in_the_list_of_parameter_value(self):
|
||||
document_text = '''# Comment1
|
||||
[section name1]
|
||||
parameter name = /home/divanov/Home
|
||||
|
||||
# Comment2
|
||||
# Comment3
|
||||
other parameter = yes
|
||||
|
||||
[section name2]
|
||||
#Comment
|
||||
!another parameter = 1'''
|
||||
|
||||
section = OrderedDict({'#': ['# Comment1'],
|
||||
('', 'parameter name'): ['/home/divanov/Home'],
|
||||
('', 'other parameter'): ['# Comment2',
|
||||
'# Comment3',
|
||||
'yes']})
|
||||
|
||||
result = OrderedDict({('', 'section name1'): section,
|
||||
('', 'section name2'): OrderedDict({
|
||||
('!', 'another parameter'):
|
||||
['#Comment', '1']})})
|
||||
|
||||
samba_object = SambaFormat(document_text)
|
||||
assert samba_object._document_dictionary == result
|
||||
|
||||
def test_if_the_IgnoreComments_flag_is_set__the_parser_ignores_all_comments(self):
|
||||
document_text = '''# Comment1
|
||||
[section name1]
|
||||
parameter name = /home/divanov/Home
|
||||
|
||||
# Comment2
|
||||
# Comment3
|
||||
other parameter = yes
|
||||
|
||||
[section name2]
|
||||
#Comment
|
||||
!another parameter = 1'''
|
||||
|
||||
section_1 = OrderedDict({('', 'parameter name'): ['/home/divanov/Home'],
|
||||
('', 'other parameter'): ['yes']})
|
||||
|
||||
section_2 = OrderedDict({('!', 'another parameter'): ['1']})
|
||||
|
||||
result = OrderedDict({('', 'section name1'): section_1,
|
||||
('', 'section name2'): section_2})
|
||||
|
||||
samba_object = SambaFormat(document_text, ignore_comments=True)
|
||||
assert samba_object._document_dictionary == result
|
||||
|
||||
def test_if_input_document_contains_parameters_to_delete_without_assign_symbol_and_any_values_and_sections_to_delete__the_document_object_contains_dictionary_with_item_to_delete(self):
|
||||
document_text = '''
|
||||
[section name1]
|
||||
!parameter name = /home/divanov/Home
|
||||
!other parameter =
|
||||
!another parameter
|
||||
[!section name2]
|
||||
parameter = no
|
||||
[-section name3]
|
||||
parameter = no'''
|
||||
|
||||
section_1 = OrderedDict({('!', 'parameter name'): ['/home/divanov/Home'],
|
||||
('!', 'other parameter'): [],
|
||||
('!', 'another parameter'): []})
|
||||
section_2 = OrderedDict({('', 'parameter'): ['no']})
|
||||
|
||||
result = OrderedDict({('', 'section name1'): section_1,
|
||||
('!', 'section name2'): section_2,
|
||||
('-', 'section name3'): section_2})
|
||||
|
||||
samba_object = SambaFormat(document_text)
|
||||
assert samba_object._document_dictionary == result
|
||||
|
||||
def test_if_joinBefore_flag_is_set__the_document_object_contains_dictionary_with_sections_added_in_the_top_of_it(self):
|
||||
original_text = '''# Comment1
|
||||
[section name2]
|
||||
parameter name = /home/divanov/Home
|
||||
|
||||
# Comment2
|
||||
# Comment3
|
||||
other parameter = yes
|
||||
|
||||
[section name3]
|
||||
#Comment
|
||||
another parameter = 1'''
|
||||
|
||||
template_text = '''
|
||||
[section name1]
|
||||
parameter name = /homeless/poorness
|
||||
|
||||
one more parameter = oh no
|
||||
|
||||
[section name3]
|
||||
# Comment
|
||||
unspoken parameter = 1'''
|
||||
|
||||
result = OrderedDict({('', 'section name1'):
|
||||
OrderedDict({('', 'parameter name'):
|
||||
['/homeless/poorness'],
|
||||
('', 'one more parameter'):
|
||||
['oh no']}),
|
||||
('', 'section name2'):
|
||||
OrderedDict({'#': ['# Comment1'],
|
||||
('', 'parameter name'):
|
||||
['/home/divanov/Home'],
|
||||
('', 'other parameter'):
|
||||
['# Comment2', '# Comment3', 'yes']}),
|
||||
('', 'section name3'):
|
||||
OrderedDict({('', 'another parameter'):
|
||||
['#Comment', '1'],
|
||||
('', 'unspoken parameter'):
|
||||
['1']})})
|
||||
|
||||
samba_original_object = SambaFormat(original_text, join_before=True)
|
||||
samba_template_object = SambaFormat(template_text, ignore_comments=True)
|
||||
samba_original_object.join_template(samba_template_object)
|
||||
|
||||
assert samba_original_object._document_dictionary == result
|
||||
|
||||
def test_if_input_document_parameters_contains_upper_case_symbols__it_becomes_lower_case(self):
|
||||
document_text = '''[SECTION]
|
||||
parameter NAME = /home/divanov/Home
|
||||
Other Parameter = yes'''
|
||||
|
||||
param_line_1 = OrderedDict({('', 'parameter name'): ['/home/divanov/Home']})
|
||||
param_line_2 = OrderedDict({('', 'other parameter'): ['yes']})
|
||||
|
||||
result = OrderedDict({('', 'section'): OrderedDict(**param_line_1,
|
||||
**param_line_2)})
|
||||
|
||||
samba_object = SambaFormat(document_text)
|
||||
assert samba_object._document_dictionary == result
|
||||
|
||||
def test_joining_documents_1(self):
|
||||
with open('./tests/format/testfiles/samba_original', 'r') as original_file:
|
||||
original_text = original_file.read()
|
||||
samba_original_object = SambaFormat(original_text)
|
||||
|
||||
with open('./tests/format/testfiles/samba_template', 'r') as template_file:
|
||||
template_text = template_file.read()
|
||||
samba_template_object = SambaFormat(template_text,
|
||||
ignore_comments=True)
|
||||
|
||||
samba_original_object.join_template(samba_template_object)
|
||||
|
||||
with open('./tests/format/testfiles/samba_result', 'r') as result_file:
|
||||
result_text = result_file.read()
|
||||
|
||||
assert samba_original_object.get_document_text() == result_text
|
89
tests/format/test_xml_gconf.py
Normal file
89
tests/format/test_xml_gconf.py
Normal file
|
@ -0,0 +1,89 @@
|
|||
import pytest
|
||||
from collections import OrderedDict
|
||||
from calculate.templates.format.xml_gconf_format import XMLGConfFormat
|
||||
|
||||
|
||||
@pytest.mark.xml_gconf
|
||||
class TestParsingMethods:
|
||||
def test_if_input_document_is_simple_gconf_tree__the_format_object_contains_correct_dictionary(self):
|
||||
document_text = '''<?xml version="1.0" encoding="UTF-8"?>
|
||||
<gconf>
|
||||
<dir name="gnome">
|
||||
<dir name="ymsgr">
|
||||
<entry name="needs_terminal">
|
||||
<default type="string">
|
||||
<stringvalue>Something I can never have.</stringvalue>
|
||||
</default>
|
||||
<local_schema short_desc="Run the command in a terminal">
|
||||
<longdesc>True if the command used to handle this type of URL should be run in a terminal.</longdesc>
|
||||
</local_schema>
|
||||
</entry>
|
||||
<entry name="logo_icon_name" mtime="1342486180" type="string">
|
||||
<stringvalue>distributor</stringvalue>
|
||||
</entry>
|
||||
</dir>
|
||||
</dir>
|
||||
</gconf>
|
||||
'''
|
||||
|
||||
result = OrderedDict({('', 'gconf'):
|
||||
OrderedDict({('', 'dir', ('name', 'gnome')):
|
||||
OrderedDict({('', 'dir', ('name', 'ymsgr')):
|
||||
OrderedDict({('', 'entry', ('name', 'needs_terminal')):
|
||||
OrderedDict({('', 'default', ('type', 'string')):
|
||||
OrderedDict({('', 'stringvalue'): 'Something I can never have.'}),
|
||||
('', 'local_schema', ('short_desc', 'Run the command in a terminal')):
|
||||
OrderedDict({('', 'longdesc'): 'True if the command used to handle this type of URL should be run in a terminal.'})}),
|
||||
('', 'entry', ('name', 'logo_icon_name'), ('mtime', '1342486180'), ('type', 'string')):
|
||||
OrderedDict({('', 'stringvalue'): 'distributor'})})})})})
|
||||
|
||||
xml_gconf_object = XMLGConfFormat(document_text)
|
||||
assert xml_gconf_object._document_dictionary == result
|
||||
|
||||
def test_if_input_document_is_simple_gconf__the_format_object_contains_correct_dictionary(self):
|
||||
document_text = '''<?xml version="1.0" encoding="UTF-8"?>
|
||||
<gconf>
|
||||
<entry name="options" mtime="1298136657" type="list" ltype="string">
|
||||
<li type="string">
|
||||
<stringvalue>grp grp:lwin_toggle</stringvalue>
|
||||
</li>
|
||||
</entry>
|
||||
<entry name="layouts" mtime="1298136657" type="list" ltype="string">
|
||||
<li type="string">
|
||||
<stringvalue>us</stringvalue>
|
||||
</li>
|
||||
<li type="string">
|
||||
<stringvalue>ru</stringvalue>
|
||||
</li>
|
||||
</entry>
|
||||
<entry name="hinting" mtime="1298136657" type="list">
|
||||
<stringvalue>full</stringvalue>
|
||||
</entry>
|
||||
</gconf>
|
||||
'''
|
||||
|
||||
result = OrderedDict({('', 'gconf'):
|
||||
OrderedDict({('', 'entry', ('name', 'options'), ('mtime', '1298136657'), ('type', 'list'), ('ltype', 'string')): ['grp grp:lwin_toggle'],
|
||||
('', 'entry', ('name', 'layouts'), ('mtime', '1298136657'), ('type', 'list'), ('ltype', 'string')):
|
||||
['us', 'ru'],
|
||||
('', 'entry', ('name', 'hinting'), ('mtime', '1298136657'), ('type', 'list')):
|
||||
OrderedDict({('', 'stringvalue'): 'full'})})})
|
||||
|
||||
xml_gconf_object = XMLGConfFormat(document_text)
|
||||
assert xml_gconf_object._document_dictionary == result
|
||||
|
||||
def test_joining_documents_1(self):
|
||||
with open('./tests/format/testfiles/xml_gconf_original.xml', 'r') as original_file:
|
||||
original_text = original_file.read()
|
||||
xml_gconf_original_object = XMLGConfFormat(original_text)
|
||||
|
||||
with open('./tests/format/testfiles/xml_gconf_template.xml', 'r') as template_file:
|
||||
template_text = template_file.read()
|
||||
xml_gconf_template_object = XMLGConfFormat(template_text)
|
||||
|
||||
xml_gconf_original_object.join_template(xml_gconf_template_object)
|
||||
|
||||
with open('./tests/format/testfiles/xml_gconf_result.xml', 'r') as result_file:
|
||||
result_text = result_file.read()
|
||||
|
||||
assert xml_gconf_original_object.get_document_text() == result_text
|
52
tests/format/test_xml_xfce.py
Normal file
52
tests/format/test_xml_xfce.py
Normal file
|
@ -0,0 +1,52 @@
|
|||
import pytest
|
||||
from collections import OrderedDict
|
||||
from calculate.templates.format.xml_xfce_format import XMLXfceFormat
|
||||
|
||||
|
||||
@pytest.mark.xml_xfce
|
||||
class TestParsingMethods:
|
||||
def test_if_input_document_contains_just_few_parameter_lines__the_initialised_object_contains_correct_dictionary(self):
|
||||
document_text = '''<?xml version="1.0" encoding="UTF-8"?>
|
||||
<channel name="xsettings" version="1.0">
|
||||
<property name="Net" type="empty">
|
||||
<property name="ThemeName" type="string" value="Calculate"/>
|
||||
<property name="IconThemeName" type="string" value="Calculate"/>
|
||||
<property name="DoubleClickTime" type="int" value="400"/>
|
||||
</property>
|
||||
<property name="Xft" type="empty">
|
||||
<property name="Antialias" type="int" value="1"/>
|
||||
<property name="HintStyle" type="string" value="hintmedium"/>
|
||||
</property>
|
||||
</channel>
|
||||
'''
|
||||
|
||||
net_dict = OrderedDict({('', 'property', 'ThemeName', 'string'): "Calculate",
|
||||
('', 'property', 'IconThemeName', 'string'): "Calculate",
|
||||
('', 'property', 'DoubleClickTime', 'int'): '400'})
|
||||
|
||||
xft_dict = OrderedDict({('', 'property', 'Antialias', 'int'): "1",
|
||||
('', 'property', 'HintStyle', 'string'): 'hintmedium'})
|
||||
|
||||
channel_content = OrderedDict({('', 'property', 'Net', 'empty'): net_dict,
|
||||
('', 'property', 'Xft', 'empty'): xft_dict})
|
||||
|
||||
result = OrderedDict({('', 'channel', 'xsettings', '1.0'): channel_content})
|
||||
|
||||
xml_xfce_object = XMLXfceFormat(document_text)
|
||||
assert xml_xfce_object._document_dictionary == result
|
||||
|
||||
def test_joining_documents_1(self):
|
||||
with open('./tests/format/testfiles/xml_xfce_original.xml', 'r') as original_file:
|
||||
original_text = original_file.read()
|
||||
xml_xfce_original_object = XMLXfceFormat(original_text)
|
||||
|
||||
with open('./tests/format/testfiles/xml_xfce_template.xml', 'r') as template_file:
|
||||
template_text = template_file.read()
|
||||
xml_xfce_template_object = XMLXfceFormat(template_text)
|
||||
|
||||
xml_xfce_original_object.join_template(xml_xfce_template_object)
|
||||
|
||||
with open('./tests/format/testfiles/xml_xfce_result.xml', 'r') as result_file:
|
||||
result_text = result_file.read()
|
||||
|
||||
assert xml_xfce_original_object.get_document_text() == result_text
|
10
tests/format/testfiles/a/dir/file1.txt
Normal file
10
tests/format/testfiles/a/dir/file1.txt
Normal file
|
@ -0,0 +1,10 @@
|
|||
CONFIG_IRQ_WORK=y
|
||||
CONFIG_BUILDTIME_EXTABLE_SORT=y
|
||||
#
|
||||
# General setup
|
||||
#
|
||||
CONFIG_HAVE_KERNEL_GZIP=y
|
||||
CONFIG_HAVE_KERNEL_BZIP2=y
|
||||
CONFIG_HAVE_KERNEL_XZ=y
|
||||
CONFIG_HAVE_KERNEL_LZO=y
|
||||
CONFIG_HAVE_KERNEL_LZ4=y
|
10
tests/format/testfiles/a/dir/file2.txt
Normal file
10
tests/format/testfiles/a/dir/file2.txt
Normal file
|
@ -0,0 +1,10 @@
|
|||
Nine Inch Nails -- Hurt
|
||||
|
||||
I hurt myself today
|
||||
To see if I still feel
|
||||
I focused on the pain
|
||||
The only thing that real
|
||||
A needle tears a hole
|
||||
The old familiar sting
|
||||
Try to kill it all away
|
||||
But I remember everything.
|
10
tests/format/testfiles/a1/dir/file1.txt
Normal file
10
tests/format/testfiles/a1/dir/file1.txt
Normal file
|
@ -0,0 +1,10 @@
|
|||
CONFIG_IRQ_WORK=y
|
||||
CONFIG_BUILDTIME_EXTABLE_SORT=y
|
||||
#
|
||||
# General setup
|
||||
#
|
||||
CONFIG_HAVE_KERNEL_GZIP=y
|
||||
CONFIG_HAVE_KERNEL_BZIP2=y
|
||||
CONFIG_HAVE_KERNEL_XZ=y
|
||||
CONFIG_HAVE_KERNEL_LZO=y
|
||||
CONFIG_HAVE_KERNEL_LZ4=y
|
17
tests/format/testfiles/b/dir/file1.txt
Normal file
17
tests/format/testfiles/b/dir/file1.txt
Normal file
|
@ -0,0 +1,17 @@
|
|||
CONFIG_IRQ_WORK=y
|
||||
CONFIG_BUILDTIME_EXTABLE_SORT=y
|
||||
CONFIG_THREAD_INFO_IN_TASK=y
|
||||
#
|
||||
# General setup
|
||||
#
|
||||
CONFIG_INIT_ENV_ARG_LIMIT=16
|
||||
# CONFIG_COMPILE_TEST is not set
|
||||
CONFIG_LOCALVERSION=""
|
||||
# CONFIG_LOCALVERSION_AUTO is not set
|
||||
CONFIG_BUILD_SALT=""
|
||||
CONFIG_HAVE_KERNEL_GZIP=y
|
||||
CONFIG_HAVE_KERNEL_BZIP2=y
|
||||
CONFIG_HAVE_KERNEL_LZMA=y
|
||||
CONFIG_HAVE_KERNEL_XZ=y
|
||||
CONFIG_HAVE_KERNEL_LZO=y
|
||||
CONFIG_HAVE_KERNEL_LZ4=y
|
16
tests/format/testfiles/b/dir/file2.txt
Normal file
16
tests/format/testfiles/b/dir/file2.txt
Normal file
|
@ -0,0 +1,16 @@
|
|||
Nine Inch Nails -- Hurt
|
||||
|
||||
I hurt myself today
|
||||
To see if I still feel
|
||||
I focused on the pain
|
||||
The only thing that real
|
||||
A needle tears a hole
|
||||
The old familiar sting
|
||||
Try to kill it all away
|
||||
But I remember everything.
|
||||
|
||||
What have I become
|
||||
My sweetest friend
|
||||
Everyone I know
|
||||
Goes away
|
||||
In the end
|
11
tests/format/testfiles/b1/dir/file1.txt
Normal file
11
tests/format/testfiles/b1/dir/file1.txt
Normal file
|
@ -0,0 +1,11 @@
|
|||
CONFIG_IRQ_WORK=y
|
||||
CONFIG_BUILDTIME_EXTABLE_SORT=y
|
||||
#
|
||||
# General setup
|
||||
#
|
||||
CONFIG_BUILD_SALT=""
|
||||
CONFIG_HAVE_KERNEL_GZIP=y
|
||||
CONFIG_HAVE_KERNEL_BZIP2=y
|
||||
CONFIG_HAVE_KERNEL_XZ=y
|
||||
CONFIG_HAVE_KERNEL_LZO=y
|
||||
CONFIG_HAVE_KERNEL_LZ4=y
|
16
tests/format/testfiles/b1/dir/file2.txt
Normal file
16
tests/format/testfiles/b1/dir/file2.txt
Normal file
|
@ -0,0 +1,16 @@
|
|||
Nine Inch Nails -- Hurt
|
||||
|
||||
I hurt myself today
|
||||
To see if I still feel
|
||||
I focused on the pain
|
||||
The only thing that real
|
||||
A needle tears a hole
|
||||
The old familiar sting
|
||||
Try to kill it all away
|
||||
But I remember everything.
|
||||
|
||||
What have I become
|
||||
My sweetest friend
|
||||
Everyone I know
|
||||
Goes away
|
||||
In the end
|
108
tests/format/testfiles/bind_original.conf
Normal file
108
tests/format/testfiles/bind_original.conf
Normal file
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* Refer to the named.conf(5) and named(8) man pages, and the documentation
|
||||
* in /usr/share/doc/bind-* for more details.
|
||||
* Online versions of the documentation can be found here:
|
||||
* https://kb.isc.org/article/AA-01031
|
||||
*
|
||||
* If you are going to set up an authoritative server, make sure you
|
||||
* understand the hairy details of how DNS works. Even with simple mistakes,
|
||||
* you can break connectivity for affected parties, or cause huge amounts of
|
||||
* useless Internet traffic.
|
||||
*/
|
||||
|
||||
/*
|
||||
* You might put in here some ips which are allowed to use the cache or
|
||||
* recursive queries
|
||||
*/
|
||||
acl "trusted" {
|
||||
127.0.0.0/8;
|
||||
10.0.0.0/8;
|
||||
192.168.1.0/24;
|
||||
::1/128;
|
||||
};
|
||||
|
||||
acl "dns_servers" {
|
||||
127.0.0.1;
|
||||
10.0.1.3;
|
||||
10.1.0.3;
|
||||
10.2.0.3;
|
||||
10.4.0.3;
|
||||
};
|
||||
|
||||
options {
|
||||
directory "/var/bind";
|
||||
pid-file "/run/named/named.pid";
|
||||
disable-empty-zone "10.in-addr.arpa";
|
||||
|
||||
/* https://www.isc.org/solutions/dlv >=bind-9.7.x only */
|
||||
//bindkeys-file "/etc/bind/bind.keys";
|
||||
|
||||
listen-on-v6 { ::1; };
|
||||
listen-on { 10.0.0.0/8; 127.0.0.1; };
|
||||
|
||||
allow-query {
|
||||
/*
|
||||
* Accept queries from our "trusted" ACL. We will
|
||||
* allow anyone to query our master zones below.
|
||||
* This prevents us from becoming a free DNS server
|
||||
* to the masses.
|
||||
*/
|
||||
trusted;
|
||||
};
|
||||
|
||||
allow-query-cache {
|
||||
/* Use the cache for the "trusted" ACL. */
|
||||
trusted;
|
||||
};
|
||||
|
||||
allow-recursion {
|
||||
/* Only trusted addresses are allowed to use recursion. */
|
||||
trusted;
|
||||
};
|
||||
|
||||
recursion yes;
|
||||
|
||||
response-policy {
|
||||
zone "rpz.zone";
|
||||
};
|
||||
};
|
||||
|
||||
controls {
|
||||
// local host -- default key.
|
||||
inet 127.0.0.1 port 953 -allow { 127.0.0.1; "rndc-users"; }
|
||||
keys { "rndc-remote"; "rndc-key"; };
|
||||
inet 127.0.0.1 allow { localhost; };
|
||||
};
|
||||
|
||||
include "/etc/bind/rndc.key";
|
||||
|
||||
zone "." in {
|
||||
type hint;
|
||||
file "/var/bind/named.cache";
|
||||
};
|
||||
|
||||
zone "localhost" IN {
|
||||
type master;
|
||||
file "pri/localhost.zone";
|
||||
notify no;
|
||||
};
|
||||
|
||||
zone "rpz.zone" {
|
||||
type master;
|
||||
file "/var/bind/pri/rpz.zone";
|
||||
allow-query {trusted;};
|
||||
allow-update {none;};
|
||||
};
|
||||
|
||||
# DMZ
|
||||
zone "dmz.calculate.ru" IN {
|
||||
type slave;
|
||||
file "/var/bind/sec/dmz.calculate.ru.zone";
|
||||
masters { 10.1.0.3; };
|
||||
};
|
||||
|
||||
zone "1.10.in-addr.arpa" IN {
|
||||
type slave;
|
||||
file "/var/bind/sec/dmz.calculate.ru.rev.zone";
|
||||
masters { 10.1.0.3; };
|
||||
};
|
131
tests/format/testfiles/bind_result.conf
Normal file
131
tests/format/testfiles/bind_result.conf
Normal file
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* Refer to the named.conf(5) and named(8) man pages, and the documentation
|
||||
* in /usr/share/doc/bind-* for more details.
|
||||
* Online versions of the documentation can be found here:
|
||||
* https://kb.isc.org/article/AA-01031
|
||||
*
|
||||
* If you are going to set up an authoritative server, make sure you
|
||||
* understand the hairy details of how DNS works. Even with simple mistakes,
|
||||
* you can break connectivity for affected parties, or cause huge amounts of
|
||||
* useless Internet traffic.
|
||||
*/
|
||||
/*
|
||||
* You might put in here some ips which are allowed to use the cache or
|
||||
* recursive queries
|
||||
*/
|
||||
acl "trusted" {
|
||||
127.0.0.0/8;
|
||||
10.0.0.0/8;
|
||||
192.168.1.0/24;
|
||||
::1/128;
|
||||
};
|
||||
|
||||
acl "dns_servers" {
|
||||
127.0.0.1;
|
||||
10.0.1.3;
|
||||
10.1.0.3;
|
||||
10.2.0.3;
|
||||
10.3.0.3;
|
||||
};
|
||||
|
||||
options {
|
||||
directory "/var/bind";
|
||||
pid-file "/run/named/named.pid";
|
||||
disable-empty-zone "10.in-addr.arpa";
|
||||
|
||||
/* https://www.isc.org/solutions/dlv >=bind-9.7.x only */
|
||||
//bindkeys-file "/etc/bind/bind.keys";
|
||||
listen-on-v6 {
|
||||
::1;
|
||||
};
|
||||
|
||||
listen-on {
|
||||
10.0.0.0/8;
|
||||
127.0.0.1;
|
||||
};
|
||||
|
||||
allow-query {
|
||||
/*
|
||||
* Accept queries from our "trusted" ACL. We will
|
||||
* allow anyone to query our master zones below.
|
||||
* This prevents us from becoming a free DNS server
|
||||
* to the masses.
|
||||
*/
|
||||
trusted;
|
||||
};
|
||||
recursion yes;
|
||||
|
||||
response-policy {
|
||||
zone "bad.zone";
|
||||
mood "almost.blue";
|
||||
};
|
||||
};
|
||||
|
||||
controls {
|
||||
// local host -- default key.
|
||||
inet 127.0.0.1 port 953 allow { 127.0.0.1; "rndc-users"; } keys { "rndc-remote"; "rndc-key"; };
|
||||
|
||||
inet 127.0.0.1 allow { localhost; };
|
||||
};
|
||||
include "/etc/bind/rndc.key";
|
||||
|
||||
zone "." in {
|
||||
type hint;
|
||||
file "/var/bind/named.cache";
|
||||
};
|
||||
|
||||
zone "localhost" IN {
|
||||
type master;
|
||||
file "pri/localhost.zone";
|
||||
notify no;
|
||||
};
|
||||
|
||||
zone "rpz.zone" {
|
||||
type master;
|
||||
file "/var/bind/pri/rpz.zone";
|
||||
|
||||
allow-query {
|
||||
untrusted;
|
||||
};
|
||||
|
||||
allow-update {
|
||||
none;
|
||||
};
|
||||
};
|
||||
|
||||
# DMZ
|
||||
zone "dmz.calculate.ru" IN {
|
||||
type slave;
|
||||
file "/var/bind/sec/spb.calculate.ru.zone";
|
||||
|
||||
masters {
|
||||
10.1.0.3;
|
||||
};
|
||||
};
|
||||
|
||||
zone "1.10.in-addr.arpa" IN {
|
||||
type slave;
|
||||
file "/var/bind/sec/dmz.calculate.ru.rev.zone";
|
||||
|
||||
masters {
|
||||
10.1.0.3;
|
||||
};
|
||||
};
|
||||
|
||||
zone "msk.calculate.ru" IN {
|
||||
type slave;
|
||||
file "/var/bind/sec/msk.calculate.ru.zone";
|
||||
|
||||
masters {
|
||||
10.1.0.3;
|
||||
};
|
||||
};
|
||||
|
||||
zone "17.2.10.in-addr.arpa" IN {
|
||||
type slave;
|
||||
file "/var/bind/sec/phone.spb.calculate.ru.rev.zone";
|
||||
|
||||
masters {
|
||||
10.1.0.3;
|
||||
};
|
||||
};
|
58
tests/format/testfiles/bind_template.conf
Normal file
58
tests/format/testfiles/bind_template.conf
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Шаблок для проведения теста.
|
||||
* Этот комментарий не перенесется в оригинальный файл
|
||||
* после наложения шаблона.
|
||||
*/
|
||||
|
||||
// First appearing of this block with replace action mark.
|
||||
options {
|
||||
-response-policy {
|
||||
zone "bad.zone";
|
||||
};
|
||||
};
|
||||
|
||||
zone "msk.calculate.ru" IN {
|
||||
type slave;
|
||||
file "/var/bind/sec/msk.calculate.ru.zone";
|
||||
masters { 10.1.0.3; };
|
||||
};
|
||||
|
||||
zone "17.2.10.in-addr.arpa" IN {
|
||||
type slave;
|
||||
file "/var/bind/sec/phone.spb.calculate.ru.rev.zone";
|
||||
masters { 10.1.0.3; };
|
||||
};
|
||||
|
||||
# Second appearing of this block in purpose to add one meaningless line in.
|
||||
options {
|
||||
response-policy {
|
||||
mood "almost.blue";
|
||||
};
|
||||
};
|
||||
|
||||
/* Replace section */
|
||||
zone "dmz.calculate.ru" IN {
|
||||
type slave;
|
||||
file "/var/bind/sec/spb.calculate.ru.zone";
|
||||
masters { 10.1.0.3; };
|
||||
};
|
||||
|
||||
options {
|
||||
-allow-recursion {};
|
||||
};
|
||||
|
||||
zone "rpz.zone" {
|
||||
-allow-query {
|
||||
untrusted;
|
||||
};
|
||||
};
|
||||
|
||||
acl "dns_servers" {
|
||||
10.3.0.3;
|
||||
!10.4.0.3;
|
||||
};
|
||||
|
||||
options {
|
||||
!allow-query-cache {};
|
||||
};
|
||||
|
32
tests/format/testfiles/compiz_original
Normal file
32
tests/format/testfiles/compiz_original
Normal file
|
@ -0,0 +1,32 @@
|
|||
# Compiz test config.
|
||||
[Added Associations]
|
||||
application/illustrator=zzz-gimp.desktop
|
||||
application/pdf=evince.desktop;
|
||||
application/rtf=libreoffice-writer.desktop;
|
||||
application/vnd.oasis.opendocument.spreadsheet=calculate-calc.desktop;
|
||||
application/vnd.oasis.opendocument.text=libreoffice-calc.desktop;
|
||||
# The Comment have to be saved.
|
||||
image/bmp=gwenview.desktop;
|
||||
image/gif=gwenview.desktop;
|
||||
image/jpeg=gwenview.desktop;
|
||||
image/jpg=gwenview.desktop;
|
||||
image/png=gwenview.desktop;
|
||||
# The Comment to go away.
|
||||
audio/x-ms-wma=clementine.desktop;
|
||||
audio/x-wav=clementine.desktop;
|
||||
|
||||
[Non Realistic Section]
|
||||
audio/mp4=clementine.desktop;
|
||||
audio/mpeg=clementine.desktop;
|
||||
audio/x-flac=clementine.desktop;
|
||||
audio/x-ms-wma=clementine.desktop;
|
||||
audio/x-wav=clementine.desktop;
|
||||
|
||||
# It is very strange section -- may be It needs to be more strange.
|
||||
[Strange Section]
|
||||
video/mp4=smplayer.desktop;
|
||||
video/mpeg=smplayer.desktop;
|
||||
video/quicktime=smplayer.desktop;
|
||||
video/vnd.mpegurl=smplayer.desktop;
|
||||
video/x-m4v=smplayer.desktop;
|
||||
video/x-sgi-movie=smplayer.desktop;
|
34
tests/format/testfiles/compiz_result
Normal file
34
tests/format/testfiles/compiz_result
Normal file
|
@ -0,0 +1,34 @@
|
|||
# Compiz test config.
|
||||
[Added Associations]
|
||||
application/illustrator=zzz-gimp.desktop
|
||||
application/pdf=evince.desktop;
|
||||
application/rtf=libreoffice-writer.desktop;
|
||||
application/vnd.oasis.opendocument.spreadsheet=calculate-calc.desktop;
|
||||
application/vnd.oasis.opendocument.text=libreoffice-calc.desktop;
|
||||
# The Comment have to be saved.
|
||||
image/bmp=other.desktop;
|
||||
image/gif=another.desktop;
|
||||
image/jpeg=gwenview.desktop;
|
||||
image/jpg=gwenview.desktop;
|
||||
image/png=gwenview.desktop;
|
||||
image/x-portable-anymap=gwenview.desktop;
|
||||
image/x-portable-bitmap=gwenview.desktop;
|
||||
image/x-portable-graymap=gwenview.desktop;
|
||||
x-scheme-handler/http=firefox.desktop;
|
||||
x-scheme-handler/https=firefox.desktop;
|
||||
|
||||
# It is very strange section -- may be It needs to be more strange.
|
||||
[Strange Section]
|
||||
video/x-sgi-movie=smplayer.desktop;
|
||||
text/plain=kwrite.desktop;
|
||||
x-scheme-handler/mailto=org.kde.kmail2.desktop;
|
||||
video/ogg=smplayer.desktop;
|
||||
audio/mp4=clementine.desktop;
|
||||
|
||||
[Audio]
|
||||
audio/mp4=clementine.desktop;
|
||||
audio/mpeg=clementine.desktop;
|
||||
audio/x-flac=clementine.desktop;
|
||||
audio/x-ms-wma=clementine.desktop;
|
||||
audio/x-wav=clementine.desktop;
|
||||
|
39
tests/format/testfiles/compiz_template
Normal file
39
tests/format/testfiles/compiz_template
Normal file
|
@ -0,0 +1,39 @@
|
|||
|
||||
[Added Associations]
|
||||
image/x-portable-anymap=gwenview.desktop;
|
||||
image/x-portable-bitmap=gwenview.desktop;
|
||||
image/x-portable-graymap=gwenview.desktop;
|
||||
|
||||
[Added Associations]
|
||||
image/bmp=other.desktop;
|
||||
image/gif=another.desktop;
|
||||
|
||||
# Let's remove non realistic section.
|
||||
[!Non Realistic Section]
|
||||
|
||||
[Added Associations]
|
||||
x-scheme-handler/http=firefox.desktop;
|
||||
x-scheme-handler/https=firefox.desktop;
|
||||
|
||||
# New section for audio
|
||||
[Audio]
|
||||
audio/mp4=clementine.desktop;
|
||||
audio/mpeg=clementine.desktop;
|
||||
audio/x-flac=clementine.desktop;
|
||||
audio/x-ms-wma=clementine.desktop;
|
||||
audio/x-wav=clementine.desktop;
|
||||
|
||||
[Added Associations]
|
||||
!audio/mp4
|
||||
!audio/mpeg
|
||||
!audio/x-flac=
|
||||
!audio/x-ms-wma=
|
||||
!audio/x-wav
|
||||
|
||||
# To make strange section more strange.
|
||||
[-Strange Section]
|
||||
video/x-sgi-movie=smplayer.desktop;
|
||||
text/plain=kwrite.desktop;
|
||||
x-scheme-handler/mailto=org.kde.kmail2.desktop;
|
||||
video/ogg=smplayer.desktop;
|
||||
audio/mp4=clementine.desktop;
|
34
tests/format/testfiles/diff_1.patch
Normal file
34
tests/format/testfiles/diff_1.patch
Normal file
|
@ -0,0 +1,34 @@
|
|||
diff -urN a/dir/file1.txt b/dir/file1.txt
|
||||
--- a/dir/file1.txt 2020-01-29 14:38:21.216540100 +0300
|
||||
+++ b/dir/file1.txt 2020-01-29 14:40:19.200542500 +0300
|
||||
@@ -1,10 +1,17 @@
|
||||
CONFIG_IRQ_WORK=y
|
||||
CONFIG_BUILDTIME_EXTABLE_SORT=y
|
||||
+CONFIG_THREAD_INFO_IN_TASK=y
|
||||
#
|
||||
# General setup
|
||||
#
|
||||
+CONFIG_INIT_ENV_ARG_LIMIT=16
|
||||
+# CONFIG_COMPILE_TEST is not set
|
||||
+CONFIG_LOCALVERSION=""
|
||||
+# CONFIG_LOCALVERSION_AUTO is not set
|
||||
+CONFIG_BUILD_SALT=""
|
||||
CONFIG_HAVE_KERNEL_GZIP=y
|
||||
CONFIG_HAVE_KERNEL_BZIP2=y
|
||||
+CONFIG_HAVE_KERNEL_LZMA=y
|
||||
CONFIG_HAVE_KERNEL_XZ=y
|
||||
CONFIG_HAVE_KERNEL_LZO=y
|
||||
CONFIG_HAVE_KERNEL_LZ4=y
|
||||
diff -urN a/dir/file2.txt b/dir/file2.txt
|
||||
< |