Random Coffee alternative - random meetings for Telegram chats https://t.me/ranteabot
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.

73 lines
2.7 KiB

2 years ago
import attr
import typing
import jinja2
import emoji_data_python as edp
"""
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(**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