diff --git a/src/__main__.py b/src/__main__.py
index 35a7fa1..ff7f86c 100644
--- a/src/__main__.py
+++ b/src/__main__.py
@@ -5,6 +5,7 @@
from telegram.ext import ApplicationBuilder, CallbackQueryHandler, CommandHandler, MessageHandler, filters
+from src.errors_solver import native_error_handler
from src.handlers import (
handler_auth,
handler_button_browser,
@@ -16,7 +17,6 @@
handler_start,
handler_unknown_command,
)
-from src.errors_solver import native_error_handler
from src.settings import Settings
diff --git a/src/answers.py b/src/answers.py
index c598a91..87d9aba 100644
--- a/src/answers.py
+++ b/src/answers.py
@@ -15,47 +15,59 @@ class Answers:
kb_print_side = '📎 Односторонняя печать'
kb_print_two_side = '🖇 Двухсторонняя печать'
hello = '👋🏻 Привет! Я телеграм-бот бесплатного принтера.\n' 'Отправьте PDF файл и получите PIN для печати.'
- help = ('Я телеграм-бот бесплатного принтера профкома студентов физического факультета МГУ!\n\n'
- '❔ Отправьте PDF файл и получите PIN для печати. '
- 'Поддерживаются только .pdf файлы не более 3МБ.\n'
- 'С этим PIN необходимо подойти к принтеру и ввести его в терминал печати. '
- 'Либо отсканировать QR-код на принтере с помощью кнопки. После этого начнётся печать.'
- '\n\n'
- '⚙️ Настройки печати можно изменять после отправки файла, они сохраняются автоматически. '
- 'В момент печати используются самые последние настройки.\n\n'
- '❗️ Файлы, которые вы отправляете через бота, будут храниться в течение нескольких месяцев'
- ' на сервере в Москве, а также в этом чате Telegram.\n'
- 'Доступ к файлам имеет узкий круг лиц, ответственных за работоспособность сервиса печати.\n'
- 'Мы НЕ рекомендуем использовать данный сервис для печати конфиденциальных документов!\n\n'
- '💻 Бот разработан группой программистов профкома, '
- 'как и приложение Твой ФФ! '
- 'В приложении вы сможете найти больше настроек печати, расписание и много других возможностей.\n'
- 'Так же есть бот для печати ВКонтакте.')
+ help = (
+ 'Я телеграм-бот бесплатного принтера профкома студентов физического факультета МГУ!\n\n'
+ '❔ Отправьте PDF файл и получите PIN для печати. '
+ 'Поддерживаются только .pdf файлы не более 3МБ.\n'
+ 'С этим PIN необходимо подойти к принтеру и ввести его в терминал печати. '
+ 'Либо отсканировать QR-код на принтере с помощью кнопки. После этого начнётся печать.'
+ '\n\n'
+ '⚙️ Настройки печати можно изменять после отправки файла, они сохраняются автоматически. '
+ 'В момент печати используются самые последние настройки.\n\n'
+ '❗️ Файлы, которые вы отправляете через бота, будут храниться в течение нескольких месяцев'
+ ' на сервере в Москве, а также в этом чате Telegram.\n'
+ 'Доступ к файлам имеет узкий круг лиц, ответственных за работоспособность сервиса печати.\n'
+ 'Мы НЕ рекомендуем использовать данный сервис для печати конфиденциальных документов!\n\n'
+ '💻 Бот разработан группой программистов профкома, '
+ 'как и приложение Твой ФФ! '
+ 'В приложении вы сможете найти больше настроек печати, расписание и много других возможностей.\n'
+ 'Так же есть бот для печати ВКонтакте.'
+ )
- val_fail = ('⚠️ Проверка не пройдена. Удостоверьтесь что вы состоите в профсоюзе и правильно ввели данные.\n\n'
- 'Введите фамилию и номер профсоюзного билета в формате:\n\nИванов\n1234567')
+ val_fail = (
+ '⚠️ Проверка не пройдена. Удостоверьтесь что вы состоите в профсоюзе и правильно ввели данные.\n\n'
+ 'Введите фамилию и номер профсоюзного билета в формате:\n\nИванов\n1234567'
+ )
val_pass = '🥳 Поздравляю! Проверка пройдена и данные сохранены для этого телеграм-аккаунта. Можете присылать pdf.'
- val_need = ('👤 Для использования принтера необходимо авторизоваться.\n'
- 'Отправьте фамилию и номер профсоюзного билета в формате:\n\nИванов\n1234567')
- val_update_fail = ('Сообщение не распознано.\nЧтобы открыть инструкцию введите: /help\n'
- 'Для того чтобы обновить данные авторизации введите фамилию и номер'
- 'профсоюзного билета в формате:\n\nИванов\n1234567')
+ val_need = (
+ '👤 Для использования принтера необходимо авторизоваться.\n'
+ 'Отправьте фамилию и номер профсоюзного билета в формате:\n\nИванов\n1234567'
+ )
+ val_update_fail = (
+ 'Сообщение не распознано.\nЧтобы открыть инструкцию введите: /help\n'
+ 'Для того чтобы обновить данные авторизации введите фамилию и номер'
+ 'профсоюзного билета в формате:\n\nИванов\n1234567'
+ )
val_update_pass = '🥳 Поздравляю! Проверка пройдена и данные обновлены.'
val_addition = '\n\nНо для начала нужно авторизоваться. Нажмите на кнопку ниже:'
- val_info = ('Вы авторизованы!\n'
- 'Ваш id в телеграм: {}
\n'
- 'Фамилия: {}
\n'
- 'Номер профсоюзного билета: {}
')
- unknown_command = ('Неизвестная команда.\n'
- 'У бота лишь три команды: /start /help /auth')
+ val_info = (
+ 'Вы авторизованы!\n'
+ 'Ваш id в телеграм: {}
\n'
+ 'Фамилия: {}
\n'
+ 'Номер профсоюзного билета: {}
'
+ )
+ unknown_command = 'Неизвестная команда.\n' 'У бота лишь три команды: /start /help /auth'
only_pdf = 'Документы на печать принимаются только в формате PDF'
- doc_not_accepted = ('⚠️ Документ не принят, сначала авторизуйтесь.\n'
- 'Отправьте фамилию и номер профсоюзного билета в формате:\n\nИванов\n1234567')
- file_size_error = ('⚠️ Принимаются только файлы размером меньше 3 MB.\n'
- 'Файл {} не принят.')
- send_to_print = ('✅ Файл {} успешно загружен. Для печати подойдите к принтеру и введите PIN:\n\n'
- '{}\n\n'
- 'Для быстрой печати отсканируйте QR код на экране принтера.')
+ doc_not_accepted = (
+ '⚠️ Документ не принят, сначала авторизуйтесь.\n'
+ 'Отправьте фамилию и номер профсоюзного билета в формате:\n\nИванов\n1234567'
+ )
+ file_size_error = '⚠️ Принимаются только файлы размером меньше 3 MB.\n' 'Файл {} не принят.'
+ send_to_print = (
+ '✅ Файл {} успешно загружен. Для печати подойдите к принтеру и введите PIN:\n\n'
+ '{}\n\n'
+ 'Для быстрой печати отсканируйте QR код на экране принтера.'
+ )
qr_print = '{}{}'
settings_warning = 'Настройки сохраняются автоматически.'
settings_change_fail = 'Что-то сломалось, настройки печати не изменены, попробуйте через пару минут.'
diff --git a/src/errors_solver.py b/src/errors_solver.py
index 4026c5c..958d70f 100644
--- a/src/errors_solver.py
+++ b/src/errors_solver.py
@@ -12,6 +12,7 @@
from src.answers import Answers
+
ans = Answers()
diff --git a/src/handlers.py b/src/handlers.py
index 83685f2..46bdc5a 100644
--- a/src/handlers.py
+++ b/src/handlers.py
@@ -19,16 +19,17 @@
from src.log_formatter import log_actor, log_formatter
from src.settings import Settings
+
ans = Answers()
settings = Settings()
-engine = create_engine(url=str(settings.DB_DSN), pool_pre_ping=True, isolation_level="AUTOCOMMIT")
+engine = create_engine(url=str(settings.DB_DSN), pool_pre_ping=True, isolation_level='AUTOCOMMIT')
Session = sessionmaker(bind=engine)
@errors_solver
@log_formatter
async def handler_start(update: Update, context: ContextTypes.DEFAULT_TYPE):
- keyboard_base = [[InlineKeyboardButton(ans.about, callback_data="to_about")]]
+ keyboard_base = [[InlineKeyboardButton(ans.about, callback_data='to_about')]]
text, reply_markup = __change_message_by_auth(update, ans.hello, keyboard_base)
await update.message.reply_text(text=text, reply_markup=reply_markup, disable_web_page_preview=True)
@@ -36,7 +37,7 @@ async def handler_start(update: Update, context: ContextTypes.DEFAULT_TYPE):
@errors_solver
@log_formatter
async def handler_help(update: Update, context: ContextTypes.DEFAULT_TYPE):
- await update.message.reply_text(ans.help, disable_web_page_preview=True, parse_mode=ParseMode("HTML"))
+ await update.message.reply_text(ans.help, disable_web_page_preview=True, parse_mode=ParseMode('HTML'))
@errors_solver
@@ -46,25 +47,25 @@ async def handler_auth(update: Update, context: ContextTypes.DEFAULT_TYPE):
if requisites is None:
await update.message.reply_text(ans.val_need)
else:
- await update.message.reply_text(ans.val_info.format(*requisites), parse_mode=ParseMode("HTML"))
+ await update.message.reply_text(ans.val_info.format(*requisites), parse_mode=ParseMode('HTML'))
@errors_solver
@log_formatter
async def handler_button_browser(update: Update, context: CallbackContext) -> None:
- if update.callback_query.data == "to_hello":
- keyboard_base = [[InlineKeyboardButton(ans.about, callback_data="to_about")]]
+ if update.callback_query.data == 'to_hello':
+ keyboard_base = [[InlineKeyboardButton(ans.about, callback_data='to_about')]]
text, reply_markup = __change_message_by_auth(update, ans.hello, keyboard_base)
- elif update.callback_query.data == "to_about":
- keyboard_base = [[InlineKeyboardButton(ans.back, callback_data="to_hello")]]
+ elif update.callback_query.data == 'to_about':
+ keyboard_base = [[InlineKeyboardButton(ans.back, callback_data='to_hello')]]
text, reply_markup = __change_message_by_auth(update, ans.help, keyboard_base)
- elif update.callback_query.data == "to_auth":
- keyboard_base = [[InlineKeyboardButton(ans.back, callback_data="to_hello")]]
+ elif update.callback_query.data == 'to_auth':
+ keyboard_base = [[InlineKeyboardButton(ans.back, callback_data='to_hello')]]
text, reply_markup = ans.val_need, InlineKeyboardMarkup(keyboard_base)
- elif update.callback_query.data.startswith("print_"):
+ elif update.callback_query.data.startswith('print_'):
await __print_settings_solver(update, context)
return
@@ -75,7 +76,7 @@ async def handler_button_browser(update: Update, context: CallbackContext) -> No
text=text,
reply_markup=reply_markup,
disable_web_page_preview=True,
- parse_mode=ParseMode("HTML"),
+ parse_mode=ParseMode('HTML'),
)
@@ -91,39 +92,39 @@ async def handler_print(update: Update, context: ContextTypes.DEFAULT_TYPE):
requisites = __auth(update)
if requisites is None:
await context.bot.send_message(chat_id=update.message.chat.id, text=ans.doc_not_accepted)
- logging.warning(f"{log_actor(update)} try print with no auth")
+ logging.warning(f'{log_actor(update)} try print with no auth')
return
try:
filebytes, filename = await __get_attachments(update, context)
- logging.info(f"{log_actor(update)} get attachments OK")
+ logging.info(f'{log_actor(update)} get attachments OK')
except FileSizeError:
await update.message.reply_text(
text=ans.file_size_error.format(update.message.document.file_name),
reply_to_message_id=update.message.id,
- parse_mode=ParseMode("HTML"),
+ parse_mode=ParseMode('HTML'),
)
- logging.warning(f"{log_actor(update)} get attachments FileSizeError")
+ logging.warning(f'{log_actor(update)} get attachments FileSizeError')
return
except TelegramError:
await update.message.reply_text(text=ans.download_error, reply_to_message_id=update.message.id)
- logging.warning(f"{log_actor(update)} get attachments download_error")
+ logging.warning(f'{log_actor(update)} get attachments download_error')
return
r = requests.post(
- settings.PRINT_URL + "/file",
- json={"surname": requisites[1], "number": requisites[2], "filename": filename, "source": "tgbot"},
+ settings.PRINT_URL + '/file',
+ json={'surname': requisites[1], 'number': requisites[2], 'filename': filename, 'source': 'tgbot'},
)
if r.status_code == 200:
- pin = r.json()["pin"]
+ pin = r.json()['pin']
files = {
- "file": (
+ 'file': (
filename,
filebytes.getvalue(),
- "application/pdf",
- {"Expires": "0"},
+ 'application/pdf',
+ {'Expires': '0'},
)
}
- rfile = requests.post(settings.PRINT_URL + "/file/" + pin, files=files)
+ rfile = requests.post(settings.PRINT_URL + '/file/' + pin, files=files)
if rfile.status_code == 200:
reply_markup = InlineKeyboardMarkup(
[
@@ -133,7 +134,7 @@ async def handler_print(update: Update, context: ContextTypes.DEFAULT_TYPE):
web_app=WebAppInfo(ans.qr_print.format(settings.PRINT_URL_QR, pin)),
)
],
- [InlineKeyboardButton(ans.kb_print, callback_data=f"print_settings_{pin}")],
+ [InlineKeyboardButton(ans.kb_print, callback_data=f'print_settings_{pin}')],
]
)
await update.message.reply_text(
@@ -141,9 +142,9 @@ async def handler_print(update: Update, context: ContextTypes.DEFAULT_TYPE):
reply_markup=reply_markup,
reply_to_message_id=update.message.id,
disable_web_page_preview=True,
- parse_mode=ParseMode("HTML"),
+ parse_mode=ParseMode('HTML'),
)
- logging.info(f"{log_actor(update)} print success")
+ logging.info(f'{log_actor(update)} print success')
marketing.print_success(
tg_id=update.message.chat.id,
surname=requisites[1],
@@ -155,16 +156,16 @@ async def handler_print(update: Update, context: ContextTypes.DEFAULT_TYPE):
await update.message.reply_text(
text=ans.file_size_error.format(update.message.document.file_name),
reply_to_message_id=update.message.id,
- parse_mode=ParseMode("HTML"),
+ parse_mode=ParseMode('HTML'),
)
- logging.warning(f"{log_actor(update)} print api 413 SizeErr")
+ logging.warning(f'{log_actor(update)} print api 413 SizeErr')
return
await context.bot.send_message(
chat_id=update.effective_user.id,
text=ans.print_err,
- parse_mode=ParseMode("HTML"),
+ parse_mode=ParseMode('HTML'),
)
- logging.warning(f"{log_actor(update)} print unknown error")
+ logging.warning(f'{log_actor(update)} print unknown error')
@errors_solver
@@ -186,22 +187,22 @@ async def handler_register(update: Update, context: ContextTypes.DEFAULT_TYPE):
text = update.message.text
chat_id = update.message.chat.id
- if text is None or len(text.split("\n")) != 2:
+ if text is None or len(text.split('\n')) != 2:
with Session() as session:
if session.query(TgUser).filter(TgUser.tg_id == chat_id).one_or_none() is None:
await context.bot.send_message(chat_id=chat_id, text=ans.val_need)
- logging.warning(f"{log_actor(update)} val_need")
+ logging.warning(f'{log_actor(update)} val_need')
else:
await context.bot.send_message(chat_id=chat_id, text=ans.val_update_fail)
- logging.warning(f"{log_actor(update)} val_update_fail")
+ logging.warning(f'{log_actor(update)} val_update_fail')
return
- if len(text.split("\n")) == 2:
- surname = text.split("\n")[0].strip()
- number = text.split("\n")[1].strip()
+ if len(text.split('\n')) == 2:
+ surname = text.split('\n')[0].strip()
+ number = text.split('\n')[1].strip()
r = requests.get(
- settings.PRINT_URL + "/is_union_member",
+ settings.PRINT_URL + '/is_union_member',
params=dict(surname=surname, v=1, number=number),
)
with Session() as session:
@@ -211,39 +212,39 @@ async def handler_register(update: Update, context: ContextTypes.DEFAULT_TYPE):
session.commit()
await context.bot.send_message(chat_id=chat_id, text=ans.val_pass)
marketing.register(tg_id=chat_id, surname=surname, number=number)
- logging.info(f"{log_actor(update)} register OK: {surname} {number}")
+ logging.info(f'{log_actor(update)} register OK: {surname} {number}')
return True
elif r.json() and data is not None:
data.surname = surname
data.number = number
await context.bot.send_message(chat_id=chat_id, text=ans.val_update_pass)
marketing.re_register(tg_id=chat_id, surname=surname, number=number)
- logging.info(f"{log_actor(update)} register repeat OK: {surname} {number}")
+ logging.info(f'{log_actor(update)} register repeat OK: {surname} {number}')
return True
elif r.json() is False:
await context.bot.send_message(chat_id=chat_id, text=ans.val_fail)
marketing.register_exc_wrong(tg_id=chat_id, surname=surname, number=number)
- logging.info(f"{log_actor(update)} register val_fail: {surname} {number}")
+ logging.info(f'{log_actor(update)} register val_fail: {surname} {number}')
async def __print_settings_solver(update: Update, context: CallbackContext):
- _, button, pin = update.callback_query.data.split("_")
+ _, button, pin = update.callback_query.data.split('_')
- r = requests.get(settings.PRINT_URL + f"""/file/{pin}""")
+ r = requests.get(settings.PRINT_URL + f'''/file/{pin}''')
if r.status_code == 200:
- options = r.json()["options"]
+ options = r.json()['options']
else:
await update.callback_query.message.reply_text(ans.settings_change_fail)
return
- if button == "copies":
- options["copies"] = options["copies"] % 5 + 1
- elif button == "twosided":
- options["two_sided"] = not options["two_sided"]
+ if button == 'copies':
+ options['copies'] = options['copies'] % 5 + 1
+ elif button == 'twosided':
+ options['two_sided'] = not options['two_sided']
else:
await context.bot.answer_callback_query(update.callback_query.id, ans.settings_warning)
- r = requests.patch(settings.PRINT_URL + f"""/file/{pin}""", json={"options": options})
+ r = requests.patch(settings.PRINT_URL + f'''/file/{pin}''', json={'options': options})
if r.status_code != 200:
await update.callback_query.message.reply_text(ans.settings_change_fail)
return
@@ -258,13 +259,13 @@ async def __print_settings_solver(update: Update, context: CallbackContext):
[
InlineKeyboardButton(
f'{ans.kb_print_copies} {options["copies"]}',
- callback_data=f"print_copies_{pin}",
+ callback_data=f'print_copies_{pin}',
)
],
[
InlineKeyboardButton(
- ans.kb_print_two_side if options["two_sided"] else ans.kb_print_side,
- callback_data=f"print_twosided_{pin}",
+ ans.kb_print_two_side if options['two_sided'] else ans.kb_print_side,
+ callback_data=f'print_twosided_{pin}',
)
],
]
@@ -277,7 +278,7 @@ def __auth(update):
tg_user: TgUser | None = session.query(TgUser).filter(TgUser.tg_id == update.effective_user.id).one_or_none()
if tg_user is not None:
r = requests.get(
- settings.PRINT_URL + "/is_union_member",
+ settings.PRINT_URL + '/is_union_member',
params=dict(surname=tg_user.surname, number=tg_user.number, v=1),
)
if r.json():
@@ -287,7 +288,7 @@ def __auth(update):
def __change_message_by_auth(update, text, keyboard):
if __auth(update) is None:
text += ans.val_addition
- keyboard.append([InlineKeyboardButton(ans.auth, callback_data="to_auth")])
+ keyboard.append([InlineKeyboardButton(ans.auth, callback_data='to_auth')])
return text, InlineKeyboardMarkup(keyboard)