Source code for quizbot.bot.bot

"""
Telegram bot to create and attempt to quizzes.
"""

import logging
from telegram import BotCommand
from telegram.ext import ApplicationBuilder, CommandHandler, MessageHandler, ConversationHandler, filters
import quizbot.bot.create_quiz as createQuiz
import quizbot.bot.attempt_quiz as attemptQuiz
import quizbot.bot.edit_quiz as editQuiz
from quizbot.bot.config import get_config, get_session_factory
from quizbot.bot.persistence import SQLAlchemyPersistence


# Enable logging
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
                    level=logging.INFO)
logger = logging.getLogger(__name__)






[docs] async def error(update, context): """Log Errors caused by Updates.""" logger.warning('Update "%s" caused error "%s"', update, context.error)
[docs] def setup_bot(app): """Setups the handlers""" # Conversation if the user wants to create a quiz create_states = { 'ENTER_TYPE': [MessageHandler(filters.TEXT & ~filters.COMMAND, createQuiz.enter_type)], 'ENTER_QUESTION': [MessageHandler(filters.TEXT & ~filters.COMMAND, createQuiz.enter_question)], 'ENTER_ANSWER': [MessageHandler(filters.TEXT & ~filters.COMMAND, createQuiz.enter_answer)], 'ENTER_POSSIBLE_ANSWER': [MessageHandler(filters.TEXT & ~filters.COMMAND, createQuiz.enter_possible_answer)], 'ENTER_RANDOMNESS_QUESTION': [MessageHandler(filters.TEXT & ~filters.COMMAND, createQuiz.enter_randomness_question)], 'ENTER_RANDOMNESS_QUIZ': [MessageHandler(filters.TEXT & ~filters.COMMAND, createQuiz.enter_randomness_quiz)], 'ENTER_RESULT_AFTER_QUESTION': [MessageHandler(filters.TEXT & ~filters.COMMAND, createQuiz.enter_result_after_question)], 'ENTER_RESULT_AFTER_QUIZ': [MessageHandler(filters.TEXT & ~filters.COMMAND, createQuiz.enter_result_after_quiz)], 'ENTER_QUIZ_NAME': [MessageHandler(filters.TEXT & ~filters.COMMAND, createQuiz.enter_quiz_name)], 'ENTER_PASSWORD_CHOICE': [MessageHandler(filters.TEXT & ~filters.COMMAND, createQuiz.enter_password_choice)], 'ENTER_PASSWORD': [MessageHandler(filters.TEXT & ~filters.COMMAND, createQuiz.enter_password)], } create_handler = ConversationHandler( entry_points=[CommandHandler('create', createQuiz.start)], states=create_states, fallbacks=[CommandHandler('cancelCreate', createQuiz.cancel)], name="create_quiz", persistent=True, ) app.add_handler(create_handler) # Conversation if the user wants to attempt a quiz attempt_states = { 'ENTER_QUIZ': [MessageHandler(filters.TEXT & ~filters.COMMAND, attemptQuiz.enter_quiz)], 'ENTER_ANSWER': [MessageHandler(filters.TEXT & ~filters.COMMAND, attemptQuiz.enter_answer)], 'ENTER_PASSWORD': [MessageHandler(filters.TEXT & ~filters.COMMAND, attemptQuiz.enter_password)], } attempt_handler = ConversationHandler( entry_points=[CommandHandler('attempt', attemptQuiz.start)], states=attempt_states, fallbacks=[CommandHandler('cancelAttempt', attemptQuiz.cancel)], name="attempt_quiz", persistent=True, ) app.add_handler(attempt_handler) # Conversation about remove or renaming exisiting quiz edit_states = { 'ENTER_NAME': [MessageHandler(filters.TEXT & ~filters.COMMAND, editQuiz.enter_name_remove)], 'ENTER_OLD_NAME': [MessageHandler(filters.TEXT & ~filters.COMMAND, editQuiz.enter_old_name)], 'ENTER_NEW_NAME': [MessageHandler(filters.TEXT & ~filters.COMMAND, editQuiz.enter_new_name)] } edit_handler = ConversationHandler( entry_points=[CommandHandler('rename', editQuiz.start_rename), CommandHandler( 'remove', editQuiz.start_remove)], states=edit_states, fallbacks=[CommandHandler('cancelEdit', editQuiz.cancel_edit)], name="edit_quiz", persistent=True, ) app.add_handler(edit_handler) # help command app.add_handler(CommandHandler("help", print_help)) # fallback for unrecognized messages async def unknown(update, _): await update.message.reply_text( "I don't understand that. Use /help to see what I can do." ) app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, unknown)) app.add_handler(MessageHandler(filters.COMMAND, unknown)) # log all errors app.add_error_handler(error)
[docs] async def post_init(application): """Set bot commands visible in the Telegram command menu.""" await application.bot.set_my_commands([ BotCommand("help", "Show help and available commands"), BotCommand("create", "Create a new quiz"), BotCommand("attempt", "Attempt an existing quiz"), BotCommand("rename", "Rename one of your quizzes"), BotCommand("remove", "Delete one of your quizzes"), ])
if __name__ == '__main__': config = get_config() Session = get_session_factory(config['DATABASE_URL']) persistence = SQLAlchemyPersistence(database_url=config['DATABASE_URL']) app = ApplicationBuilder().token(config['TELEGRAM_TOKEN']).persistence(persistence).post_init(post_init).build() app.bot_data['Session'] = Session setup_bot(app) if config['WEBHOOK']: app.run_webhook( listen="0.0.0.0", port=config['PORT'], url_path=config['TELEGRAM_TOKEN'], webhook_url=config['WEBHOOK'] + config['TELEGRAM_TOKEN'], ) else: logger.info('No WEBHOOK set, starting in polling mode') app.run_polling()