|
|
|
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
|