Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 27 additions & 6 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,27 @@
auth.ini
userdata
logs*.txt
*.log
*.logs
.env
# Text backup files
*.bak

# Database
*.sqlite3
*.db

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
tests/.cache/

# virtualenv
venv/
static/**

# PyCharm
.idea

# dotenv
.env

# CI/CD
.venv/
.wheels/
.core
2 changes: 0 additions & 2 deletions migrations/env.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
from logging.config import fileConfig

from alembic import context
from sqlalchemy import engine_from_config, pool

from src.db import Base
from src.settings import Settings


# this is the Alembic Config object, which provides
# access to the values within the .ini file in use.
config = context.config
Expand Down
5 changes: 3 additions & 2 deletions migrations/versions/14de3a5684ea_bigint.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
"""bigint

Revision ID: 14de3a5684ea
Expand All @@ -9,7 +9,6 @@
import sqlalchemy as sa
from alembic import op


# revision identifiers, used by Alembic.
revision = "14de3a5684ea"
down_revision = "bd42bc6088a1"
Expand All @@ -19,7 +18,9 @@

def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.execute("ALTER TABLE tg_user ALTER COLUMN tg_id TYPE bigint USING tg_id::bigint;")
op.execute(
"ALTER TABLE tg_user ALTER COLUMN tg_id TYPE bigint USING tg_id::bigint;"
)
# ### end Alembic commands ###


Expand Down
3 changes: 1 addition & 2 deletions migrations/versions/56584d8792af_init.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
"""Init

Revision ID: 56584d8792af
Revises:
Revises:
Create Date: 2023-01-12 18:59:05.426265

"""

import sqlalchemy as sa
from alembic import op


# revision identifiers, used by Alembic.
revision = "56584d8792af"
down_revision = None
Expand Down
1 change: 0 additions & 1 deletion migrations/versions/bd42bc6088a1_nullable.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
"""nullable

Revision ID: bd42bc6088a1
Expand All @@ -9,7 +9,6 @@
import sqlalchemy as sa
from alembic import op


# revision identifiers, used by Alembic.
revision = "bd42bc6088a1"
down_revision = "56584d8792af"
Expand Down
54 changes: 31 additions & 23 deletions src/__main__.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,22 @@
# Marakulin Andrey https://github.com/Annndruha
# 2023

import asyncio
import logging

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,
handler_help,
handler_mismatch_doctype,
handler_other_messages,
handler_print,
handler_register,
handler_start,
handler_unknown_command,
)
from src.settings import Settings

from src.handlers import (handler_auth, handler_button_browser, handler_help,
handler_mismatch_doctype, handler_other_messages,
handler_print, handler_register, handler_start,
handler_unknown_command)
from src.settings import get_settings, sync_from_server
from telegram.ext import (ApplicationBuilder, CallbackQueryHandler,
CommandHandler, MessageHandler, filters)

tg_log_handler = logging.FileHandler("tgbot_telegram_updater.log")
tg_log_handler.setFormatter(logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s"))
tg_log_handler.setFormatter(
logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
)
tg_logger = logging.getLogger("telegram.ext._updater")
tg_logger.propagate = False
tg_logger.addHandler(tg_log_handler)
Expand All @@ -35,16 +30,29 @@
)

if __name__ == "__main__":
settings = Settings()
asyncio.run(sync_from_server())
settings = get_settings()
application = ApplicationBuilder().token(settings.BOT_TOKEN).build()
application.add_handler(CallbackQueryHandler(handler_button_browser))
application.add_handler(CommandHandler("start", handler_start, filters=filters.UpdateType.MESSAGE))
application.add_handler(CommandHandler("help", handler_help, filters=filters.UpdateType.MESSAGE))
application.add_handler(CommandHandler("auth", handler_auth, filters=filters.UpdateType.MESSAGE))
application.add_handler(
CommandHandler("start", handler_start, filters=filters.UpdateType.MESSAGE)
)
application.add_handler(
CommandHandler("help", handler_help, filters=filters.UpdateType.MESSAGE)
)
application.add_handler(
CommandHandler("auth", handler_auth, filters=filters.UpdateType.MESSAGE)
)
application.add_handler(MessageHandler(filters.COMMAND, handler_unknown_command))
application.add_handler(MessageHandler(filters.Document.PDF, handler_print))
application.add_handler(MessageHandler(filters.Document.ALL, handler_mismatch_doctype))
application.add_handler(MessageHandler(filters.UpdateType.MESSAGE & filters.TEXT, handler_register))
application.add_handler(MessageHandler(filters.UpdateType.MESSAGE, handler_other_messages))
application.add_handler(
MessageHandler(filters.Document.ALL, handler_mismatch_doctype)
)
application.add_handler(
MessageHandler(filters.UpdateType.MESSAGE & filters.TEXT, handler_register)
)
application.add_handler(
MessageHandler(filters.UpdateType.MESSAGE, handler_other_messages)
)
application.add_error_handler(native_error_handler)
application.run_polling()
129 changes: 74 additions & 55 deletions src/answers.py
Original file line number Diff line number Diff line change
@@ -1,80 +1,99 @@
# Marakulin Andrey https://github.com/Annndruha
# 2023

from dataclasses import dataclass

from src.settings import get_settings

settings = get_settings()


@dataclass
class Answers:
auth = '🔑 Авторизация'
about = '📄 Описание'
back = '◀️ Назад'
qr = '📷 Печать по QR'
kb_print = '⚙️ Настройки печати'
kb_print_copies = '📑 Копий:'
kb_print_side = '📎 Односторонняя печать'
kb_print_two_side = '🖇 Двухсторонняя печать'
hello = '👋🏻 Привет! Я телеграм-бот бесплатного принтера.\n' 'Отправьте PDF файл и получите PIN для печати.'
auth = "🔑 Авторизация"
about = "📄 Описание"
back = "◀️ Назад"
qr = "📷 Печать по QR"
kb_print = "⚙️ Настройки печати"
kb_print_copies = "📑 Копий:"
kb_print_side = "📎 Односторонняя печать"
kb_print_two_side = "🖇 Двухсторонняя печать"
hello = (
"👋🏻 Привет! Я телеграм-бот бесплатного принтера.\n"
f"Отправьте файл формата {settings.CONTENT_TYPES} и получите PIN для печати."
)
help = (
'Я телеграм-бот бесплатного принтера профкома студентов физического факультета МГУ!\n\n'
'❔ Отправьте PDF файл и получите PIN для печати. '
'Поддерживаются <b>только .pdf</b> файлы не более 3МБ.\n'
'С этим PIN необходимо подойти к принтеру и ввести его в терминал печати. '
'Либо отсканировать QR-код на принтере с помощью кнопки. После этого начнётся печать.'
'\n\n'
'⚙️ Настройки печати можно изменять после отправки файла, они сохраняются автоматически. '
'В момент печати используются самые последние настройки.\n\n'
'❗️ Файлы, которые вы отправляете через бота, будут храниться в течение нескольких месяцев'
' на сервере в Москве, а также в этом чате Telegram.\n'
'Доступ к файлам имеет узкий круг лиц, ответственных за работоспособность сервиса печати.\n'
'Мы <b>НЕ</b> рекомендуем использовать данный сервис для печати конфиденциальных документов!\n\n'
'💻 Бот разработан группой программистов профкома, '
"Я телеграм-бот бесплатного принтера профкома студентов физического факультета МГУ!\n\n"
f"❔ Отправьте файл формата {settings.CONTENT_TYPES} и получите PIN для печати. "
f"Поддерживаются <b>только .pdf</b> файлы не более {settings.MAX_PDF_SIZE_MB} .\n"
"С этим PIN необходимо подойти к принтеру и ввести его в терминал печати. "
"Либо отсканировать QR-код на принтере с помощью кнопки. После этого начнётся печать."
"\n\n"
"⚙️ Настройки печати можно изменять после отправки файла, они сохраняются автоматически. "
"В момент печати используются самые последние настройки.\n\n"
"❗️ Файлы, которые вы отправляете через бота, будут храниться в течение нескольких месяцев"
" на сервере в Москве, а также в этом чате Telegram.\n"
"Доступ к файлам имеет узкий круг лиц, ответственных за работоспособность сервиса печати.\n"
"Мы <b>НЕ</b> рекомендуем использовать данный сервис для печати конфиденциальных документов!\n\n"
"💻 Бот разработан группой программистов профкома, "
'как и приложение <a href="https://app.profcomff.com">Твой ФФ!</a> '
'В приложении вы сможете найти больше настроек печати, расписание и много других возможностей.\n'
"В приложении вы сможете найти больше настроек печати, расписание и много других возможностей.\n"
'Так же есть <a href="https://vk.me/profcomff_print_bot">бот для печати ВКонтакте</a>.'
)

val_fail = (
'⚠️ Проверка не пройдена. Удостоверьтесь что вы состоите в профсоюзе и правильно ввели данные.\n\n'
'Введите фамилию и номер профсоюзного билета в формате:\n\nИванов\n1234567'
"⚠️ Проверка не пройдена. Удостоверьтесь что вы состоите в профсоюзе и правильно ввели данные.\n\n"
"Введите фамилию и номер профсоюзного билета в формате:\n\nИванов\n1234567"
)
val_pass = '🥳 Поздравляю! Проверка пройдена и данные сохранены для этого телеграм-аккаунта. Можете присылать pdf.'
val_pass = "🥳 Поздравляю! Проверка пройдена и данные сохранены для этого телеграм-аккаунта. Можете присылать pdf."
val_need = (
'👤 Для использования принтера необходимо авторизоваться.\n'
'Отправьте фамилию и номер профсоюзного билета в формате:\n\nИванов\n1234567'
"👤 Для использования принтера необходимо авторизоваться.\n"
"Отправьте фамилию и номер профсоюзного билета в формате:\n\nИванов\n1234567"
)
val_update_fail = (
'Сообщение не распознано.\nЧтобы открыть инструкцию введите: /help\n'
'Для того чтобы обновить данные авторизации введите фамилию и номер'
'профсоюзного билета в формате:\n\nИванов\n1234567'
"Сообщение не распознано.\nЧтобы открыть инструкцию введите: /help\n"
"Для того чтобы обновить данные авторизации введите фамилию и номер"
"профсоюзного билета в формате:\n\nИванов\n1234567"
)
val_update_pass = '🥳 Поздравляю! Проверка пройдена и данные обновлены.'
val_addition = '\n\nНо для начала нужно авторизоваться. Нажмите на кнопку ниже:'
val_update_pass = "🥳 Поздравляю! Проверка пройдена и данные обновлены."
val_addition = "\n\nНо для начала нужно авторизоваться. Нажмите на кнопку ниже:"
val_info = (
'Вы авторизованы!\n'
'Ваш id в телеграм: <code>{}</code>\n'
'Фамилия: <code>{}</code>\n'
'Номер профсоюзного билета: <code>{}</code>'
"Вы авторизованы!\n"
"Ваш id в телеграм: <code>{}</code>\n"
"Фамилия: <code>{}</code>\n"
"Номер профсоюзного билета: <code>{}</code>"
)
unknown_command = (
"Неизвестная команда.\n" "У бота лишь три команды: /start /help /auth"
)
unknown_command = 'Неизвестная команда.\n' 'У бота лишь три команды: /start /help /auth'
only_pdf = 'Документы на печать принимаются только в формате PDF'
only_pdf = "Документы на печать принимаются только в формате PDF"
doc_not_accepted = (
'⚠️ Документ не принят, сначала авторизуйтесь.\n'
'Отправьте фамилию и номер профсоюзного билета в формате:\n\nИванов\n1234567'
"⚠️ Документ не принят, сначала авторизуйтесь.\n"
"Отправьте фамилию и номер профсоюзного билета в формате:\n\nИванов\n1234567"
)
file_size_error = (
f"⚠️ Принимаются только файлы размером меньше {settings.MAX_PDF_SIZE_MB} MB.\n"
"Файл <b>{}</b> не принят."
)
file_size_error = '⚠️ Принимаются только файлы размером меньше 3 MB.\n' 'Файл <b>{}</b> не принят.'
send_to_print = (
'✅ Файл <b>{}</b> успешно загружен. Для печати подойдите к принтеру и введите PIN:\n\n'
'<b>{}</b>\n\n'
'Для быстрой печати отсканируйте QR код на экране принтера.'
"✅ Файл <b>{}</b> успешно загружен. Для печати подойдите к принтеру и введите PIN:\n\n"
"<b>{}</b>\n\n"
"Для быстрой печати отсканируйте QR код на экране принтера."
)
unreadable_file_error = (
"⚠️ Я не смог прочитать файл {}."
f"Проверьте его целостность и формат, я работаю только с {settings.CONTENT_TYPES}."
)
qr_print = "{}{}"
settings_warning = "Настройки сохраняются автоматически."
settings_change_fail = (
"Что-то сломалось, настройки печати не изменены, попробуйте через пару минут."
)
unknown_keyboard_payload = "Видимо бот обновился, выполните команду /start"
im_broken = "Глубоко внутри меня что-то сломалось...\nПопробуйте через пару минут."
download_error = "Ошибка получения файла, попробуйте позже."
print_err = "😵 Ошибка сервера печати. Попробуйте позже."
db_err = "😵 Ошибка базы данных. Попробуйте ещё раз, если не получилось, то попробуйте позже."
err_message_type = (
"Сообщение не распознано.\nЧтобы открыть инструкцию введите: /help"
)
unreadable_file_error = '⚠️ Я не смог прочитать файл {}. Проверьте его целостность и формат, я работаю только с pdf.'
qr_print = '{}{}'
settings_warning = 'Настройки сохраняются автоматически.'
settings_change_fail = 'Что-то сломалось, настройки печати не изменены, попробуйте через пару минут.'
unknown_keyboard_payload = 'Видимо бот обновился, выполните команду /start'
im_broken = 'Глубоко внутри меня что-то сломалось...\nПопробуйте через пару минут.'
download_error = 'Ошибка получения файла, попробуйте позже.'
print_err = '😵 Ошибка сервера печати. Попробуйте позже.'
db_err = '😵 Ошибка базы данных. Попробуйте ещё раз, если не получилось, то попробуйте позже.'
err_message_type = 'Сообщение не распознано.\nЧтобы открыть инструкцию введите: /help'
10 changes: 5 additions & 5 deletions src/errors_solver.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# Marakulin Andrey https://github.com/Annndruha
# 2023

Expand All @@ -6,13 +6,11 @@

import psycopg2
from sqlalchemy.exc import SQLAlchemyError
from src.answers import Answers
from telegram import Update
from telegram.error import TelegramError
from telegram.ext import ContextTypes

from src.answers import Answers


ans = Answers()


Expand All @@ -31,11 +29,13 @@
try:
await func(update, context)
except TelegramError as err:
logging.error(f'TelegramError: {str(err.message)}')
logging.error(f"TelegramError: {str(err.message)}")
except (SQLAlchemyError, psycopg2.Error) as err:
logging.error(err)
traceback.print_tb(err.__traceback__)
await context.bot.send_message(chat_id=update.message.chat.id, text=ans.db_err)
await context.bot.send_message(
chat_id=update.message.chat.id, text=ans.db_err
)
except Exception as err:
logging.error(err)
traceback.print_tb(err.__traceback__)
Expand Down
Loading
Loading