-
Notifications
You must be signed in to change notification settings - Fork 0
/
tg_quiz_bot.py
122 lines (101 loc) · 4.21 KB
/
tg_quiz_bot.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
from enum import Enum
from environs import Env
from functools import partial
import sqlite3
from telegram import Update, KeyboardButton, ReplyKeyboardMarkup, ReplyKeyboardRemove
from telegram.ext import Updater, CommandHandler, MessageHandler, Filters, CallbackContext, ConversationHandler
from quiz_utils import check_answer
from db_functions import *
from cli_interface import create_parser
STAGE = Enum('Stage', ['QUIZ'])
def start(update: Update, context: CallbackContext):
"""Send a message when the command /start is issued."""
user = update.effective_user
context.user_data['score'] = 0
keyboard = [
[KeyboardButton('Новый вопрос'), KeyboardButton('Сдаться')],
[KeyboardButton('Мой счет')]
]
reply_markup = ReplyKeyboardMarkup(keyboard)
update.message.reply_markdown_v2(
fr'Hi {user.mention_markdown_v2()}\!',
reply_markup=reply_markup,
)
return STAGE['QUIZ'].value
def cancel(update, _):
update.message.reply_text('Bye!', reply_markup=ReplyKeyboardRemove())
return ConversationHandler.END
def process_question(update, context, db_connection):
chat_id = update.message.chat.id
question_id, question, answer = get_question(db_connection)
insert_into_user_answers(db_connection, chat_id, question_id, 0)
update.message.reply_text(f'{question}')
context.user_data['answer'] = answer
context.user_data['question_id'] = question_id
return STAGE['QUIZ'].value
def surrunder(update, context):
text = 'Cначала ответьте на новый вопрос'
if 'answer' in context.user_data:
answer = context.user_data['answer']
text = f'Верный ответ: {answer}'
update.message.reply_text(text)
return STAGE['QUIZ'].value
def handle_solution_attempt(update, context):
correct_answer = context.user_data['answer']
question_id = context.user_data['question_id']
user_answer = update.message.text
chat_id = update.message.chat.id
keyboard = [
[KeyboardButton('Новый вопрос'), KeyboardButton('Сдаться')],
[KeyboardButton('Мой счет')]
]
reply_markup = ReplyKeyboardMarkup(keyboard)
if check_answer(user_answer, correct_answer):
text = 'Правильно\! Поздравляю\! Для следующего вопроса нажми *«Новый вопрос»*'
update_user_answer_table(connection, chat_id, question_id)
context.user_data['answer'] = ''
else:
text = 'Неправильно… Попробуешь ещё раз?'
update.message.reply_markdown_v2(
text,
reply_markup=reply_markup,
)
return STAGE['QUIZ'].value
def send_score(update, context, connection):
chat_id = update.message.chat.id
score = get_score(connection, chat_id)
keyboard = [
[KeyboardButton('Новый вопрос'), KeyboardButton('Сдаться')],
[KeyboardButton('Мой счет')]
]
reply_markup = ReplyKeyboardMarkup(keyboard)
update.message.reply_markdown_v2(
f'Ваш счет: {score}',
reply_markup=reply_markup,
)
if __name__ == '__main__':
env = Env()
env.read_env()
parser = create_parser()
args = parser.parse_args()
bot_token = env('TG_TOKEN')
connection = sqlite3.connect(args.database, check_same_thread=False)
handle_new_question_request = partial(process_question, db_connection=connection)
handle_send_score = partial(send_score, connection=connection)
updater = Updater(bot_token)
dispatcher = updater.dispatcher
conv_handler = ConversationHandler(
entry_points=[CommandHandler('start', start)],
states={
STAGE['QUIZ'].value: [
MessageHandler(Filters.regex('Новый вопрос.*'), handle_new_question_request),
MessageHandler(Filters.regex('[Сc]даться'), surrunder),
MessageHandler(Filters.regex('Мой счет'), handle_send_score),
MessageHandler(Filters.text, handle_solution_attempt),
],
},
fallbacks=[CommandHandler('cancel', cancel)]
)
dispatcher.add_handler(conv_handler)
updater.start_polling()
updater.idle()