Skip to content
Merged
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
11 changes: 10 additions & 1 deletion telegram_bot_project/bot/buttons.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,13 @@ def idea_reply_keyboard() -> ReplyKeyboardMarkup:
idea_reply_keyboard.keyboard.append([button_update, button_all_ideas])
idea_reply_keyboard.keyboard.append([button_menu])

return idea_reply_keyboard
return idea_reply_keyboard

def task_reply_keyboard() -> InlineKeyboardMarkup:
inline_markup = InlineKeyboardMarkup(inline_keyboard=[], row_width=2)

button_yes: InlineKeyboardButton = InlineKeyboardButton(text=BUTTON_YES, callback_data="yes_task")
button_no: InlineKeyboardButton = InlineKeyboardButton(text=BUTTON_NO, callback_data="no_task")

inline_markup.inline_keyboard.append([button_yes, button_no])
return inline_markup
32 changes: 32 additions & 0 deletions telegram_bot_project/bot/callbacks.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
from bot.buttons import menu_reply_keyboard, idea_reply_keyboard
from messages import MESSAGES
from service.idea import IdeaService
from service.task import TaskService
from service.user import UserService
from states import DialogStates


async def start_callback_language(callback_query: types.CallbackQuery) -> None:
await callback_query.answer()
Expand Down Expand Up @@ -75,3 +78,32 @@ async def callback_idea_process(callback_query: types.CallbackQuery, state: FSMC
case _:
print(f"--[INFO] - User {user_id} ({user_name}) sent invalid callback: {callback_query.data}")
await callback_query.message.answer(MESSAGES[language]["IDEA_PROBLEM"], reply_markup=idea_reply_keyboard())

async def callback_task_deadline(callback_query: types.CallbackQuery, state: FSMContext) -> None:
await callback_query.answer()

user_id: int = callback_query.from_user.id
user_name: str = callback_query.from_user.username or "unknown"
user_find: Optional[dict] = await UserService.get_user_by_id(user_id)
language: str = await UserService.get_user_language(user_id)
if not language:
language = 'ENGLISH'
if not user_find:
await callback_query.message.answer(MESSAGES['ENGLISH']["AUTHORIZATION_PROBLEM"])
return

match callback_query.data:
case "yes_task":
await state.set_state(DialogStates.task_deadline)
await callback_query.message.answer(MESSAGES[language]["TASK_DEADLINE_YES"])
case "no_task":
data = await state.get_data()
saved_task = data.get("task")
print(f"--[INFO] - User {user_id} ({user_name}) saved task: {saved_task}")

await TaskService.create_task(user_id, saved_task, False)
await callback_query.message.answer(MESSAGES[language]["TASK_DEADLINE_NO"], reply_markup=menu_reply_keyboard())
await state.clear()
case _:
print(f"--[INFO] - User {user_id} ({user_name}) sent invalid callback: {callback_query.data}")
await callback_query.message.answer(MESSAGES[language]["TASK_DEADLINE_INVALID"])
13 changes: 13 additions & 0 deletions telegram_bot_project/bot/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,16 @@ async def update_idea_command(message: types.Message, state: FSMContext):
await message.answer(MESSAGES[language]['UPDATE_IDEA'])
await state.set_state(DialogStates.update_idea)

# Create Task Handler
async def task_command(message: types.Message, state: FSMContext):
user_id: int = message.from_user.id
user_find: Any = await UserService.get_user_by_id(user_id)
language: str = await UserService.get_user_language(user_id)

if not user_find:
await message.answer(MESSAGES['ENGLISH']['AUTHORIZATION_PROBLEM'])
else:
print(f"--[INFO] - User with id: {user_id} - opened /task.")

await message.answer(MESSAGES[language]['TASK_ADD'])
await state.set_state(DialogStates.confirm_task)
46 changes: 45 additions & 1 deletion telegram_bot_project/bot/handlers.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from aiogram.fsm.context import FSMContext
from aiogram.types import Message

from bot.buttons import get_idea_conf_keyboard, menu_reply_keyboard, idea_reply_keyboard
from bot.buttons import get_idea_conf_keyboard, menu_reply_keyboard, idea_reply_keyboard, task_reply_keyboard
from messages import MESSAGES
from service.idea import IdeaService
from service.task import TaskService
from service.user import UserService
from states import DialogStates

Expand Down Expand Up @@ -146,3 +147,46 @@ async def process_save_updated_idea_text(message: Message, state: FSMContext):
)

await state.clear()

async def process_task_save(message: Message, state: FSMContext):
user_id = message.from_user.id
user_find = await UserService.get_user_by_id(user_id)
language = await UserService.get_user_language(user_id) or "ENGLISH"
if not user_find:
await message.answer(MESSAGES["ENGLISH"]['AUTHORIZATION_PROBLEM'])
return
else:
task = message.text.strip()
print(f"--[INFO] User with id: {user_id} provided task: {task}")

await message.answer(MESSAGES[language]['TASK_DEADLINE_ASK'], reply_markup=task_reply_keyboard())
await state.update_data(task=task)

from datetime import datetime

async def process_task_deadline(message: Message, state: FSMContext):
user_id = message.from_user.id
user_find = await UserService.get_user_by_id(user_id)
language = await UserService.get_user_language(user_id) or "ENGLISH"

if not user_find:
await message.answer(MESSAGES["ENGLISH"]['AUTHORIZATION_PROBLEM'])
return

data = await state.get_data()
task = data.get("task")

deadline_str = message.text.strip()

try:
time_obj = datetime.strptime(deadline_str, "%H:%M").time()
deadline_dt = datetime.combine(datetime.now().date(), time_obj)

print(f"--[INFO] User with id: {user_id} provided deadline: {deadline_dt}")

await TaskService.create_task(user_id, task, False, deadline_dt)
await message.answer(MESSAGES[language]['TASK_SAVED'], reply_markup=menu_reply_keyboard())
await state.clear()

except ValueError:
await message.answer(MESSAGES[language]['TASK_DEADLINE_INVALID'])
14 changes: 11 additions & 3 deletions telegram_bot_project/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from config import TOKEN
from bot.commands import *
from bot.handlers import *
from bot.callbacks import start_callback_language, callback_idea_process
from bot.callbacks import start_callback_language, callback_idea_process, callback_task_deadline
from messages import *
from states import DialogStates

Expand Down Expand Up @@ -50,8 +50,8 @@ async def update_idea(message: Message, state: FSMContext):
await update_idea_command(message, state)

@dp.message(Command("task"))
async def task(message: Message):
pass
async def task(message: Message, state: FSMContext):
await task_command(message, state)

@dp.callback_query(F.data.in_({"lang_ua", "lang_en"}))
async def callback_language(callback_query: CallbackQuery):
Expand All @@ -61,6 +61,10 @@ async def callback_language(callback_query: CallbackQuery):
async def callback_idea(callback_query: CallbackQuery, state: FSMContext):
await callback_idea_process(callback_query, state)

@dp.callback_query(F.data.in_({"yes_task", "no_task"}))
async def callback_idea(callback_query: CallbackQuery, state: FSMContext):
await callback_task_deadline(callback_query, state)

@dp.message()
async def process_fallback(message: Message, state: FSMContext):
current_state = await state.get_state()
Expand All @@ -73,6 +77,10 @@ async def process_fallback(message: Message, state: FSMContext):
await process_idea_update(message, state)
elif current_state == DialogStates.waiting_for_update_text:
await process_save_updated_idea_text(message, state)
elif current_state == DialogStates.confirm_task:
await process_task_save(message, state)
elif current_state == DialogStates.task_deadline:
await process_task_deadline(message, state)

# Main Function
async def main():
Expand Down
14 changes: 14 additions & 0 deletions telegram_bot_project/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@
"IDEA_DELETED": "🗑️ Ідею №{} '{}' було видалено.",
"ASK_NEW_IDEA_TEXT": "✏️ Введіть новий текст для ідеї №{} '{}'.",
"IDEA_UPDATED": "✅ Ідею №{} успішно оновлено.",
"TASK_ADD": "Вкажіть назву завдання та натисніть кнопку нижче, щоб продовжити",
"TASK_DEADLINE_ASK": "Це завдання має крайній термін?",
"TASK_DEADLINE_YES": "Будьласка введіть годину (дедлайн) для задачі.\nПриклад: 13:10",
"TASK_DEADLINE_NO": "Гаразд, без крайнього терміну. Ваше завдання збережено.",
"TASK_DEADLINE_INVALID": "Недійсний термін. Будь ласка, спробуйте ще раз.",
"TASK_SAVED": "Задачу збережено.",
"LANGUAGE_ASK": (
"🌐 **Оберіть мову інтерфейсу:**\n"
"Натисніть кнопку нижче, щоб продовжити:"
Expand Down Expand Up @@ -68,6 +74,12 @@
"IDEA_DELETED": "🗑️ Idea #{} '{}' has been deleted.",
"ASK_NEW_IDEA_TEXT": "✏️ Please enter the new text for idea #{} '{}'.",
"IDEA_UPDATED": "✅ Idea №{} updated successfully.",
"TASK_ADD": "Provide a task name and press the button below to continue",
"TASK_DEADLINE_ASK": "This task have a deadline?",
"TASK_DEADLINE_YES": "Please enter the time (deadline) for the task.\nExample: 13:10",
"TASK_DEADLINE_NO": "Ok, no deadline. Your task saved.",
"TASK_DEADLINE_INVALID": "Invalid deadline. Please try again.",
"TASK_SAVED": "Task saved successfully.",
"LANGUAGE_ASK": (
"🌐 **Please choose your interface language:**\n"
"Tap a button below to continue:"
Expand Down Expand Up @@ -96,3 +108,5 @@
MENU_BUTTON: str = "📂 Main Menu"
UPDATE_IDEA_BUTTON: str = "✏️ Update Idea"
ALL_IDEAS: str = "📋 View All Ideas"
BUTTON_YES: str = "Yes"
BUTTON_NO: str = "No"
4 changes: 3 additions & 1 deletion telegram_bot_project/states.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ class DialogStates(StatesGroup):
confirm_idea = State()
delete_idea = State()
update_idea = State()
waiting_for_update_text = State()
waiting_for_update_text = State()
confirm_task = State()
task_deadline = State()