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

141 lines
5.4 KiB

# vim: fileencoding=utf-8
#
from .base_format import BaseFormat
from collections import OrderedDict
from jinja2 import PackageLoader, Environment
from pyparsing import Literal, Regex, Word, nums, alphanums, Optional,\
ParseException
class ContentsFormat(BaseFormat):
FORMAT = 'contents'
_initialized = False
def __init__(self, document_text: str,
ignore_comments=False,
join_before=False,
template_parser=True):
processing_methods = [self._parse_dir_line,
self._parse_sym_line,
self._parse_obj_line]
super().__init__(processing_methods)
self._ignore_comments = ignore_comments
self._join_before = join_before
self._template_parser_flag = template_parser
if not self._initialized:
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)
@classmethod
def _initialize_parser(cls):
action_symbols = (Literal('!') | Literal('-'))
sym_keyword = Literal('sym')
dir_keyword = Literal('dir')
obj_keyword = Literal('obj')
symlink_arrow = Literal('->')
file_path = Regex(r'\S+')
time_value = Word(nums)
md5 = Word(alphanums)
cls.sym_line = (Optional(action_symbols, default='')('action')
+ sym_keyword('type') + file_path('name')
+ symlink_arrow.suppress() + file_path('target')
+ time_value('time'))
cls.dir_line = (Optional(action_symbols, default='')('action')
+ dir_keyword('type') + file_path('name'))
cls.obj_line = (Optional(action_symbols, default='')('action')
+ obj_keyword('type') + file_path('name')
+ md5('md5') + time_value('time'))
cls._initialized = True
def _parse_sym_line(self, line):
try:
parsing_result = self.sym_line.parseString(line)
self._match = True
if self._template_parser_flag:
output_name = (parsing_result.action, parsing_result.name)
output_value = (parsing_result.type,
parsing_result.target,
parsing_result.time)
self._item_to_add = OrderedDict({output_name: [output_value]})
else:
output_name = parsing_result.name
output_value = OrderedDict({'type': parsing_result.type,
'target': parsing_result.target,
'mtime': parsing_result.time})
self._item_to_add = OrderedDict({output_name: output_value})
self._ready_to_update = True
except ParseException:
return
def _parse_dir_line(self, line):
try:
parsing_result = self.dir_line.parseString(line)
self._match = True
if self._template_parser_flag:
output_name = (parsing_result.action, parsing_result.name)
output_value = (parsing_result.type,)
self._item_to_add = OrderedDict({output_name: [output_value]})
else:
output_name = parsing_result.name
output_value = OrderedDict({'type': parsing_result.type})
self._item_to_add = OrderedDict({output_name: output_value})
self._ready_to_update = True
except ParseException:
return
def _parse_obj_line(self, line):
try:
parsing_result = self.obj_line.parseString(line)
self._match = True
if self._template_parser_flag:
output_name = (parsing_result.action, parsing_result.name)
output_value = (parsing_result.type,
parsing_result.md5,
parsing_result.time)
self._item_to_add = OrderedDict({output_name: [output_value]})
else:
output_name = parsing_result.name
output_value = OrderedDict({'type': parsing_result.type,
'md5': parsing_result.md5,
'mtime': parsing_result.time})
self._item_to_add = OrderedDict({output_name: output_value})
self._ready_to_update = True
except ParseException:
return
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,
template_parser=self._template_parser_flag
)
return document_text