diff --git a/.gitignore b/.gitignore index 5df3a6b..d329c12 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ config.yaml database/* -__pycache__/* \ No newline at end of file +__pycache__/* +old.py \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..aa77b01 --- /dev/null +++ b/README.md @@ -0,0 +1,38 @@ +# TG Keeper + +TG Keeper bot allows you to store notes, display them at a specified interval, and recognizes date formats: DD.MM, DD month. It works both in group chats by mentioning @username_bot and in private messages. + +## Features + +- Convenient setup interface +- Dependency installation via `requirements.txt` +- Initial configuration in the `config.yaml` file + +## Installation + +1. Clone the repository: + ```sh + git clone https://github.com/yourusername/tg-keeper.git + ``` +2. Navigate to the project directory: + ```sh + cd tg-keeper + ``` +3. Install the dependencies: + ```sh + pip install -r requirements.txt + ``` + +## Configuration + +1. Open the `config.yaml` file and configure the parameters as you wish. + +## Usage + +Run the bot: + +```sh +python bot.py +``` + +Now you can add and manage your notes through TG Keeper. diff --git a/config_expl.yaml b/config_expl.yaml new file mode 100644 index 0000000..815126f --- /dev/null +++ b/config_expl.yaml @@ -0,0 +1,6 @@ +admin_id: "856850518" +api_token: null +test_token: null +bot_username: "@keeper_inbot" +users_path: "database/users.yaml" +user_path: "database/users/{}.yaml" diff --git a/for_db.py b/for_db.py index 04f9649..3b1f0de 100644 --- a/for_db.py +++ b/for_db.py @@ -23,37 +23,20 @@ def new_user(message: types.Message) -> bool: if check_user(message.chat.id): return False - user = { - "id": message.chat.id, - "type": message.chat.type, - "username": message.chat.username, - "first_name": message.chat.first_name, - "last_name": message.chat.last_name, - "time_created": datetime.now().strftime("%Y-%m-%d %H:%M:%S"), - "last_message": None, - "remind_delta": 12 * 60 * 60, # 12 часов по умолчанию - } - - users = yaml.safe_load(open(users_path, "r"), encoding="utf-8") - - if not users: - users = {} - - users[user["id"]] = user - - yaml_data = yaml.dump( - users, - default_flow_style=False, - encoding="utf-8", - allow_unicode=True, - width=float("inf"), - sort_keys=False, + update_user_settings(message.chat.id, "id", message.chat.id) + update_user_settings(message.chat.id, "type", message.chat.type) + update_user_settings(message.chat.id, "username", message.chat.username) + update_user_settings(message.chat.id, "first_name", message.chat.first_name) + update_user_settings(message.chat.id, "last_name", message.chat.last_name) + update_user_settings( + message.chat.id, "time_created", datetime.now().strftime("%Y-%m-%d %H:%M:%S") ) + update_user_settings(message.chat.id, "last_message", None) + update_user_settings( + message.chat.id, "remind_delta", 12 * 60 * 60 + ) # 12 часов по умолчанию - with open(users_path, "wb") as file: - file.write(yaml_data) - - return True + return def add_note( @@ -233,3 +216,38 @@ def check_old_notes() -> list[int, str, int]: # возвращает перву return user_id, list, ind return None, None, None + + +def update_user_settings(user_id: int, param: str, value: any) -> bool: + users = yaml.safe_load(open(users_path, "r", encoding="utf-8")) + + if not users: + users = {} + + if user_id not in users: + users[user_id] = {} + + users[user_id][param] = value + + yaml_data = yaml.dump( + users, + default_flow_style=False, + encoding="utf-8", + allow_unicode=True, + width=float("inf"), + sort_keys=False, + ) + + with open(users_path, "wb") as file: + file.write(yaml_data) + + return True + + +def user_settings(user_id: int) -> dict: + if not check_user(user_id): + return None + + users = yaml.safe_load(open(users_path, "r", encoding="utf-8")) + + return users[user_id] diff --git a/lang.yaml b/lang.yaml index 3406bd7..da47ad9 100644 --- a/lang.yaml +++ b/lang.yaml @@ -12,3 +12,4 @@ error_message: "Произошла ошибка. \ \nПожалуйста, попробуйте снова или свяжитесь с @Kr0sH_512" no_reminders: "У вас нет напоминаний." + not_registered: "Пожалуйста, воспользуйтесь сперва командой /start" diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..f7a3ae2 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,4 @@ +pyyaml +pytelegrambotapi +schedule +python-telegram-bot \ No newline at end of file diff --git a/tg.py b/tg.py index 35bdab1..9eca199 100644 --- a/tg.py +++ b/tg.py @@ -45,6 +45,9 @@ def start(message: types.Message): send_message(message, lang["start_message"]) + if not db.check_user(message.chat.id): + db.new_user(message) + return @@ -54,6 +57,9 @@ def help(message: types.Message): send_message(message, help_msg) + if not db.check_user(message.chat.id): + db.new_user(message) + return @@ -187,13 +193,89 @@ def choose_note_callback(call): return -@bot.message_handler(commands=["settings", "setting", "edit"]) -def display_settings(message: types.Message): +@bot.callback_query_handler(func=lambda call: "edit_time" in call.data) +def edit_time(call): + list_time = { + (24 - 8) * 3600: "8:00 в день до напоминания", + (24 - 12) * 3600: "12:00 в день до напоминания", + (24 - 18) * 3600: "18:00 в день до напоминания", + 0: "0:00 в день до напоминания", + (-8) * 3600: "8:00 в день напоминания", + (-12) * 3600: "12:00 в день напоминания", + (-18) * 3600: "18:00 в день напоминания", + } + + if call.data[-1] == "#": + markup = types.InlineKeyboardMarkup() + for delta in list_time.keys(): + markup.add( + types.InlineKeyboardButton( + list_time[delta], + callback_data=f"edit_time^{delta}", + ) + ) + + bot.edit_message_text( + "⏰ Выберите время для уведомлений:", + call.message.chat.id, + call.message.message_id, + reply_markup=markup, + ) + + return + + delta = int(call.data.split("^")[1]) + + db.update_user_settings(call.message.chat.id, "remind_delta", delta) + + bot.edit_message_text( + f"Выбранное время: \n\n{list_time[delta]}", + call.message.chat.id, + call.message.message_id, + ) return -@bot.message_handler(commands=["list"]) +@bot.message_handler(commands=["settings", "setting", "edit"]) +def display_settings(message: types.Message): + if not db.check_user(message.chat.id): + db.new_user(message) + + settings_msg = "Изменить время отправки напоминания" + markup = types.InlineKeyboardMarkup() + markup.add( + types.InlineKeyboardButton( + "Изменить время", + callback_data="edit_time#", + ) + ) + + send_message(message, settings_msg, markup) + + return + + settings = db.user_settings(message.chat.id) + # if not settings: + # send_message(message, lang["not_registered"]) + + # return + + settings_msg = "⚙️ Настройки:\ + \n\nВремя до отправки уведомления: {}" + + markup = types.InlineKeyboardMarkup() + markup.add( + types.InlineKeyboardButton( + "Изменить время", + callback_data="edit_time#", + ) + ) + + return + + +@bot.message_handler(commands=["list", "lists", "l"]) def list_notes(message: types.Message, list: str = "Default", edit: bool = False): notes = db.get_notes(message.chat.id, list) @@ -242,14 +324,15 @@ def text_message(message: types.Message): return # ignore messages from supergroups - if db.check_user(message.chat.id) is None: + if not db.check_user(message.chat.id): db.new_user(message) message.text = message.text.replace(f"{bot_username}", "").strip() if not message.text: if not message.reply_to_message: return - message.text = message.reply_to_message.text + # message.text = message.reply_to_message.text + message = message.reply_to_message date_patterns = [ r"\b\d{1,2}\s(?:января|февраля|марта|апреля|мая|июня|июля|августа|сентября|октября|ноября|декабря)\b", @@ -328,6 +411,8 @@ def send_message( if not thread_id: thread_id = message.message_thread_id + msg = None + try: msg = bot.send_message( chat_id=id,