mirror of
https://github.com/civsocit/olgram.git
synced 2023-07-22 01:29:12 +03:00
Chinese language support (suddenly!)
This commit is contained in:
parent
db54473e0f
commit
1a9646d607
@ -4,6 +4,11 @@ ENV PYTHONUNBUFFERED=1 \
|
||||
POETRY_VERSION=1.1.2 \
|
||||
POETRY_VIRTUALENVS_CREATE="false"
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y gettext build-essential && \
|
||||
apt-get clean && rm -rf /var/cache/apt/* && rm -rf /var/lib/apt/lists/* && rm -rf /tmp/*
|
||||
|
||||
|
||||
RUN pip install "poetry==$POETRY_VERSION"
|
||||
|
||||
WORKDIR /app
|
||||
@ -13,6 +18,8 @@ RUN poetry install --no-interaction --no-ansi --no-dev
|
||||
|
||||
COPY . /app
|
||||
|
||||
RUN msgfmt locales/zh/LC_MESSAGES/olgram.po -o locales/zh/LC_MESSAGES/olgram.mo --use-fuzzy
|
||||
|
||||
EXPOSE 80
|
||||
|
||||
ENTRYPOINT ["./docker-entrypoint.sh"]
|
||||
|
@ -3,7 +3,7 @@
|
||||
version: '3'
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:13.4
|
||||
image: postgres:14
|
||||
environment:
|
||||
- POSTGRES_USER=test_user
|
||||
- POSTGRES_PASSWORD=test_passwd
|
||||
|
12
locales/locale.py
Normal file
12
locales/locale.py
Normal file
@ -0,0 +1,12 @@
|
||||
import gettext
|
||||
from olgram.settings import BotSettings
|
||||
from os.path import dirname
|
||||
|
||||
locales_dir = dirname(__file__)
|
||||
|
||||
lang = BotSettings.language()
|
||||
if lang == "ru":
|
||||
_ = lambda x: x
|
||||
else:
|
||||
t = gettext.translation("olgram", localedir=locales_dir, languages=[lang])
|
||||
_ = t.gettext
|
564
locales/zh/LC_MESSAGES/olgram.po
Normal file
564
locales/zh/LC_MESSAGES/olgram.po
Normal file
@ -0,0 +1,564 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR ORGANIZATION
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"POT-Creation-Date: 2022-03-22 04:36+0300\n"
|
||||
"PO-Revision-Date: 2022-03-22 04:55+0300\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: pygettext.py 1.5\n"
|
||||
"X-Generator: Poedit 3.0\n"
|
||||
"Last-Translator: \n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
"Language: zh_CN\n"
|
||||
|
||||
#: olgram/commands/bot_actions.py:21
|
||||
msgid "Бот удалён"
|
||||
msgstr "移除机器人"
|
||||
|
||||
#: olgram/commands/bot_actions.py:37 olgram/commands/bot_actions.py:49
|
||||
msgid "Текст сброшен"
|
||||
msgstr "倾倒的文本"
|
||||
|
||||
#: olgram/commands/bot_actions.py:63
|
||||
msgid "Выбран личный чат"
|
||||
msgstr "选择了私聊"
|
||||
|
||||
#: olgram/commands/bot_actions.py:68
|
||||
msgid "Нельзя привязать бота к этому чату"
|
||||
msgstr "你不能将机器人链接到这个聊天室"
|
||||
|
||||
#: olgram/commands/bot_actions.py:72
|
||||
msgid "Выбран чат {0}"
|
||||
msgstr "聊天选择 {0}"
|
||||
|
||||
#: olgram/commands/bots.py:42
|
||||
msgid "У вас уже слишком много ботов."
|
||||
msgstr "你已经有太多的机器人了。"
|
||||
|
||||
#: olgram/commands/bots.py:45
|
||||
msgid ""
|
||||
"\n"
|
||||
" Чтобы подключить бот, вам нужно выполнить три действия:\n"
|
||||
"\n"
|
||||
" 1. Перейдите в бот @BotFather, нажмите START и отправьте команду /"
|
||||
"newbot\n"
|
||||
" 2. Введите название бота, а потом username бота.\n"
|
||||
" 3. После создания бота перешлите ответное сообщение в этот бот или "
|
||||
"скопируйте и пришлите token бота.\n"
|
||||
"\n"
|
||||
" Важно: не подключайте боты, которые используются в других сервисах "
|
||||
"(Manybot, Chatfuel, Livegram и других).\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
" 要连接机器人,你需要遵循三个步骤。\n"
|
||||
"\n"
|
||||
" 1. 转到机器人@BotFather,按START键并发送/newbot\n"
|
||||
" 2. 输入机器人的名字,然后输入机器人的用户名。\n"
|
||||
" 3. 一旦创建了机器人,就向这个机器人转发一条回复信息,或者复制并发送机器人"
|
||||
"的令牌。\n"
|
||||
"\n"
|
||||
" 重要:不要连接用于其他服务的机器人(Manybot、Chatfuel、Livegram和其"
|
||||
"他)。\n"
|
||||
" "
|
||||
|
||||
#: olgram/commands/bots.py:65
|
||||
msgid ""
|
||||
"\n"
|
||||
" Это не токен бота.\n"
|
||||
"\n"
|
||||
" Токен выглядит вот так: 123456789:AAAA-"
|
||||
"abc123_AbcdEFghijKLMnopqrstu12\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
" 这不是一个机器人令牌。\n"
|
||||
"\n"
|
||||
" 该令牌看起来像这样:123456789:AAAA-abc123_AbcdEFghijKLMnopqrstu12\n"
|
||||
" "
|
||||
|
||||
#: olgram/commands/bots.py:72
|
||||
msgid ""
|
||||
"\n"
|
||||
" Не удалось запустить этого бота: неверный токен\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
" 运行此机器人失败:错误的令牌\n"
|
||||
" "
|
||||
|
||||
#: olgram/commands/bots.py:77
|
||||
msgid ""
|
||||
"\n"
|
||||
" Не удалось запустить этого бота: непредвиденная ошибка\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
" 该机器人无法启动:意外错误\n"
|
||||
" "
|
||||
|
||||
#: olgram/commands/bots.py:82
|
||||
msgid ""
|
||||
"\n"
|
||||
" Такой бот уже есть в базе данных\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
" 这样的机器人已经在数据库中出现了\n"
|
||||
" "
|
||||
|
||||
#: olgram/commands/bots.py:114
|
||||
msgid "Бот добавлен! Список ваших ботов: /mybots"
|
||||
msgstr "机器人已加入! 你的机器人列表:/mybots"
|
||||
|
||||
#: olgram/commands/info.py:21
|
||||
msgid "Недостаточно прав"
|
||||
msgstr "没有足够的权利"
|
||||
|
||||
#: olgram/commands/info.py:32
|
||||
msgid "Количество ботов: {0}\n"
|
||||
msgstr "机器人的数量。{0}\n"
|
||||
|
||||
#: olgram/commands/info.py:33
|
||||
msgid "Количество пользователей (у конструктора): {0}\n"
|
||||
msgstr "用户的数量(在构造器处)。{0}\n"
|
||||
|
||||
#: olgram/commands/info.py:34
|
||||
msgid "Шаблонов ответов: {0}\n"
|
||||
msgstr "答案模板。{0}\n"
|
||||
|
||||
#: olgram/commands/info.py:35
|
||||
msgid "Входящих сообщений у всех ботов: {0}\n"
|
||||
msgstr "所有的机器人都有传入的信息。{0}\n"
|
||||
|
||||
#: olgram/commands/info.py:36
|
||||
msgid "Исходящих сообщений у всех ботов: {0}\n"
|
||||
msgstr "所有的机器人都有外发信息。{0}\n"
|
||||
|
||||
#: olgram/commands/menu.py:31
|
||||
msgid ""
|
||||
"\n"
|
||||
" У вас нет добавленных ботов.\n"
|
||||
"\n"
|
||||
" Отправьте команду /addbot, чтобы добавить бот.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
" 你没有添加任何机器人。\n"
|
||||
"\n"
|
||||
" 发送命令/addbot来添加一个机器人。\n"
|
||||
" "
|
||||
|
||||
#: olgram/commands/menu.py:46
|
||||
msgid "Ваши боты"
|
||||
msgstr "你的机器人"
|
||||
|
||||
#: olgram/commands/menu.py:67
|
||||
msgid "Личные сообщения"
|
||||
msgstr "个人留言"
|
||||
|
||||
#: olgram/commands/menu.py:72 olgram/commands/menu.py:117
|
||||
#: olgram/commands/menu.py:143 olgram/commands/menu.py:166
|
||||
#: olgram/commands/menu.py:222
|
||||
msgid "<< Назад"
|
||||
msgstr "<< 返回"
|
||||
|
||||
#: olgram/commands/menu.py:78
|
||||
msgid ""
|
||||
"\n"
|
||||
" Этот бот не добавлен в чаты, поэтому все сообщения будут приходить "
|
||||
"вам в бот.\n"
|
||||
" Чтобы подключить чат — добавьте бот @{0} в чат, откройте это меню "
|
||||
"ещё раз и выберите добавленный чат.\n"
|
||||
" Если ваш бот состоял в групповом чате до того, как его добавили в "
|
||||
"Olgram - удалите бота из чата и добавьте\n"
|
||||
" снова.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
" 这个机器人没有被添加到聊天记录中,所以所有的信息都会在机器人中找到"
|
||||
"你。\n"
|
||||
" 要连接聊天--将机器人@{0}添加到聊天中,再次打开此菜单并选择添加的聊"
|
||||
"天。\n"
|
||||
" 如果你的机器人在添加到Olgram之前是在群组聊天中,请将其从聊天室中删"
|
||||
"除,然后添加到群组中。\n"
|
||||
" 再次。\n"
|
||||
" "
|
||||
|
||||
#: olgram/commands/menu.py:85
|
||||
msgid ""
|
||||
"\n"
|
||||
" В этом разделе вы можете привязать бота @{0} к чату.\n"
|
||||
" Выберите чат, куда бот будет пересылать сообщения.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
" 在本节中,您可以将@{0}机器人绑定到一个聊天室。\n"
|
||||
" 选择机器人将转发消息的聊天室。\n"
|
||||
" "
|
||||
|
||||
#: olgram/commands/menu.py:97
|
||||
msgid "Текст"
|
||||
msgstr "文本"
|
||||
|
||||
#: olgram/commands/menu.py:102
|
||||
msgid "Чат"
|
||||
msgstr "聊天"
|
||||
|
||||
#: olgram/commands/menu.py:107
|
||||
msgid "Удалить бот"
|
||||
msgstr "删除机器人"
|
||||
|
||||
#: olgram/commands/menu.py:112
|
||||
msgid "Статистика"
|
||||
msgstr "统计数据"
|
||||
|
||||
#: olgram/commands/menu.py:121
|
||||
msgid "Опции"
|
||||
msgstr "选择"
|
||||
|
||||
#: olgram/commands/menu.py:126
|
||||
msgid ""
|
||||
"\n"
|
||||
" Управление ботом @{0}.\n"
|
||||
"\n"
|
||||
" Если у вас возникли вопросы по настройке бота, то посмотрите нашу "
|
||||
"справку /help или напишите нам\n"
|
||||
" @civsocit_feedback_bot\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
" 机器人管理@{0}。\n"
|
||||
"\n"
|
||||
" 如果你有任何关于机器人配置的问题,请参阅我们的帮助/help或给我们发电子邮"
|
||||
"件\n"
|
||||
" @civsocit_feedback_bot\n"
|
||||
" "
|
||||
|
||||
#: olgram/commands/menu.py:138
|
||||
msgid "Да, удалить бот"
|
||||
msgstr "是的,删除该机器人"
|
||||
|
||||
#: olgram/commands/menu.py:147
|
||||
msgid ""
|
||||
"\n"
|
||||
" Вы уверены, что хотите удалить бота @{0}?\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
" 你确定要删除机器人@{0}吗?\n"
|
||||
" "
|
||||
|
||||
#: olgram/commands/menu.py:156
|
||||
msgid "Потоки сообщений"
|
||||
msgstr "信息流"
|
||||
|
||||
#: olgram/commands/menu.py:161
|
||||
msgid "Данные пользователя"
|
||||
msgstr "用户数据"
|
||||
|
||||
#: olgram/commands/menu.py:171 olgram/commands/menu.py:172
|
||||
msgid "включены"
|
||||
msgstr "包括"
|
||||
|
||||
#: olgram/commands/menu.py:171 olgram/commands/menu.py:172
|
||||
msgid "выключены"
|
||||
msgstr "关闭"
|
||||
|
||||
#: olgram/commands/menu.py:173
|
||||
msgid ""
|
||||
"\n"
|
||||
" <a href=\"https://olgram.readthedocs.io/ru/latest/options.html#threads"
|
||||
"\">Потоки сообщений</a>: <b>{0}</b>\n"
|
||||
" <a href=\"https://olgram.readthedocs.io/ru/latest/options.html#user-info"
|
||||
"\">Данные пользователя</a>: <b>{1}</b>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
" <a href=\"https://olgram.readthedocs.io/ru/latest/options.html#threads\">"
|
||||
"信息流</a>: <b>{0}</b>\n"
|
||||
" <a href=\"https://olgram.readthedocs.io/ru/latest/options.html#user-info"
|
||||
"\">用户数据</a>: <b>{1}</b>\n"
|
||||
" "
|
||||
|
||||
#: olgram/commands/menu.py:185 olgram/commands/menu.py:247
|
||||
#: olgram/commands/menu.py:289
|
||||
msgid "<< Завершить редактирование"
|
||||
msgstr "<< 完成编辑"
|
||||
|
||||
#: olgram/commands/menu.py:189
|
||||
msgid "Автоответчик"
|
||||
msgstr "答录机"
|
||||
|
||||
#: olgram/commands/menu.py:194 olgram/commands/menu.py:261
|
||||
msgid "Сбросить текст"
|
||||
msgstr "重置文本"
|
||||
|
||||
#: olgram/commands/menu.py:199
|
||||
msgid ""
|
||||
"\n"
|
||||
" Сейчас вы редактируете текст, который отправляется после того, как "
|
||||
"пользователь отправит вашему боту @{0}\n"
|
||||
" команду /start\n"
|
||||
"\n"
|
||||
" Текущий текст:\n"
|
||||
" <pre>\n"
|
||||
" {1}\n"
|
||||
" </pre>\n"
|
||||
" Отправьте сообщение, чтобы изменить текст.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
" 你现在正在编辑用户向你的机器人发送@{0}之后的文本。\n"
|
||||
" /启动命令\n"
|
||||
"\n"
|
||||
" 目前的文本。\n"
|
||||
" <pre>\n"
|
||||
" {1}\n"
|
||||
" </pre>。\n"
|
||||
" 发送消息,改变文本。\n"
|
||||
" "
|
||||
|
||||
#: olgram/commands/menu.py:226
|
||||
msgid ""
|
||||
"\n"
|
||||
" Статистика по боту @{0}\n"
|
||||
"\n"
|
||||
" Входящих сообщений: <b>{1}</b>\n"
|
||||
" Ответных сообщений: <b>{2}</b>\n"
|
||||
" Шаблоны ответов: <b>{3}</b>\n"
|
||||
" Забанено пользователей: <b>{4}</b>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
" 机器人统计 @{0}\n"
|
||||
"\n"
|
||||
" 收到的信息: <b>{1}</b>\n"
|
||||
" 回复信息: <b>{2}</b>\n"
|
||||
" 答案模板: <b>{3}</b>\n"
|
||||
" 被禁止的用户: <b>{4}</b>\n"
|
||||
" "
|
||||
|
||||
#: olgram/commands/menu.py:251
|
||||
msgid "Предыдущий текст"
|
||||
msgstr ""
|
||||
|
||||
#: olgram/commands/menu.py:256
|
||||
msgid "Шаблоны ответов..."
|
||||
msgstr "回答模板..."
|
||||
|
||||
#: olgram/commands/menu.py:266
|
||||
msgid ""
|
||||
"\n"
|
||||
" Сейчас вы редактируете текст автоответчика. Это сообщение отправляется в "
|
||||
"ответ на все входящие сообщения @{0} автоматически. По умолчанию оно "
|
||||
"отключено.\n"
|
||||
"\n"
|
||||
" Текущий текст:\n"
|
||||
" <pre>\n"
|
||||
" {1}\n"
|
||||
" </pre>\n"
|
||||
" Отправьте сообщение, чтобы изменить текст.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
" 你现在正在编辑自动回复的文本。该信息会自动响应所有收到的@{0}信息而发送。"
|
||||
"默认情况下,它是禁用的。\n"
|
||||
"\n"
|
||||
" 目前的文本。\n"
|
||||
" <pre>\n"
|
||||
" {1}\n"
|
||||
" </pre>。\n"
|
||||
" 发送消息,改变文本。\n"
|
||||
" "
|
||||
|
||||
#: olgram/commands/menu.py:276
|
||||
msgid "(отключено)"
|
||||
msgstr "(关闭)"
|
||||
|
||||
#: olgram/commands/menu.py:293
|
||||
msgid ""
|
||||
"\n"
|
||||
" Сейчас вы редактируете шаблоны ответов для @{0}. Текущие шаблоны:\n"
|
||||
"\n"
|
||||
" <pre>\n"
|
||||
" {1}\n"
|
||||
" </pre>\n"
|
||||
" Отправьте какую-нибудь фразу (например: \"Ваш заказ готов, ожидайте!\"), "
|
||||
"чтобы добавить её в шаблон.\n"
|
||||
" Чтобы удалить шаблон из списка, отправьте его номер в списке (например, "
|
||||
"4)\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
" 你现在正在编辑@{0}的答案模板。目前的模板。\n"
|
||||
"\n"
|
||||
" <pre>\n"
|
||||
" {1}\n"
|
||||
" </pre>。\n"
|
||||
" 发送一个短语(例如:\"您的订单已准备好,请等待!\"),将其添加到模板"
|
||||
"中。\n"
|
||||
" 要从列表中删除一个模板,请发送它在列表中的编号(如4)。\n"
|
||||
" "
|
||||
|
||||
#: olgram/commands/menu.py:312
|
||||
msgid "(нет шаблонов)"
|
||||
msgstr "(没有模板)"
|
||||
|
||||
#: olgram/commands/menu.py:351
|
||||
msgid "У вас нет шаблонов, чтобы их удалять"
|
||||
msgstr "你没有模板来删除它们"
|
||||
|
||||
#: olgram/commands/menu.py:353
|
||||
msgid "Неправильное число. Чтобы удалить шаблон, введите число от 0 до {0}"
|
||||
msgstr "不正确的数字。要删除一个模式,请在0和{0}之间输入一个数字。"
|
||||
|
||||
#: olgram/commands/menu.py:361
|
||||
msgid "У вашего бота уже слишком много шаблонов"
|
||||
msgstr "你的机器人已经有太多的模式了"
|
||||
|
||||
#: olgram/commands/menu.py:365
|
||||
msgid "Такой текст уже есть в списке шаблонов"
|
||||
msgstr "此文本已在模板列表中"
|
||||
|
||||
#: olgram/commands/menu.py:383
|
||||
msgid "У вас нет прав на этого бота"
|
||||
msgstr "你对这个机器人没有任何权利"
|
||||
|
||||
#: olgram/commands/start.py:23
|
||||
msgid ""
|
||||
"\n"
|
||||
" Olgram Bot — это конструктор ботов обратной связи в Telegram. Подробнее "
|
||||
"<a href=\"https://olgram.readthedocs.io\">читайте здесь</a>.\n"
|
||||
"\n"
|
||||
" Используйте эти команды, чтобы управлять этим ботом:\n"
|
||||
"\n"
|
||||
" /addbot - добавить бот\n"
|
||||
" /mybots - управление ботами\n"
|
||||
"\n"
|
||||
" /help - помощь\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
" Olgram Bot — 是一个Telegram反馈机器人的构建者。阅读更多 <a href="
|
||||
"\"https://olgram.readthedocs.io\">在此阅读</a>.\n"
|
||||
"\n"
|
||||
" 使用这些命令来控制这个机器人:\n"
|
||||
"\n"
|
||||
" /addbot - 捆绑\n"
|
||||
" /mybots - 机器人控制\n"
|
||||
"\n"
|
||||
" /help - 帮助\n"
|
||||
" "
|
||||
|
||||
#: olgram/commands/start.py:42
|
||||
msgid ""
|
||||
"\n"
|
||||
" Читайте инструкции на нашем сайте https://olgram.readthedocs.io\n"
|
||||
" Техническая поддержка: @civsocit_feedback_bot\n"
|
||||
" Версия {0}\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
" 请阅读我们网站上的说明 https://olgram.readthedocs.io\n"
|
||||
" 技术支持。@civsocit_feedback_bot\n"
|
||||
" 版本{0}\n"
|
||||
" "
|
||||
|
||||
#: olgram/models/models.py:30
|
||||
msgid ""
|
||||
"\n"
|
||||
" Здравствуйте!\n"
|
||||
" Напишите ваш вопрос и мы ответим вам в ближайшее время.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
" 你好!\n"
|
||||
" 请写下您的问题,我们将很快给您答复。\n"
|
||||
" "
|
||||
|
||||
#: olgram/utils/permissions.py:40
|
||||
msgid "Владелец бота ограничил доступ к этому функционалу 😞"
|
||||
msgstr "机器人所有者已经限制了对该功能的访问 😞"
|
||||
|
||||
#: olgram/utils/permissions.py:52
|
||||
msgid "Владелец бота ограничил доступ к этому функционалу😞"
|
||||
msgstr "机器人主人限制了对该功能的访问😞。"
|
||||
|
||||
#: server/custom.py:40
|
||||
msgid ""
|
||||
"<b>Политика конфиденциальности</b>\n"
|
||||
"\n"
|
||||
"Этот бот не хранит ваши сообщения, имя пользователя и @username. При "
|
||||
"отправке сообщения (кроме команд /start и /security_policy) ваш "
|
||||
"идентификатор пользователя записывается в кеш на некоторое время и потом "
|
||||
"удаляется из кеша. Этот идентификатор используется только для общения с "
|
||||
"оператором; боты Olgram не делают массовых рассылок.\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
"<b>隐私政策</b\n"
|
||||
"\n"
|
||||
"这个机器人不存储你的信息、用户名或@用户名。当你发送消息时(除/start和/"
|
||||
"security_policy外),你的用户名会被缓存一段时间,然后从缓存中删除。这个ID只用"
|
||||
"于与运营商沟通;Olgram机器人不做批量信息发送。\n"
|
||||
"\n"
|
||||
|
||||
#: server/custom.py:46
|
||||
msgid ""
|
||||
"При отправке сообщения (кроме команд /start и /security_policy) оператор "
|
||||
"<b>видит</b> ваши имя пользователя, @username и идентификатор пользователя в "
|
||||
"силу настроек, которые оператор указал при создании бота."
|
||||
msgstr ""
|
||||
"当发送消息时(除了/start和/security_policy),操作者<b>看到</b>你的用户名、@"
|
||||
"用户名和用户ID,凭借的是操作者在创建机器人时指定的设置。"
|
||||
|
||||
#: server/custom.py:50
|
||||
msgid ""
|
||||
"В зависимости от ваших настроек конфиденциальности Telegram, оператор может "
|
||||
"видеть ваш username, имя пользователя и другую информацию."
|
||||
msgstr ""
|
||||
"根据你的Telegram隐私设置,运营商可能会看到你的用户名,用户名和其他信息。"
|
||||
|
||||
#: server/custom.py:61
|
||||
msgid "Сообщение от пользователя "
|
||||
msgstr "用户的信息 "
|
||||
|
||||
#: server/custom.py:88
|
||||
msgid "Вы заблокированы в этом боте"
|
||||
msgstr "你在这个机器人中被封锁了"
|
||||
|
||||
#: server/custom.py:128
|
||||
msgid ""
|
||||
"<i>Невозможно переслать сообщение: автор не найден (сообщение слишком "
|
||||
"старое?)</i>"
|
||||
msgstr "无法转发信息:找不到作者(信息太旧?)"
|
||||
|
||||
#: server/custom.py:136
|
||||
msgid "Пользователь заблокирован"
|
||||
msgstr "用户被封锁了"
|
||||
|
||||
#: server/custom.py:141
|
||||
msgid "Пользователь не был забанен"
|
||||
msgstr "该用户没有被禁止"
|
||||
|
||||
#: server/custom.py:144
|
||||
msgid "Пользователь разбанен"
|
||||
msgstr "解禁的用户"
|
||||
|
||||
#: server/custom.py:149
|
||||
msgid "<i>Невозможно переслать сообщение (автор заблокировал бота?)</i>"
|
||||
msgstr "无法转发该信息(作者已经屏蔽了机器人?)"
|
||||
|
||||
#: server/server.py:41
|
||||
msgid "(Пере)запустить бота"
|
||||
msgstr "(重新)启动机器人"
|
||||
|
||||
#: server/server.py:42
|
||||
msgid "Политика конфиденциальности"
|
||||
msgstr "隐私政策"
|
9
main.py
9
main.py
@ -12,6 +12,7 @@ import olgram.commands.start # noqa: F401
|
||||
import olgram.commands.menu # noqa: F401
|
||||
import olgram.commands.bot_actions # noqa: F401
|
||||
import olgram.commands.info # noqa: F401
|
||||
from locales.locale import _
|
||||
|
||||
from server.server import main as server_main
|
||||
|
||||
@ -26,10 +27,10 @@ async def init_olgram():
|
||||
from aiogram.types import BotCommand
|
||||
await bot.set_my_commands(
|
||||
[
|
||||
BotCommand("start", "Запустить бота"),
|
||||
BotCommand("addbot", "Добавить бот"),
|
||||
BotCommand("mybots", "Управление ботами"),
|
||||
BotCommand("help", "Справка")
|
||||
BotCommand("start", _("Запустить бота")),
|
||||
BotCommand("addbot", _("Добавить бот")),
|
||||
BotCommand("mybots", _("Управление ботами")),
|
||||
BotCommand("help", _("Справка"))
|
||||
]
|
||||
)
|
||||
|
||||
|
@ -5,6 +5,7 @@ from aiogram import types
|
||||
from aiogram.utils.exceptions import TelegramAPIError, Unauthorized
|
||||
from olgram.models.models import Bot
|
||||
from server.server import unregister_token
|
||||
from locales.locale import _
|
||||
|
||||
|
||||
async def delete_bot(bot: Bot, call: types.CallbackQuery):
|
||||
@ -17,7 +18,7 @@ async def delete_bot(bot: Bot, call: types.CallbackQuery):
|
||||
# Вероятно пользователь сбросил токен или удалил бот, это уже не наши проблемы
|
||||
pass
|
||||
await bot.delete()
|
||||
await call.answer("Бот удалён")
|
||||
await call.answer(_("Бот удалён"))
|
||||
try:
|
||||
await call.message.delete()
|
||||
except TelegramAPIError:
|
||||
@ -33,7 +34,7 @@ async def reset_bot_text(bot: Bot, call: types.CallbackQuery):
|
||||
"""
|
||||
bot.start_text = bot._meta.fields_map['start_text'].default
|
||||
await bot.save()
|
||||
await call.answer("Текст сброшен")
|
||||
await call.answer(_("Текст сброшен"))
|
||||
|
||||
|
||||
async def reset_bot_second_text(bot: Bot, call: types.CallbackQuery):
|
||||
@ -45,7 +46,7 @@ async def reset_bot_second_text(bot: Bot, call: types.CallbackQuery):
|
||||
"""
|
||||
bot.second_text = bot._meta.fields_map['second_text'].default
|
||||
await bot.save()
|
||||
await call.answer("Текст сброшен")
|
||||
await call.answer(_("Текст сброшен"))
|
||||
|
||||
|
||||
async def select_chat(bot: Bot, call: types.CallbackQuery, chat: str):
|
||||
@ -59,16 +60,16 @@ async def select_chat(bot: Bot, call: types.CallbackQuery, chat: str):
|
||||
if chat == "personal":
|
||||
bot.group_chat = None
|
||||
await bot.save()
|
||||
await call.answer("Выбран личный чат")
|
||||
await call.answer(_("Выбран личный чат"))
|
||||
return
|
||||
|
||||
chat_obj = await bot.group_chats.filter(id=chat).first()
|
||||
if not chat_obj:
|
||||
await call.answer("Нельзя привязать бота к этому чату")
|
||||
await call.answer(_("Нельзя привязать бота к этому чату"))
|
||||
return
|
||||
bot.group_chat = chat_obj
|
||||
await bot.save()
|
||||
await call.answer(f"Выбран чат {chat_obj.name}")
|
||||
await call.answer(_("Выбран чат {0}").format(chat_obj.name))
|
||||
|
||||
|
||||
async def threads(bot: Bot, call: types.CallbackQuery):
|
||||
|
@ -12,6 +12,7 @@ from olgram.models.models import Bot, User
|
||||
from olgram.settings import OlgramSettings
|
||||
from olgram.commands.menu import send_bots_menu
|
||||
from server.server import register_token
|
||||
from locales.locale import _
|
||||
|
||||
from olgram.router import dp
|
||||
|
||||
@ -38,10 +39,10 @@ async def add_bot(message: types.Message, state: FSMContext):
|
||||
"""
|
||||
bot_count = await Bot.filter(owner__telegram_id=message.from_user.id).count()
|
||||
if bot_count >= OlgramSettings.max_bots_per_user():
|
||||
await message.answer("У вас уже слишком много ботов.")
|
||||
await message.answer(_("У вас уже слишком много ботов."))
|
||||
return
|
||||
|
||||
await message.answer(dedent("""
|
||||
await message.answer(dedent(_("""
|
||||
Чтобы подключить бот, вам нужно выполнить три действия:
|
||||
|
||||
1. Перейдите в бот @BotFather, нажмите START и отправьте команду /newbot
|
||||
@ -49,7 +50,7 @@ async def add_bot(message: types.Message, state: FSMContext):
|
||||
3. После создания бота перешлите ответное сообщение в этот бот или скопируйте и пришлите token бота.
|
||||
|
||||
Важно: не подключайте боты, которые используются в других сервисах (Manybot, Chatfuel, Livegram и других).
|
||||
"""))
|
||||
""")))
|
||||
await state.set_state("add_bot")
|
||||
|
||||
|
||||
@ -61,26 +62,26 @@ async def bot_added(message: types.Message, state: FSMContext):
|
||||
token = re.findall(token_pattern, message.text)
|
||||
|
||||
async def on_invalid_token():
|
||||
await message.answer(dedent("""
|
||||
await message.answer(dedent(_("""
|
||||
Это не токен бота.
|
||||
|
||||
Токен выглядит вот так: 123456789:AAAA-abc123_AbcdEFghijKLMnopqrstu12
|
||||
"""))
|
||||
""")))
|
||||
|
||||
async def on_dummy_token():
|
||||
await message.answer(dedent("""
|
||||
await message.answer(dedent(_("""
|
||||
Не удалось запустить этого бота: неверный токен
|
||||
"""))
|
||||
""")))
|
||||
|
||||
async def on_unknown_error():
|
||||
await message.answer(dedent("""
|
||||
await message.answer(dedent(_("""
|
||||
Не удалось запустить этого бота: непредвиденная ошибка
|
||||
"""))
|
||||
""")))
|
||||
|
||||
async def on_duplication_bot():
|
||||
await message.answer(dedent("""
|
||||
await message.answer(dedent(_("""
|
||||
Такой бот уже есть в базе данных
|
||||
"""))
|
||||
""")))
|
||||
|
||||
if not token:
|
||||
return await on_invalid_token()
|
||||
@ -98,7 +99,7 @@ async def bot_added(message: types.Message, state: FSMContext):
|
||||
except TelegramAPIError:
|
||||
return await on_unknown_error()
|
||||
|
||||
user, _ = await User.get_or_create(telegram_id=message.from_user.id)
|
||||
user, created = await User.get_or_create(telegram_id=message.from_user.id)
|
||||
bot = Bot(token=Bot.encrypted_token(token), owner=user, name=test_bot_info.username,
|
||||
super_chat_id=message.from_user.id)
|
||||
try:
|
||||
@ -110,5 +111,5 @@ async def bot_added(message: types.Message, state: FSMContext):
|
||||
await bot.delete()
|
||||
return await on_unknown_error()
|
||||
|
||||
await message.answer("Бот добавлен! Список ваших ботов: /mybots")
|
||||
await message.answer(_("Бот добавлен! Список ваших ботов: /mybots"))
|
||||
await state.reset_state()
|
||||
|
@ -8,6 +8,7 @@ from olgram.models import models
|
||||
|
||||
from olgram.router import dp
|
||||
from olgram.settings import OlgramSettings
|
||||
from locales.locale import _
|
||||
|
||||
|
||||
@dp.message_handler(commands=["info"], state="*")
|
||||
@ -17,7 +18,7 @@ async def info(message: types.Message, state: FSMContext):
|
||||
"""
|
||||
|
||||
if message.chat.id != OlgramSettings.supervisor_id():
|
||||
await message.answer("Недостаточно прав")
|
||||
await message.answer(_("Недостаточно прав"))
|
||||
return
|
||||
|
||||
bots = await models.Bot.all()
|
||||
@ -28,8 +29,8 @@ async def info(message: types.Message, state: FSMContext):
|
||||
income_messages = sum([bot.incoming_messages_count for bot in bots])
|
||||
outgoing_messages = sum([bot.outgoing_messages_count for bot in bots])
|
||||
|
||||
await message.answer(f"Количество ботов: {bots_count}\n"
|
||||
f"Количество пользователей (у конструктора): {user_count}\n"
|
||||
f"Шаблонов ответов: {templates_count}\n"
|
||||
f"Входящих сообщений у всех ботов: {income_messages}\n"
|
||||
f"Исходящих сообщений у всех ботов: {outgoing_messages}\n")
|
||||
await message.answer(_("Количество ботов: {0}\n").format(bots_count) +
|
||||
_("Количество пользователей (у конструктора): {0}\n").format(user_count) +
|
||||
_("Шаблонов ответов: {0}\n").format(templates_count) +
|
||||
_("Входящих сообщений у всех ботов: {0}\n").format(income_messages) +
|
||||
_("Исходящих сообщений у всех ботов: {0}\n").format(outgoing_messages))
|
||||
|
@ -7,6 +7,7 @@ from aiogram.utils.callback_data import CallbackData
|
||||
from textwrap import dedent
|
||||
from olgram.utils.mix import edit_or_create, button_text_limit, wrap
|
||||
from olgram.commands import bot_actions
|
||||
from locales.locale import _
|
||||
|
||||
import typing as ty
|
||||
|
||||
@ -27,11 +28,11 @@ async def send_bots_menu(chat_id: int, user_id: int, call=None):
|
||||
user = await User.get_or_none(telegram_id=user_id)
|
||||
bots = await Bot.filter(owner=user)
|
||||
if not bots:
|
||||
await AioBot.get_current().send_message(chat_id, dedent("""
|
||||
await AioBot.get_current().send_message(chat_id, dedent(_("""
|
||||
У вас нет добавленных ботов.
|
||||
|
||||
Отправьте команду /addbot, чтобы добавить бот.
|
||||
"""))
|
||||
""")))
|
||||
return
|
||||
|
||||
keyboard = types.InlineKeyboardMarkup(row_width=2)
|
||||
@ -42,7 +43,7 @@ async def send_bots_menu(chat_id: int, user_id: int, call=None):
|
||||
chat=empty))
|
||||
)
|
||||
|
||||
text = "Ваши боты"
|
||||
text = _("Ваши боты")
|
||||
if call:
|
||||
await edit_or_create(call, text, keyboard)
|
||||
else:
|
||||
@ -63,28 +64,28 @@ async def send_chats_menu(bot: Bot, call: types.CallbackQuery):
|
||||
)
|
||||
if chats:
|
||||
keyboard.insert(
|
||||
types.InlineKeyboardButton(text="Личные сообщения",
|
||||
types.InlineKeyboardButton(text=_("Личные сообщения"),
|
||||
callback_data=menu_callback.new(level=3, bot_id=bot.id, operation="chat",
|
||||
chat="personal"))
|
||||
)
|
||||
keyboard.insert(
|
||||
types.InlineKeyboardButton(text="<< Назад",
|
||||
types.InlineKeyboardButton(text=_("<< Назад"),
|
||||
callback_data=menu_callback.new(level=1, bot_id=bot.id, operation=empty,
|
||||
chat=empty))
|
||||
)
|
||||
|
||||
if not chats:
|
||||
text = dedent(f"""
|
||||
text = dedent(_("""
|
||||
Этот бот не добавлен в чаты, поэтому все сообщения будут приходить вам в бот.
|
||||
Чтобы подключить чат — добавьте бот @{bot.name} в чат, откройте это меню ещё раз и выберите добавленный чат.
|
||||
Чтобы подключить чат — добавьте бот @{0} в чат, откройте это меню ещё раз и выберите добавленный чат.
|
||||
Если ваш бот состоял в групповом чате до того, как его добавили в Olgram - удалите бота из чата и добавьте
|
||||
снова.
|
||||
""")
|
||||
""")).format(bot.name)
|
||||
else:
|
||||
text = dedent(f"""
|
||||
В этом разделе вы можете привязать бота @{bot.name} к чату.
|
||||
text = dedent(_("""
|
||||
В этом разделе вы можете привязать бота @{0} к чату.
|
||||
Выберите чат, куда бот будет пересылать сообщения.
|
||||
""")
|
||||
""")).format(bot.name)
|
||||
|
||||
await edit_or_create(call, text, keyboard)
|
||||
|
||||
@ -93,86 +94,86 @@ async def send_bot_menu(bot: Bot, call: types.CallbackQuery):
|
||||
await call.answer()
|
||||
keyboard = types.InlineKeyboardMarkup(row_width=2)
|
||||
keyboard.insert(
|
||||
types.InlineKeyboardButton(text="Текст",
|
||||
types.InlineKeyboardButton(text=_("Текст"),
|
||||
callback_data=menu_callback.new(level=2, bot_id=bot.id, operation="text",
|
||||
chat=empty))
|
||||
)
|
||||
keyboard.insert(
|
||||
types.InlineKeyboardButton(text="Чат",
|
||||
types.InlineKeyboardButton(text=_("Чат"),
|
||||
callback_data=menu_callback.new(level=2, bot_id=bot.id, operation="chat",
|
||||
chat=empty))
|
||||
)
|
||||
keyboard.insert(
|
||||
types.InlineKeyboardButton(text="Удалить бот",
|
||||
types.InlineKeyboardButton(text=_("Удалить бот"),
|
||||
callback_data=menu_callback.new(level=2, bot_id=bot.id, operation="delete",
|
||||
chat=empty))
|
||||
)
|
||||
keyboard.insert(
|
||||
types.InlineKeyboardButton(text="Статистика",
|
||||
types.InlineKeyboardButton(text=_("Статистика"),
|
||||
callback_data=menu_callback.new(level=2, bot_id=bot.id, operation="stat",
|
||||
chat=empty))
|
||||
)
|
||||
keyboard.insert(
|
||||
types.InlineKeyboardButton(text="<< Назад",
|
||||
types.InlineKeyboardButton(text=_("<< Назад"),
|
||||
callback_data=menu_callback.new(level=0, bot_id=empty, operation=empty, chat=empty))
|
||||
)
|
||||
keyboard.insert(
|
||||
types.InlineKeyboardButton(text="Опции",
|
||||
types.InlineKeyboardButton(text=_("Опции"),
|
||||
callback_data=menu_callback.new(level=2, bot_id=bot.id, operation="settings",
|
||||
chat=empty))
|
||||
)
|
||||
|
||||
await edit_or_create(call, dedent(f"""
|
||||
Управление ботом @{bot.name}.
|
||||
await edit_or_create(call, dedent(_("""
|
||||
Управление ботом @{0}.
|
||||
|
||||
Если у вас возникли вопросы по настройке бота, то посмотрите нашу справку /help или напишите нам
|
||||
@civsocit_feedback_bot
|
||||
"""), reply_markup=keyboard)
|
||||
""")).format(bot.name), reply_markup=keyboard)
|
||||
|
||||
|
||||
async def send_bot_delete_menu(bot: Bot, call: types.CallbackQuery):
|
||||
await call.answer()
|
||||
keyboard = types.InlineKeyboardMarkup(row_width=2)
|
||||
keyboard.insert(
|
||||
types.InlineKeyboardButton(text="Да, удалить бот",
|
||||
types.InlineKeyboardButton(text=_("Да, удалить бот"),
|
||||
callback_data=menu_callback.new(level=3, bot_id=bot.id, operation="delete_yes",
|
||||
chat=empty))
|
||||
)
|
||||
keyboard.insert(
|
||||
types.InlineKeyboardButton(text="<< Назад",
|
||||
types.InlineKeyboardButton(text=_("<< Назад"),
|
||||
callback_data=menu_callback.new(level=1, bot_id=bot.id, operation=empty, chat=empty))
|
||||
)
|
||||
|
||||
await edit_or_create(call, dedent(f"""
|
||||
Вы уверены, что хотите удалить бота @{bot.name}?
|
||||
"""), reply_markup=keyboard)
|
||||
await edit_or_create(call, dedent(_("""
|
||||
Вы уверены, что хотите удалить бота @{0}?
|
||||
""")).format(bot.name), reply_markup=keyboard)
|
||||
|
||||
|
||||
async def send_bot_settings_menu(bot: Bot, call: types.CallbackQuery):
|
||||
await call.answer()
|
||||
keyboard = types.InlineKeyboardMarkup(row_width=1)
|
||||
keyboard.insert(
|
||||
types.InlineKeyboardButton(text="Потоки сообщений",
|
||||
types.InlineKeyboardButton(text=_("Потоки сообщений"),
|
||||
callback_data=menu_callback.new(level=3, bot_id=bot.id, operation="threads",
|
||||
chat=empty))
|
||||
)
|
||||
keyboard.insert(
|
||||
types.InlineKeyboardButton(text="Данные пользователя",
|
||||
types.InlineKeyboardButton(text=_("Данные пользователя"),
|
||||
callback_data=menu_callback.new(level=3, bot_id=bot.id, operation="additional_info",
|
||||
chat=empty))
|
||||
)
|
||||
keyboard.insert(
|
||||
types.InlineKeyboardButton(text="<< Назад",
|
||||
types.InlineKeyboardButton(text=_("<< Назад"),
|
||||
callback_data=menu_callback.new(level=1, bot_id=bot.id, operation=empty,
|
||||
chat=empty))
|
||||
)
|
||||
|
||||
thread_turn = "включены" if bot.enable_threads else "выключены"
|
||||
info_turn = "включены" if bot.enable_additional_info else "выключены"
|
||||
text = dedent(f"""
|
||||
<a href="https://olgram.readthedocs.io/ru/latest/options.html#threads">Потоки сообщений</a>: <b>{thread_turn}</b>
|
||||
<a href="https://olgram.readthedocs.io/ru/latest/options.html#user-info">Данные пользователя</a>: <b>{info_turn}</b>
|
||||
""")
|
||||
thread_turn = _("включены") if bot.enable_threads else _("выключены")
|
||||
info_turn = _("включены") if bot.enable_additional_info else _("выключены")
|
||||
text = dedent(_("""
|
||||
<a href="https://olgram.readthedocs.io/ru/latest/options.html#threads">Потоки сообщений</a>: <b>{0}</b>
|
||||
<a href="https://olgram.readthedocs.io/ru/latest/options.html#user-info">Данные пользователя</a>: <b>{1}</b>
|
||||
""")).format(thread_turn, info_turn)
|
||||
await edit_or_create(call, text, reply_markup=keyboard, parse_mode="HTML")
|
||||
|
||||
|
||||
@ -181,21 +182,21 @@ async def send_bot_text_menu(bot: Bot, call: ty.Optional[types.CallbackQuery] =
|
||||
await call.answer()
|
||||
keyboard = types.InlineKeyboardMarkup(row_width=2)
|
||||
keyboard.insert(
|
||||
types.InlineKeyboardButton(text="<< Завершить редактирование",
|
||||
types.InlineKeyboardButton(text=_("<< Завершить редактирование"),
|
||||
callback_data=menu_callback.new(level=1, bot_id=bot.id, operation=empty, chat=empty))
|
||||
)
|
||||
keyboard.insert(
|
||||
types.InlineKeyboardButton(text="Автоответчик",
|
||||
types.InlineKeyboardButton(text=_("Автоответчик"),
|
||||
callback_data=menu_callback.new(level=3, bot_id=bot.id, operation="next_text",
|
||||
chat=empty))
|
||||
)
|
||||
keyboard.insert(
|
||||
types.InlineKeyboardButton(text="Сбросить текст",
|
||||
types.InlineKeyboardButton(text=_("Сбросить текст"),
|
||||
callback_data=menu_callback.new(level=3, bot_id=bot.id, operation="reset_text",
|
||||
chat=empty))
|
||||
)
|
||||
|
||||
text = dedent("""
|
||||
text = dedent(_("""
|
||||
Сейчас вы редактируете текст, который отправляется после того, как пользователь отправит вашему боту @{0}
|
||||
команду /start
|
||||
|
||||
@ -204,7 +205,7 @@ async def send_bot_text_menu(bot: Bot, call: ty.Optional[types.CallbackQuery] =
|
||||
{1}
|
||||
</pre>
|
||||
Отправьте сообщение, чтобы изменить текст.
|
||||
""")
|
||||
"""))
|
||||
text = text.format(bot.name, bot.start_text)
|
||||
if call:
|
||||
await edit_or_create(call, text, keyboard, parse_mode="HTML")
|
||||
@ -218,18 +219,19 @@ async def send_bot_statistic_menu(bot: Bot, call: ty.Optional[types.CallbackQuer
|
||||
await call.answer()
|
||||
keyboard = types.InlineKeyboardMarkup(row_width=2)
|
||||
keyboard.insert(
|
||||
types.InlineKeyboardButton(text="<< Назад",
|
||||
types.InlineKeyboardButton(text=_("<< Назад"),
|
||||
callback_data=menu_callback.new(level=1, bot_id=bot.id, operation=empty, chat=empty))
|
||||
)
|
||||
|
||||
text = dedent(f"""
|
||||
Статистика по боту @{bot.name}
|
||||
text = dedent(_("""
|
||||
Статистика по боту @{0}
|
||||
|
||||
Входящих сообщений: <b>{bot.incoming_messages_count}</b>
|
||||
Ответных сообщений: <b>{bot.outgoing_messages_count}</b>
|
||||
Шаблоны ответов: <b>{len(await bot.answers)}</b>
|
||||
Забанено пользователей: <b>{len(await bot.banned_users)}</b>
|
||||
""")
|
||||
Входящих сообщений: <b>{1}</b>
|
||||
Ответных сообщений: <b>{2}</b>
|
||||
Шаблоны ответов: <b>{3}</b>
|
||||
Забанено пользователей: <b>{4}</b>
|
||||
""")).format(bot.name, bot.incoming_messages_count, bot.outgoing_messages_count, len(await bot.answers),
|
||||
len(await bot.banned_users))
|
||||
if call:
|
||||
await edit_or_create(call, text, keyboard, parse_mode="HTML")
|
||||
else:
|
||||
@ -242,26 +244,26 @@ async def send_bot_second_text_menu(bot: Bot, call: ty.Optional[types.CallbackQu
|
||||
await call.answer()
|
||||
keyboard = types.InlineKeyboardMarkup(row_width=2)
|
||||
keyboard.insert(
|
||||
types.InlineKeyboardButton(text="<< Завершить редактирование",
|
||||
types.InlineKeyboardButton(text=_("<< Завершить редактирование"),
|
||||
callback_data=menu_callback.new(level=1, bot_id=bot.id, operation=empty, chat=empty))
|
||||
)
|
||||
keyboard.insert(
|
||||
types.InlineKeyboardButton(text="Предыдущий текст",
|
||||
types.InlineKeyboardButton(text=_("Предыдущий текст"),
|
||||
callback_data=menu_callback.new(level=2, bot_id=bot.id, operation="text",
|
||||
chat=empty))
|
||||
)
|
||||
keyboard.insert(
|
||||
types.InlineKeyboardButton(text="Шаблоны ответов...",
|
||||
types.InlineKeyboardButton(text=_("Шаблоны ответов..."),
|
||||
callback_data=menu_callback.new(level=3, bot_id=bot.id, operation="templates",
|
||||
chat=empty))
|
||||
)
|
||||
keyboard.insert(
|
||||
types.InlineKeyboardButton(text="Сбросить текст",
|
||||
types.InlineKeyboardButton(text=_("Сбросить текст"),
|
||||
callback_data=menu_callback.new(level=3, bot_id=bot.id,
|
||||
operation="reset_second_text", chat=empty))
|
||||
)
|
||||
|
||||
text = dedent("""
|
||||
text = dedent(_("""
|
||||
Сейчас вы редактируете текст автоответчика. Это сообщение отправляется в ответ на все входящие сообщения @{0} \
|
||||
автоматически. По умолчанию оно отключено.
|
||||
|
||||
@ -270,8 +272,8 @@ async def send_bot_second_text_menu(bot: Bot, call: ty.Optional[types.CallbackQu
|
||||
{1}
|
||||
</pre>
|
||||
Отправьте сообщение, чтобы изменить текст.
|
||||
""")
|
||||
text = text.format(bot.name, bot.second_text if bot.second_text else "(отключено)")
|
||||
"""))
|
||||
text = text.format(bot.name, bot.second_text if bot.second_text else _("(отключено)"))
|
||||
if call:
|
||||
await edit_or_create(call, text, keyboard, parse_mode="HTML")
|
||||
else:
|
||||
@ -284,11 +286,11 @@ async def send_bot_templates_menu(bot: Bot, call: ty.Optional[types.CallbackQuer
|
||||
await call.answer()
|
||||
keyboard = types.InlineKeyboardMarkup(row_width=2)
|
||||
keyboard.insert(
|
||||
types.InlineKeyboardButton(text="<< Завершить редактирование",
|
||||
types.InlineKeyboardButton(text=_("<< Завершить редактирование"),
|
||||
callback_data=menu_callback.new(level=1, bot_id=bot.id, operation=empty, chat=empty))
|
||||
)
|
||||
|
||||
text = dedent("""
|
||||
text = dedent(_("""
|
||||
Сейчас вы редактируете шаблоны ответов для @{0}. Текущие шаблоны:
|
||||
|
||||
<pre>
|
||||
@ -296,7 +298,7 @@ async def send_bot_templates_menu(bot: Bot, call: ty.Optional[types.CallbackQuer
|
||||
</pre>
|
||||
Отправьте какую-нибудь фразу (например: "Ваш заказ готов, ожидайте!"), чтобы добавить её в шаблон.
|
||||
Чтобы удалить шаблон из списка, отправьте его номер в списке (например, 4)
|
||||
""")
|
||||
"""))
|
||||
|
||||
templates = await bot.answers
|
||||
|
||||
@ -307,7 +309,7 @@ async def send_bot_templates_menu(bot: Bot, call: ty.Optional[types.CallbackQuer
|
||||
|
||||
templates_text = "\n".join(f"{n}. {wrap(template.text, max_len)}" for n, template in enumerate(templates))
|
||||
if not templates_text:
|
||||
templates_text = "(нет шаблонов)"
|
||||
templates_text = _("(нет шаблонов)")
|
||||
text = text.format(bot.name, templates_text)
|
||||
if call:
|
||||
await edit_or_create(call, text, keyboard, parse_mode="HTML")
|
||||
@ -346,20 +348,21 @@ async def template_received(message: types.Message, state: FSMContext):
|
||||
number = int(message.text)
|
||||
templates = await bot.answers
|
||||
if not templates:
|
||||
await message.answer("У вас нет шаблонов, чтобы их удалять")
|
||||
await message.answer(_("У вас нет шаблонов, чтобы их удалять"))
|
||||
if number < 0 or number >= len(templates):
|
||||
await message.answer(f"Неправильное число. Чтобы удалить шаблон, введите число от 0 до {len(templates)}")
|
||||
await message.answer(_("Неправильное число. Чтобы удалить шаблон, введите число от 0 до {0}").format(
|
||||
len(templates)))
|
||||
return
|
||||
await templates[number].delete()
|
||||
else:
|
||||
# Add template
|
||||
total_templates = len(await bot.answers)
|
||||
if total_templates > 30:
|
||||
await message.answer("У вашего бота уже слишком много шаблонов")
|
||||
await message.answer(_("У вашего бота уже слишком много шаблонов"))
|
||||
else:
|
||||
answers = await bot.answers.filter(text=message.text)
|
||||
if answers:
|
||||
await message.answer("Такой текст уже есть в списке шаблонов")
|
||||
await message.answer(_("Такой текст уже есть в списке шаблонов"))
|
||||
else:
|
||||
template = DefaultAnswer(text=message.text, bot=bot)
|
||||
await template.save()
|
||||
@ -377,7 +380,7 @@ async def callback(call: types.CallbackQuery, callback_data: dict, state: FSMCon
|
||||
bot_id = callback_data.get("bot_id")
|
||||
bot = await Bot.get_or_none(id=bot_id)
|
||||
if not bot or (await bot.owner).telegram_id != call.from_user.id:
|
||||
await call.answer("У вас нет прав на этого бота", show_alert=True)
|
||||
await call.answer(_("У вас нет прав на этого бота"), show_alert=True)
|
||||
return
|
||||
|
||||
if level == "1":
|
||||
|
@ -7,6 +7,7 @@ from aiogram.dispatcher import FSMContext
|
||||
from textwrap import dedent
|
||||
from olgram.settings import OlgramSettings
|
||||
from olgram.utils.permissions import public
|
||||
from locales.locale import _
|
||||
|
||||
from olgram.router import dp
|
||||
|
||||
@ -19,9 +20,7 @@ async def start(message: types.Message, state: FSMContext):
|
||||
"""
|
||||
await state.reset_state()
|
||||
|
||||
# TODO: locale
|
||||
|
||||
await message.answer(dedent("""
|
||||
await message.answer(dedent(_("""
|
||||
Olgram Bot — это конструктор ботов обратной связи в Telegram. Подробнее \
|
||||
<a href="https://olgram.readthedocs.io">читайте здесь</a>.
|
||||
|
||||
@ -31,7 +30,7 @@ async def start(message: types.Message, state: FSMContext):
|
||||
/mybots - управление ботами
|
||||
|
||||
/help - помощь
|
||||
"""), parse_mode="html")
|
||||
""")), parse_mode="html")
|
||||
|
||||
|
||||
@dp.message_handler(commands=["help"], state="*")
|
||||
@ -40,11 +39,11 @@ async def help(message: types.Message, state: FSMContext):
|
||||
"""
|
||||
Команда /help
|
||||
"""
|
||||
await message.answer(dedent(f"""
|
||||
await message.answer(dedent(_("""
|
||||
Читайте инструкции на нашем сайте https://olgram.readthedocs.io
|
||||
Техническая поддержка: @civsocit_feedback_bot
|
||||
Версия {OlgramSettings.version()}
|
||||
"""))
|
||||
Версия {0}
|
||||
""")).format(OlgramSettings.version()))
|
||||
|
||||
|
||||
@dp.message_handler(commands=["chatid"], state="*")
|
||||
|
@ -3,6 +3,7 @@ from tortoise import fields
|
||||
from uuid import uuid4
|
||||
from textwrap import dedent
|
||||
from olgram.settings import DatabaseSettings
|
||||
from locales.locale import _
|
||||
|
||||
|
||||
class MetaInfo(Model):
|
||||
@ -26,10 +27,10 @@ class Bot(Model):
|
||||
owner = fields.ForeignKeyField("models.User", related_name="bots")
|
||||
name = fields.CharField(max_length=33)
|
||||
code = fields.UUIDField(default=uuid4, index=True)
|
||||
start_text = fields.TextField(default=dedent("""
|
||||
start_text = fields.TextField(default=dedent(_("""
|
||||
Здравствуйте!
|
||||
Напишите ваш вопрос и мы ответим вам в ближайшее время.
|
||||
"""))
|
||||
""")))
|
||||
second_text = fields.TextField(null=True, default=None)
|
||||
|
||||
group_chats = fields.ManyToManyField("models.GroupChat", related_name="bots", on_delete=fields.relational.CASCADE,
|
||||
|
@ -109,6 +109,14 @@ class BotSettings(AbstractSettings):
|
||||
"""
|
||||
return cls._get_env("BOT_TOKEN")
|
||||
|
||||
@classmethod
|
||||
def language(cls) -> str:
|
||||
"""
|
||||
Язык
|
||||
"""
|
||||
lang = cls._get_env("O_LANG", allow_none=True)
|
||||
return lang.lower() if lang else "ru"
|
||||
|
||||
|
||||
class DatabaseSettings(AbstractSettings):
|
||||
@classmethod
|
||||
|
@ -1,6 +1,7 @@
|
||||
import aiogram.types as types
|
||||
from aiogram.dispatcher.handler import CancelHandler, current_handler
|
||||
from aiogram.dispatcher.middlewares import BaseMiddleware
|
||||
from locales.locale import _
|
||||
|
||||
|
||||
def public():
|
||||
@ -36,7 +37,7 @@ class AccessMiddleware(BaseMiddleware):
|
||||
return
|
||||
|
||||
if message.chat.id != admin_id:
|
||||
await message.answer("Владелец бота ограничил доступ к этому функционалу 😞")
|
||||
await message.answer(_("Владелец бота ограничил доступ к этому функционалу 😞"))
|
||||
raise CancelHandler()
|
||||
|
||||
async def on_process_callback_query(self, call: types.CallbackQuery, data: dict):
|
||||
@ -48,5 +49,5 @@ class AccessMiddleware(BaseMiddleware):
|
||||
return
|
||||
|
||||
if call.message.chat.id != admin_id:
|
||||
await call.answer("Владелец бота ограничил доступ к этому функционалу😞")
|
||||
await call.answer(_("Владелец бота ограничил доступ к этому функционалу😞"))
|
||||
raise CancelHandler()
|
||||
|
13
poetry.lock
generated
13
poetry.lock
generated
@ -341,6 +341,14 @@ python-versions = ">=3.5"
|
||||
[package.extras]
|
||||
cli = ["click (>=5.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "python-gettext"
|
||||
version = "4.0"
|
||||
description = "Python Gettext po to mo file compiler."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "pytz"
|
||||
version = "2020.5"
|
||||
@ -393,7 +401,7 @@ multidict = ">=4.0"
|
||||
[metadata]
|
||||
lock-version = "1.1"
|
||||
python-versions = "^3.8"
|
||||
content-hash = "20aec5e4517c3e0bc03d4410544c1c898f0469c9bcfc4f4fecf4c405b1765ded"
|
||||
content-hash = "9151864c69f349148a36cc7551bb54fd240229eb2533e92b82a0f85a251a56f3"
|
||||
|
||||
[metadata.files]
|
||||
aerich = [
|
||||
@ -825,6 +833,9 @@ python-dotenv = [
|
||||
{file = "python-dotenv-0.19.2.tar.gz", hash = "sha256:a5de49a31e953b45ff2d2fd434bbc2670e8db5273606c1e737cc6b93eff3655f"},
|
||||
{file = "python_dotenv-0.19.2-py2.py3-none-any.whl", hash = "sha256:32b2bdc1873fd3a3c346da1c6db83d0053c3c62f28f1f38516070c4c8971b1d3"},
|
||||
]
|
||||
python-gettext = [
|
||||
{file = "python-gettext-4.0.tar.gz", hash = "sha256:626b501a51ac892fc3460cf550e60dca121f544eaa46eb69c90ce4682fc7ec02"},
|
||||
]
|
||||
pytz = [
|
||||
{file = "pytz-2020.5-py2.py3-none-any.whl", hash = "sha256:16962c5fb8db4a8f63a26646d8886e9d769b6c511543557bc84e9569fb9a9cb4"},
|
||||
{file = "pytz-2020.5.tar.gz", hash = "sha256:180befebb1927b16f6b57101720075a984c019ac16b1b7575673bea42c6c3da5"},
|
||||
|
@ -15,6 +15,7 @@ pycrypto = "^2.6.1"
|
||||
aioredis = "1.3"
|
||||
aerich = "0.5.x"
|
||||
tortoise-orm = {extras = ["asyncpg"], version = "^0.18.1"}
|
||||
python-gettext = "^4.0"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
flake8 = "^4.0.1"
|
||||
|
1
refresh_lang.sh
Normal file
1
refresh_lang.sh
Normal file
@ -0,0 +1 @@
|
||||
/usr/lib/python3.10/Tools/i18n/pygettext.py -d chinese -o locales/zh/LC_MESSAGES/olgram.pot olgram/ server/
|
@ -12,6 +12,7 @@ import logging
|
||||
import typing as ty
|
||||
from olgram.settings import ServerSettings
|
||||
from olgram.models.models import Bot, GroupChat, BannedUser
|
||||
from locales.locale import _
|
||||
from server.inlines import inline_handler
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
@ -36,18 +37,18 @@ def _thread_uniqie_id(bot_id: int, chat_id: int) -> str:
|
||||
|
||||
|
||||
def _on_security_policy(message: types.Message, bot):
|
||||
text = "<b>Политика конфиденциальности</b>\n\n" \
|
||||
"Этот бот не хранит ваши сообщения, имя пользователя и @username. При отправке сообщения (кроме команд " \
|
||||
"/start и /security_policy) ваш идентификатор пользователя записывается в кеш на некоторое время и потом " \
|
||||
"удаляется из кеша. Этот идентификатор используется только для общения с оператором; боты Olgram " \
|
||||
"не делают массовых рассылок.\n\n"
|
||||
text = _("<b>Политика конфиденциальности</b>\n\n" \
|
||||
"Этот бот не хранит ваши сообщения, имя пользователя и @username. При отправке сообщения (кроме команд " \
|
||||
"/start и /security_policy) ваш идентификатор пользователя записывается в кеш на некоторое время и потом " \
|
||||
"удаляется из кеша. Этот идентификатор используется только для общения с оператором; боты Olgram " \
|
||||
"не делают массовых рассылок.\n\n")
|
||||
if bot.enable_additional_info:
|
||||
text += "При отправке сообщения (кроме команд /start и /security_policy) оператор <b>видит</b> ваши имя " \
|
||||
"пользователя, @username и идентификатор пользователя в силу настроек, которые оператор указал при " \
|
||||
"создании бота."
|
||||
text += _("При отправке сообщения (кроме команд /start и /security_policy) оператор <b>видит</b> ваши имя " \
|
||||
"пользователя, @username и идентификатор пользователя в силу настроек, которые оператор указал при " \
|
||||
"создании бота.")
|
||||
else:
|
||||
text += "В зависимости от ваших настроек конфиденциальности Telegram, оператор может видеть ваш username, " \
|
||||
"имя пользователя и другую информацию."
|
||||
text += _("В зависимости от ваших настроек конфиденциальности Telegram, оператор может видеть ваш username, " \
|
||||
"имя пользователя и другую информацию.")
|
||||
|
||||
return SendMessage(chat_id=message.chat.id,
|
||||
text=text,
|
||||
@ -57,7 +58,7 @@ def _on_security_policy(message: types.Message, bot):
|
||||
async def send_user_message(message: types.Message, super_chat_id: int, bot):
|
||||
"""Переслать сообщение от пользователя, добавлять к нему user info при необходимости"""
|
||||
if bot.enable_additional_info:
|
||||
user_info = "Сообщение от пользователя "
|
||||
user_info = _("Сообщение от пользователя ")
|
||||
user_info += message.from_user.full_name
|
||||
if message.from_user.username:
|
||||
user_info += " | @" + message.from_user.username
|
||||
@ -84,7 +85,7 @@ async def handle_user_message(message: types.Message, super_chat_id: int, bot):
|
||||
banned = await bot.banned_users.filter(telegram_id=message.chat.id)
|
||||
if banned:
|
||||
return SendMessage(chat_id=message.chat.id,
|
||||
text="Вы заблокированы в этом боте")
|
||||
text=_("Вы заблокированы в этом боте"))
|
||||
|
||||
# Пересылаем сообщение в супер-чат
|
||||
if is_super_group and bot.enable_threads:
|
||||
@ -124,28 +125,28 @@ async def handle_operator_message(message: types.Message, super_chat_id: int, bo
|
||||
chat_id = message.reply_to_message.forward_from_chat
|
||||
if not chat_id:
|
||||
return SendMessage(chat_id=message.chat.id,
|
||||
text="<i>Невозможно переслать сообщение: автор не найден "
|
||||
"(сообщение слишком старое?)</i>",
|
||||
text=_("<i>Невозможно переслать сообщение: автор не найден (сообщение слишком "
|
||||
"старое?)</i>"),
|
||||
parse_mode="HTML")
|
||||
chat_id = int(chat_id)
|
||||
|
||||
if message.text == "/ban":
|
||||
user, _ = await BannedUser.get_or_create(telegram_id=chat_id, bot=bot)
|
||||
user, create = await BannedUser.get_or_create(telegram_id=chat_id, bot=bot)
|
||||
await user.save()
|
||||
return SendMessage(chat_id=message.chat.id, text="Пользователь заблокирован")
|
||||
return SendMessage(chat_id=message.chat.id, text=_("Пользователь заблокирован"))
|
||||
|
||||
if message.text == "/unban":
|
||||
banned_user = await bot.banned_users.filter(telegram_id=chat_id).first()
|
||||
if not banned_user:
|
||||
return SendMessage(chat_id=message.chat.id, text="Пользователь не был забанен")
|
||||
return SendMessage(chat_id=message.chat.id, text=_("Пользователь не был забанен"))
|
||||
else:
|
||||
await banned_user.delete()
|
||||
return SendMessage(chat_id=message.chat.id, text="Пользователь разбанен")
|
||||
return SendMessage(chat_id=message.chat.id, text=_("Пользователь разбанен"))
|
||||
|
||||
try:
|
||||
await message.copy_to(chat_id)
|
||||
except (exceptions.MessageError, exceptions.Unauthorized):
|
||||
await message.reply("<i>Невозможно переслать сообщение (автор заблокировал бота?)</i>",
|
||||
await message.reply(_("<i>Невозможно переслать сообщение (автор заблокировал бота?)</i>"),
|
||||
parse_mode="HTML")
|
||||
return
|
||||
|
||||
|
@ -5,6 +5,7 @@ from aiohttp import web
|
||||
from asyncio import get_event_loop
|
||||
import ssl
|
||||
from olgram.settings import ServerSettings
|
||||
from locales.locale import _
|
||||
from .custom import CustomRequestHandler
|
||||
|
||||
import logging
|
||||
@ -37,8 +38,8 @@ async def register_token(bot: Bot) -> bool:
|
||||
res = await a_bot.set_webhook(url_for_bot(bot), certificate=certificate, drop_pending_updates=True,
|
||||
max_connections=10)
|
||||
await a_bot.set_my_commands([
|
||||
BotCommand("/start", "(Пере)запустить бота"),
|
||||
BotCommand("/security_policy", "Политика конфиденциальности")
|
||||
BotCommand("/start", _("(Пере)запустить бота")),
|
||||
BotCommand("/security_policy", _("Политика конфиденциальности"))
|
||||
])
|
||||
|
||||
await a_bot.session.close()
|
||||
|
Loading…
Reference in New Issue
Block a user