# 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