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.
142 lines
5.4 KiB
142 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
|
|
|
|
@property
|
|
def 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
|