diff --git a/main.py b/main.py index 0a7f46b..29b450e 100644 --- a/main.py +++ b/main.py @@ -4,7 +4,7 @@ from dotenv import load_dotenv from aiogram import Bot, Dispatcher from aiogram.client.default import DefaultBotProperties from aiogram.enums import ParseMode -from aiogram.filters import CommandStart +from aiogram.filters import Command, CommandStart from aiogram.types import Message from trilium_py.client import ETAPI @@ -23,6 +23,7 @@ ea = ETAPI(server_url=TRILIUM_URL, token=TRILIUM_TOKEN) bot = Bot(token=TELEGRAM_TOKEN, default=DefaultBotProperties(parse_mode=ParseMode.HTML)) dp = Dispatcher() +pending_daily_chats = set() # chat_ids ожидающих текст для /daily @dp.message(CommandStart()) @@ -30,151 +31,150 @@ async def start(msg: Message): await msg.answer("Отправь мне текст — я создам заметку в Trilium.") -@dp.message() -async def handler(msg: Message): - text = msg.text.strip() +def _get_id(obj): + if isinstance(obj, dict): + return obj.get("noteId") or obj.get("id") + return getattr(obj, "noteId", None) or getattr(obj, "id", None) - # Проверяем флаг /daily - is_daily = text.startswith("/daily") - if is_daily: - # Удаляем флаг из текста - text = text[6:].strip() # удаляем "/daily" +def _get_title(obj): + return obj.get("title") if isinstance(obj, dict) else getattr(obj, "title", "") + +def _get_content(obj): + return obj.get("content") if isinstance(obj, dict) else getattr(obj, "content", "") + + +def _translate_month_en_ru(name: str) -> str: + mapping = { + "January": "Январь", + "February": "Февраль", + "March": "Март", + "April": "Апрель", + "May": "Май", + "June": "Июнь", + "July": "Июль", + "August": "Август", + "September": "Сентябрь", + "October": "Октябрь", + "November": "Ноябрь", + "December": "Декабрь", + } + return mapping.get(name, name) + + +def _translate_weekday_en_ru(name: str) -> str: + mapping = { + "Monday": "Понедельник", + "Tuesday": "Вторник", + "Wednesday": "Среда", + "Thursday": "Четверг", + "Friday": "Пятница", + "Saturday": "Суббота", + "Sunday": "Воскресенье", + } + return mapping.get(name, name) + + +def save_inbox(text: str): # разделяем на заголовок и тело lines = text.split("\n", 1) - title = lines[0][:100] # заголовок = первая строка - content = lines[1] if len(lines) > 1 else "" # остальное — тело заметки + title = lines[0][:100] + content = lines[1] if len(lines) > 1 else "" + ea.create_note( + parentNoteId=INBOX_NOTE_ID, title=title, content=content, type="text" + ) - if is_daily: - # Работаем с ежедневной заметкой - today = datetime.now() - month_name = ( - today.strftime("%m - %B") - .replace("January", "Январь") - .replace("February", "Февраль") - .replace("March", "Март") - .replace("April", "Апрель") - .replace("May", "Май") - .replace("June", "Июнь") - .replace("July", "Июль") - .replace("August", "Август") - .replace("September", "Сентябрь") - .replace("October", "Октябрь") - .replace("November", "Ноябрь") - .replace("December", "Декабрь") - ) - day_name = ( - today.strftime("%d - %A") - .replace("Monday", "Понедельник") - .replace("Tuesday", "Вторник") - .replace("Wednesday", "Среда") - .replace("Thursday", "Четверг") - .replace("Friday", "Пятница") - .replace("Saturday", "Суббота") - .replace("Sunday", "Воскресенье") - ) - today_date = today.strftime("%Y-%m-%d") +def save_daily(text: str) -> str: + today = datetime.now() + month_name = ( + f"{today.strftime('%m')} - {_translate_month_en_ru(today.strftime('%B'))}" + ) + day_name = ( + f"{today.strftime('%d')} - {_translate_weekday_en_ru(today.strftime('%A'))}" + ) + today_date = today.strftime("%Y-%m-%d") + + # Корень daily + daily_root = ea.get_note(DAILY_NOTE_ID) + + # Ищем/создаём месяц + month_folder = None + if hasattr(daily_root, "children"): + for child in daily_root.children: + if _get_title(child) == month_name: + month_folder = child + break + + if not month_folder: + month_folder = ea.create_note( + parentNoteId=DAILY_NOTE_ID, title=month_name, type="text" + ) + + month_id = _get_id(month_folder) + month_folder = ea.get_note(month_id) + + # Ищем/создаём день + day_folder = None + if hasattr(month_folder, "children"): + for child in month_folder.children: + if _get_title(child) == day_name: + day_folder = child + break + + if not day_folder: + day_folder = ea.create_note(parentNoteId=month_id, title=day_name, type="text") + + day_id = _get_id(day_folder) + day_folder = ea.get_note(day_id) + + # Ищем заметку по дате + existing_note = None + if hasattr(day_folder, "children"): + for child in day_folder.children: + if _get_title(child) == today_date: + existing_note = child + break + + if existing_note: + existing_content = _get_content(existing_note) + new_content = f"{existing_content}\n\n---\n{text}" if existing_content else text + ea.update_note(noteId=_get_id(existing_note), content=new_content) + return f"Добавлено в ежедневную заметку за {today_date}." + + ea.create_note(parentNoteId=day_id, title=today_date, content=text, type="text") + return f"Создана ежедневная заметка за {today_date}." + + +@dp.message(Command("daily")) +async def daily_command(msg: Message): + pending_daily_chats.add(msg.chat.id) + await msg.answer( + "Жду текст для ежедневной заметки. Следующее сообщение запишу в текущий день." + ) + + +@dp.message() +async def handler(msg: Message): + text = (msg.text or "").strip() + + # Если ожидаем daily — пишем туда + if msg.chat.id in pending_daily_chats: + pending_daily_chats.discard(msg.chat.id) try: - # Получаем папку с ежедневными заметками - daily_root = ea.get_note(DAILY_NOTE_ID) - month_folder = None - - # Вспомогательная функция для получения ID - def get_id(obj): - if isinstance(obj, dict): - return obj.get("noteId") or obj.get("id") - return obj.noteId if hasattr(obj, "noteId") else obj.id - - # Ищем папку месяца - if hasattr(daily_root, "children"): - for child in daily_root.children: - child_title = ( - child.get("title") if isinstance(child, dict) else child.title - ) - if month_name in child_title: - month_folder = child - break - - if not month_folder: - # Создаём папку месяца, если её нет - month_folder = ea.create_note( - parentNoteId=DAILY_NOTE_ID, title=month_name, type="text" - ) - - month_id = get_id(month_folder) - - # Ищем папку дня внутри месячной папки - day_folder = None - month_folder_refresh = ea.get_note(month_id) - if hasattr(month_folder_refresh, "children"): - for child in month_folder_refresh.children: - child_title = ( - child.get("title") if isinstance(child, dict) else child.title - ) - if day_name in child_title: - day_folder = child - break - - if not day_folder: - # Создаём папку дня, если её нет - day_folder = ea.create_note( - parentNoteId=month_id, title=day_name, type="text" - ) - - day_id = get_id(day_folder) - - # Ищем заметку с сегодняшней датой - existing_note = None - day_folder_refresh = ea.get_note(day_id) - if hasattr(day_folder_refresh, "children"): - for child in day_folder_refresh.children: - child_title = ( - child.get("title") if isinstance(child, dict) else child.title - ) - if child_title == today_date: - existing_note = child - break - - if existing_note: - # Дописываем в существующую заметку - existing_content = ( - existing_note.get("content") - if isinstance(existing_note, dict) - else existing_note.content - ) - new_content = ( - existing_content + "\n\n---\n" + content - if existing_content - else content - ) - existing_id = get_id(existing_note) - ea.update_note(noteId=existing_id, content=new_content) - await msg.answer(f"Добавлено в ежедневную заметку за {today_date}.") - else: - # Создаём новую заметку на сегодня - try: - ea.create_note( - parentNoteId=day_id, - title=today_date, - content=content, - type="text", - ) - await msg.answer(f"Создана ежедневная заметка за {today_date}.") - except Exception as create_err: - await msg.answer(f"Ошибка при создании заметки: {str(create_err)}") + result = save_daily(text) + await msg.answer(result) except Exception as e: await msg.answer(f"Ошибка при работе с ежедневной заметкой: {str(e)}") - else: - # Обычное сохранение в Inbox - try: - ea.create_note( - parentNoteId=INBOX_NOTE_ID, title=title, content=content, type="text" - ) - await msg.answer("Заметка сохранена в Trilium.") - except Exception as e: - await msg.answer(f"Ошибка при сохранении в Inbox: {str(e)}") + return + + # Обычная заметка в Inbox + try: + save_inbox(text) + await msg.answer("Заметка сохранена в Trilium.") + except Exception as e: + await msg.answer(f"Ошибка при сохранении в Inbox: {str(e)}") async def main():