import attr import typing import jinja2 import emoji_data_python as edp from utils import print_user_link """ Template format: ||<| template_name |>|| //| locale_1 |// Text for locale 1 >>| Reply Keyboard: row 1, button 1;; Row 1, button 2 |<< >>| Row 2, button 1 :-: callback_data_for_inline_keyboard |<< //| locale_2 |// Text for locale 2 """ KeyboardMarkup = typing.List[typing.List[typing.Union[str, typing.Tuple[str, str]]]] @attr.s(auto_attribs=True) class TemplateProvider: # {template: {locale: jinja template}} templates: typing.Dict[str, typing.Dict[str, jinja2.Template]] = attr.Factory(dict) locales: typing.Tuple[str] = ('', 'both', 'en', 'ru') def get_template(self, template_name: str, locale: str) -> jinja2.Template: locales = [locale] + list(self.locales) template = self.templates[template_name] for locale in locales: if locale in template.keys(): return template[locale] return next(template.values()) def render_template(self, template_name: str, locale: str, **kwargs) -> str: return edp.replace_colons( self.get_template(template_name, locale) .render(print_user_link=print_user_link, **kwargs, **__builtins__)).strip() def add_template(self, template_string: str): template_name = template_string.split('||<|')[1].split('|>||')[0].strip() template: typing.Dict[str, jinja2.Template] = dict() for locale_string in template_string.split('//|')[1:]: locale_name: str = locale_string.split('|//')[0].strip() locale_text: str = '|//'.join(locale_string.split('|//')[1:]).strip() template[locale_name] = jinja2.Environment(loader=jinja2.FileSystemLoader('./')).from_string(locale_text) self.templates[template_name] = template def load_file(self, filename: str): file_content = open(filename).read() for template_string in file_content.split('||<|')[1:]: template_string = '||<|' + template_string self.add_template(edp.replace_colons(template_string)) @staticmethod def separate_text_and_keyboards(text: str) -> typing.Tuple[str, typing.Optional[KeyboardMarkup]]: pure_text = text.split('>>|')[0].strip() if len(text.split('>>|')) <= 1: return pure_text, None keyboard_rows = [row.split('|<<')[0].strip() for row in text.split('>>|')[1:]] keyboard: KeyboardMarkup = list() for row_raw in keyboard_rows: row = list() for btn in row_raw.split(';;'): if ':-:' in btn: row.append(tuple(btn.split(':-:'))) else: row.append(btn) keyboard.append(row) return pure_text, keyboard