diff options
| -rw-r--r-- | backend_api.py | 75 | ||||
| -rw-r--r-- | bot.py | 21 | ||||
| -rw-r--r-- | keyboards.py | 6 | ||||
| -rw-r--r-- | states.py | 22 | ||||
| -rw-r--r-- | utils.py | 9 |
5 files changed, 92 insertions, 41 deletions
diff --git a/backend_api.py b/backend_api.py index 4fb11cf..8f678bb 100644 --- a/backend_api.py +++ b/backend_api.py @@ -2,23 +2,24 @@ import requests import urllib from config import BACKEND_URL import logging +import json +from typing import Tuple, Dict + +logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s') logger = logging.getLogger(__name__) logger.setLevel(logging.DEBUG) -def register_user(tg_id, username, fullname) -> bool: - logger.debug(f"Registering user with id={tg_id}; username={username}") +def make_request(method: str, url: str, **kwargs) -> Tuple[int, Dict]: try: - response = requests.post(f"{BACKEND_URL}/profiles/", data={ - "tg_id": tg_id, - "username": username, - "fullname": fullname - }) + response = requests.request(method, url, **kwargs) + answer = response.json() + except Exception as e: logger.debug(f"Got exception while making request: {e}") - return False + return 500, {} logger.debug( f"Got response from backend: " @@ -26,31 +27,51 @@ def register_user(tg_id, username, fullname) -> bool: f"Text={response.text[:200]}..." ) - return response.status_code == 201 + return response.status_code, answer + + +def post_request(url: str, **kwargs): + return make_request("post", url, **kwargs) + + +def put_request(url: str, **kwargs): + return make_request("put", url, **kwargs) + + +def get_request(url: str, **kwargs): + return make_request("get", url, **kwargs) + + +def register_user(tg_id: int, username: str, fullname: str) -> Tuple[int, Dict]: + logger.debug(f"Trying to register user with id={tg_id}; username={username}") + return post_request(f"{BACKEND_URL}/profiles/", data={ + "tg_id": tg_id, + "username": username, + "fullname": fullname + }) def get_tasks(): - response = requests.get(f"{BACKEND_URL}/tasks/") - return response.json() + logger.debug(f"Trying to retrieve all tasks") + return get_request(f"{BACKEND_URL}/tasks/") -def get_task(title: str): +def get_task(title: str) -> Tuple[int, Dict]: logger.debug(f"Trying to retrieve task with title={title}") - try: - response = requests.get( - "http://127.0.0.1:8000/api/get_task/" - + urllib.parse.quote(title) - ) - task = response.json() + return get_request(f"{BACKEND_URL}/api/get_task/" + urllib.parse.quote(title)) - except Exception as e: - logger.debug(f"Got exception while making request: {e}") - return 500, {} - logger.debug( - f"Got response from backend: " - f"Status={response.status_code}; " - f"Text={response.text[:200]}..." - ) +def save_state(last_state: int, tg_id: int, user_data: dict) -> Tuple[int, Dict]: + user_data_dumped = json.dumps(user_data) + logger.debug(f"Trying to save state for user with id={tg_id}; state={last_state}; user_data={user_data_dumped}") + + return put_request(f"{BACKEND_URL}/api/state/update/{tg_id}/", data={ + "last_state": last_state, + "tg_id": tg_id, + "user_data": user_data_dumped + }) + - return response.status_code, task +def get_state(tg_id: int) -> Tuple[int, dict]: + logger.debug(f"Trying to get state for user with id={tg_id}") + return get_request(f"{BACKEND_URL}/api/state/get/{tg_id}/") @@ -6,6 +6,7 @@ from telegram import Update, User, Bot import logging from os import environ +import json from config import TG_TOKEN, REQUEST_KWARGS import backend_api @@ -16,12 +17,14 @@ from keyboards import ( from utils import * from states import States -logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s') +logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s') logger = logging.getLogger(__name__) logger.setLevel(logging.DEBUG) -def start(bot: Bot, update: Update, user_data): +def start(bot: Bot, update: Update, user_data: dict): + user_data.update({"chosen_task": None}) + update.message.reply_text( "Привет! Ты вошел в телеграм-квиз с мемами про наш любимый КНиИТ!", reply_markup=ReplyKeyboardRemove() @@ -48,6 +51,19 @@ def username_check(bot: Bot, update: Update, user_data): return States.main_menu(bot, update, user_data) +def resume_bot(bot: Bot, update: Update, user_data): + status_code, state = backend_api.get_state(update.message.from_user.id) + + user_data.update(json.loads(state["user_data"])) + last_state = state["last_state"] + + for handler in conversation_handler.states[last_state]: + if handler.filters.filter(update): + return handler.callback(bot, update, user_data) + + return last_state + + def stop(bot, update): update.message.reply_text('Пока!', reply_markup=ReplyKeyboardRemove()) update.message.reply_text('Для того, чтобы начать работу с ботом заново напишите /start') @@ -72,6 +88,7 @@ def main(): conversation_handler = ConversationHandler( entry_points=[ CommandHandler('start', start, pass_user_data=True), + MessageHandler(Filters.text, resume_bot, pass_user_data=True), ], states={ diff --git a/keyboards.py b/keyboards.py index 5966d90..cbdd770 100644 --- a/keyboards.py +++ b/keyboards.py @@ -35,9 +35,11 @@ class TasksKeyboard(Keyboard): @classmethod def get_keyboard(cls, telegram_id=None): - tasks = backend_api.get_tasks() + status, tasks = backend_api.get_tasks() titles_keyboard = [[cls.CANCEL]] - titles_keyboard.extend([task.get("title")] for task in tasks) + if status == 200: + titles_keyboard.extend([task.get("title")] for task in tasks) + return titles_keyboard @@ -11,8 +11,19 @@ import backend_api from telegram import Update, User, Bot +def save_state(func): + def wrapper(bot: Bot, update: Update, user_data: dict, *args, **kwargs): + print(user_data) + last_state = func(bot, update, user_data, *args, **kwargs) + backend_api.save_state(last_state, update.message.from_user.id, user_data) + return last_state + + return wrapper + + class States: @staticmethod + @save_state def wait_for_username(bot: Bot, update: Update, user_data: dict): update.message.reply_text( "По правилам квиза ты не можешь участвовать, если у тебя не указано " @@ -22,6 +33,7 @@ class States: return WAIT_FOR_USERNAME @staticmethod + @save_state def main_menu(bot: Bot, update: Update, user_data: dict): user_data["chosen_task"] = None @@ -34,6 +46,7 @@ class States: return MAIN_MENU @staticmethod + @save_state def choose_task(bot: Bot, update: Update, user_data: dict): user_data["chosen_task"] = None @@ -44,21 +57,24 @@ class States: return TASK_CHOOSING @staticmethod + @save_state def top_10(bot: Bot, update: Update, user_data: dict): update.message.reply_text("какая то хуйня") return MAIN_MENU @staticmethod + @save_state def rules(bot: Bot, update: Update, user_data: dict): update.message.reply_text("какая то хуйня") return MAIN_MENU @staticmethod + @save_state def show_task(bot: Bot, update: Update, user_data: dict): if "chosen_task" in user_data and user_data["chosen_task"] is not None: task_title = user_data["chosen_task"] else: - task_title = get_input(update, user_data) + task_title = update.message.text user_data["chosen_task"] = task_title status_code, task = backend_api.get_task(task_title) @@ -83,6 +99,7 @@ class States: return TASK_SHOWN @staticmethod + @save_state def type_answer(bot: Bot, update: Update, user_data: dict): update.message.reply_text( "Вводи свой ответ, я его проверю.", @@ -91,8 +108,9 @@ class States: return ANSWERING @staticmethod + @save_state def accept_answer(bot: Bot, update: Update, user_data: dict): - answer = get_input(update, user_data) + answer = update.message.text if answer == "хуй": update.message.reply_text( "Ты ввел правильный ответ! Возвращайся к другим задачам", @@ -1,14 +1,7 @@ -def get_input(update, user_data): - if "resuming" in user_data and user_data["resuming"] == True: - return user_data["text"] - else: - return update.message.text - - ( WAIT_FOR_USERNAME, MAIN_MENU, TOP_10, RULES, TASK_CHOOSING, TASK_SHOWN, ANSWERING, ANSWER_RIGHT, ANSWER_WRONG, *_ -) = range(100)
\ No newline at end of file +) = range(100) |