diff --git a/database/db.py b/database/db.py index bd3c13c..76f4b12 100644 --- a/database/db.py +++ b/database/db.py @@ -1,14 +1,16 @@ -import sqlite3 import os +import sqlite3 from datetime import datetime + from logs.custom_logger import logger + # Получение абсолютного пути к текущей директории -current_dir = os.getcwd() +# current_dir = os.getcwd() class BotDB: - def __init__(self, name): + def __init__(self, current_dir, name): self.db_file = os.path.join(current_dir, name) self.conn = None self.cursor = None @@ -59,7 +61,7 @@ class BotDB: self.logger.info(f'Получена текущая версия миграции: {version}') return version except Exception as e: - self.logger.error(f'Ошибка при получении текущей версии миграции: {e}') + self.logger.error(f'Ошибка при получении текущей версии миграции: {str(e)}') raise finally: self.close() @@ -298,11 +300,6 @@ class BotDB: finally: self.close() - def change_name(self, user_id): - #TODO: реализовать функцию изменения имени пользователя по которому к нему обращается бот. Обновляем поля first_name, date_changed - #result = self.cursor.execute("UPDATE 'our_users' SET (?) WHERE user_id = (?)", (new_user_name), ) - pass - def get_info_about_stickers(self, user_id: int): """ Проверяет, получил ли пользователь стикеры. @@ -825,38 +822,23 @@ class BotDB: finally: self.close() - def add_post_from_telegram_in_db(self, group_message_id, message_id, is_last_message_id, content_name, text): - self.logger.info( - f"Запуск функции add_post_from_telegram_in_db: group_message_id={group_message_id}, message_id={message_id}" - f", is_last_message_id={is_last_message_id}, content_name={content_name}, text={text}") - try: - self.connect() - self.cursor.execute( - "INSERT INTO posts_from_telegram (group_message_id, message_id, is_last_message_id, content_name, text)" - "VALUES (?, ?, ?, ?, ?)", (group_message_id, message_id, is_last_message_id, content_name, text)) - self.conn.commit() - self.logger.info(f"Функция add_post_from_telegram_in_db отработала успешно") - return True - except Exception as e: - self.logger.error(f"Ошибка в функции add_post_from_telegram_in_db при добавлении поста в базу данных: {e}") - return False - def get_post_content_from_telegram_by_last_id(self, last_post_id: int): self.logger.info( f"Запуск функции get_post_content_from_telegram_by_last_id, идентификатор поста {last_post_id}") try: self.connect() - main_post_sql = self.cursor.execute("SELECT group_message_id " - "FROM posts_from_telegram WHERE message_id = ?", (last_post_id,)) - main_post = main_post_sql.fetchone()[0] - except Exception as e: - self.logger.error(f"Ошибка в функции get_post_content_from_telegram_by_last_id {str(e)}") - return False - try: - result = self.cursor.execute("SELECT content_name " - "FROM posts_from_telegram WHERE group_message_id = ?", (main_post,)) + result = self.cursor.execute(""" + SELECT cpft.content_name + FROM post_from_telegram_suggest pft + JOIN message_link_to_content mltc + ON pft.message_id = mltc.post_id + JOIN content_post_from_telegram cpft + ON cpft.message_id = mltc.message_id + WHERE pft.helper_text_message_id = ? + """, (last_post_id,)) post_content = result.fetchall() - self.logger.info(f"Функция get_post_content_from_telegram_by_last_id получила список контента: {post_content}") + self.logger.info( + f"Функция get_post_content_from_telegram_by_last_id получила список контента: {post_content}") return post_content finally: self.close() @@ -866,18 +848,20 @@ class BotDB: f"Запуск функции get_post_ids_from_telegram_by_last_id, идентификатор поста {last_post_id}") try: self.connect() - main_post_sql = self.cursor.execute("SELECT group_message_id " - "FROM posts_from_telegram WHERE message_id = ?", (last_post_id,)) - main_post = main_post_sql.fetchone()[0] + result = self.cursor.execute(""" + SELECT mltc.message_id + FROM post_from_telegram_suggest pft + JOIN message_link_to_content mltc + ON pft.message_id = mltc.post_id + WHERE pft.helper_text_message_id = ? + """, (last_post_id,)) + post_ids = result.fetchall() + self.logger.info(f"Функция get_post_ids_from_telegram_by_last_id " + f"получила идентификаторы сообщений: {post_ids}") + return post_ids except Exception as e: self.logger.error(f"Ошибка в функции get_post_ids_from_telegram_by_last_id {str(e)}") return False - try: - result = self.cursor.execute("SELECT message_id " - "FROM posts_from_telegram WHERE group_message_id = ?", (main_post,)) - post_ids = result.fetchall() - self.logger.info(f"Функция get_post_ids_from_telegram_by_last_id получила идентификаторы сообщений: {post_ids}") - return post_ids finally: self.close() @@ -886,13 +870,67 @@ class BotDB: try: self.connect() result = self.cursor.execute("SELECT text " - "FROM posts_from_telegram WHERE message_id = ?", (last_post_id,)) + "FROM post_from_telegram_suggest WHERE helper_text_message_id = ?", + (last_post_id,)) text = result.fetchone()[0] self.logger.info(f"Функция get_post_text_from_telegram_by_last_id получила text") return text except Exception as e: self.logger.error(f"Ошибка в функции get_post_text_from_telegram_by_last_id {str(e)}") + def add_post_content_in_db(self, post_id: int, message_id: int, content_name: str): + self.logger.info( + f"Запуск функции add_post_content_in_db: post_id={post_id}, message_id={message_id}, " + f"content_name={content_name}") + try: + self.connect() + self.cursor.execute( + "INSERT INTO message_link_to_content (post_id, message_id)" + "VALUES (?, ?)", (post_id, message_id)) + self.conn.commit() + self.cursor.execute( + "INSERT INTO content_post_from_telegram (message_id, content_name)" + "VALUES (?, ?)", (message_id, content_name)) + self.conn.commit() + self.logger.info(f"Функция add_post_content_in_db отработала успешно") + return True + except Exception as e: + self.logger.error(f"Ошибка в функции add_post_content_in_db при добавлении поста в базу данных: {e}") + return False + + def add_post_in_db(self, message_id: int, text: str, author_id: int): + self.logger.info( + f"Запуск функции add_post_in_db: message_id={message_id}, " + f"author_id={author_id}") + try: + today = datetime.now().strftime("%d-%m-%Y %H:%M:%S") + self.connect() + self.cursor.execute( + "INSERT INTO post_from_telegram_suggest (message_id, text, author_id, created_at)" + "VALUES (?, ?, ?, ?)", (message_id, text, author_id, today)) + self.conn.commit() + self.logger.info(f"Функция add_post_in_db отработала успешно") + return True + except Exception as e: + self.logger.error(f"Ошибка в функции add_post_in_db при добавлении поста в базу данных: {e}") + return False + + def update_helper_message_in_db(self, message_id: int, helper_message_id: int): + self.logger.info( + f"Запуск функции update_helper_message_in_db: message_id={message_id}, " + f"helper_message_id={helper_message_id}") + try: + self.connect() + self.cursor.execute( + "UPDATE post_from_telegram_suggest SET helper_text_message_id = ? WHERE message_id = ?", + (helper_message_id, message_id,)) + self.conn.commit() + self.logger.info(f"Функция update_helper_message_in_db отработала успешно") + return True + except Exception as e: + self.logger.error(f"Ошибка в функции update_helper_message_in_db при добавлении поста в базу данных: {e}") + return False + def add_audio_record(self, file_name, author_id, date_added, listen_count, file_id): """Добавляет информацию о войсе юзера в БД""" self.logger.info( diff --git a/helper_bot/handlers/callback/callback_handlers.py b/helper_bot/handlers/callback/callback_handlers.py index 417daa7..354f638 100644 --- a/helper_bot/handlers/callback/callback_handlers.py +++ b/helper_bot/handlers/callback/callback_handlers.py @@ -55,30 +55,19 @@ async def post_for_group(call: CallbackQuery, state: FSMContext): logger.error(f'Ошибка при публикации фотографии в канал {MAIN_PUBLIC}: {str(e)}') await call.answer(text='Что-то пошло не так!', show_alert=True, cache_time=3) elif call.message.text == "^": - user_data = await state.get_data() + # Получаем контент медиагруппы и текст для публикации + post_content = BotDB.get_post_content_from_telegram_by_last_id(call.message.message_id) + post_text = BotDB.get_post_text_from_telegram_by_last_id(call.message.message_id) - # Получаем идентификатор последнего предложенного сообщения из кэша - help_message = get_help_message_id(call.message.message_id, user_data) - - # Получаем идентификатор медиагруппы - media_group_id = help_message - 1 - - # Получаем контент медиагруппы и текст - post_content = BotDB.get_post_content_from_telegram_by_last_id(media_group_id) - post_text = BotDB.get_post_text_from_telegram_by_last_id(media_group_id) - post_ids = BotDB.get_post_ids_from_telegram_by_last_id(media_group_id) - - # Преобразуем результат в список + # Готовим список для удаления + post_ids = BotDB.get_post_ids_from_telegram_by_last_id(call.message.message_id) message_ids = [row[0] for row in post_ids] - - # Добавляем help_message в список - message_ids.append(help_message) + message_ids.append(call.message.message_id) # Выкладываем пост в канал await send_media_group_to_channel(bot=call.bot, chat_id=MAIN_PUBLIC, post_content=post_content, post_text=post_text) - # TODO: Удалить фотки с локалки - # TODO: Поменять чтобы записывалось не в FSM + # TODO: Удалить фотки с локалки после выкладки? await call.bot.delete_messages(chat_id=GROUP_FOR_POST, message_ids=message_ids) await call.answer(text='Выложено!', show_alert=True, cache_time=3) @@ -96,9 +85,12 @@ async def decline_post_for_group(call: CallbackQuery, state: FSMContext): f'Сообщение отклонено админом {call.from_user.full_name} (ID: {call.from_user.id}).') await call.answer(text='Отклонено!', show_alert=True, cache_time=3) if call.message.text == '^': - user_data = await state.get_data() - media_group_message_id = get_help_message_id(call.message.message_id, user_data) - await call.bot.delete_message(chat_id=MAIN_PUBLIC, message_id=media_group_message_id) + post_ids = BotDB.get_post_ids_from_telegram_by_last_id(call.message.message_id) + message_ids = [row[0] for row in post_ids] + message_ids.append(call.message.message_id) + + await call.bot.delete_messages(chat_id=GROUP_FOR_POST, message_ids=message_ids) + await call.answer(text='Удалено!', show_alert=True, cache_time=3) except Exception as e: await call.bot.send_message(IMPORTANT_LOGS, f"Произошла ошибка: {str(e)}\n\nTraceback:\n{traceback.format_exc()}") diff --git a/helper_bot/handlers/private/private_handlers.py b/helper_bot/handlers/private/private_handlers.py index 1dffc69..4f4060b 100644 --- a/helper_bot/handlers/private/private_handlers.py +++ b/helper_bot/handlers/private/private_handlers.py @@ -161,6 +161,7 @@ async def suggest_router(message: types.Message, state: FSMContext, album: list f"Вызов функции suggest_router. Пользователь: {message.from_user.id} Имя автора сообщения: {message.from_user.full_name}") try: if message.content_type == 'text': + print(message.content_type) lower_text = message.text.lower() # Получаем текст сообщения и преобразовываем его по правилам post_text = get_text_message(lower_text, message.from_user.full_name, @@ -179,6 +180,7 @@ async def suggest_router(message: types.Message, state: FSMContext, album: list await state.set_state("START") elif message.content_type == 'photo' and message.media_group_id is None: + print(message.content_type) lower_caption = message.caption.lower() markup = get_reply_keyboard_for_post() # Получаем текст сообщения и преобразовываем его по правилам @@ -197,7 +199,10 @@ async def suggest_router(message: types.Message, state: FSMContext, album: list elif message.media_group_id is not None: post_caption = " " - #TODO: Поставить запрет на обработку любых типов кроме photo. Запретить работать с forward message + if message.content_type != 'photo': + await message.bot.send_message(message.chat.id, + 'Я пока не умею работать с таким сообщением. ' + 'Пришли текст и фото/фоты(ы)') # Получаем сообщение и проверяем есть ли подпись. Если подпись есть, то преобразуем ее через функцию if album[0].caption: @@ -217,7 +222,7 @@ async def suggest_router(message: types.Message, state: FSMContext, album: list help_message_id = await send_text_message(GROUP_FOR_POST, message, "^", markup) # Записываем в state идентификаторы текстового сообщения И последнего сообщения медиагруппы - await state.update_data(media_group_message_id=media_group_message_id, help_message_id=help_message_id) + BotDB.update_helper_message_in_db(message_id=media_group_message_id, helper_message_id=help_message_id) # Получаем клавиатуру для пользователя, благодарим за пост, и возвращаем в дефолтное сообщение markup_for_user = get_reply_keyboard(BotDB, message.from_user.id) @@ -225,6 +230,7 @@ async def suggest_router(message: types.Message, state: FSMContext, album: list await message.answer(success_send_message, reply_markup=markup_for_user) await state.set_state("START") else: + print(f'Тип: {message.content_type}') await message.bot.send_message(message.chat.id, 'Я пока не умею работать с таким сообщением. Пришли текст и фото/фоты(ы)') except Exception as e: diff --git a/helper_bot/utils/__pycache__/base_dependency_factory.cpython-312.pyc b/helper_bot/utils/__pycache__/base_dependency_factory.cpython-312.pyc index 6701f6c..f818b5d 100644 Binary files a/helper_bot/utils/__pycache__/base_dependency_factory.cpython-312.pyc and b/helper_bot/utils/__pycache__/base_dependency_factory.cpython-312.pyc differ diff --git a/helper_bot/utils/__pycache__/helper_func.cpython-312.pyc b/helper_bot/utils/__pycache__/helper_func.cpython-312.pyc index ca80510..5ed8989 100644 Binary files a/helper_bot/utils/__pycache__/helper_func.cpython-312.pyc and b/helper_bot/utils/__pycache__/helper_func.cpython-312.pyc differ diff --git a/helper_bot/utils/base_dependency_factory.py b/helper_bot/utils/base_dependency_factory.py index 392ac95..988ebe3 100644 --- a/helper_bot/utils/base_dependency_factory.py +++ b/helper_bot/utils/base_dependency_factory.py @@ -4,6 +4,8 @@ import sys from database.db import BotDB +current_dir = os.getcwd() + class BaseDependencyFactory: def __init__(self): @@ -12,7 +14,7 @@ class BaseDependencyFactory: self.config = configparser.ConfigParser() self.config.read(config_path) self.settings = {} - self.database = BotDB('database/tg-bot-database') + self.database = BotDB(current_dir, 'database/tg-bot-database') for section in self.config.sections(): self.settings[section] = {} diff --git a/helper_bot/utils/helper_func.py b/helper_bot/utils/helper_func.py index 2d800cb..b062cdc 100644 --- a/helper_bot/utils/helper_func.py +++ b/helper_bot/utils/helper_func.py @@ -85,28 +85,26 @@ async def prepare_media_group_from_middlewares(album, post_caption: str = ''): return media_group # Возвращаем MediaGroup -async def add_in_db_media(sent_message, post_caption: str = ''): +async def add_in_db_media(sent_message): """ Идентификатор медиа-группы Args: - sent_message: sent_message объект из Telegram API. - post_caption: Текст подписи к первому фото. + sent_message: sent_message объект из Telegram API Returns: Список InputMediaPhoto. """ - media_group_message_id = sent_message[0].message_id # Получаем идентификатор медиа-группы + media_group_message_id = sent_message[-1].message_id # Получаем идентификатор медиа-группы for i, message in enumerate(sent_message): file_id = message.photo[-1].file_id file_path = await download_photo(message, file_id=file_id) if i == 0: - BotDB.add_post_from_telegram_in_db(media_group_message_id, message.message_id, 0, file_path, post_caption) + BotDB.add_post_content_in_db(media_group_message_id, message.message_id, file_path) elif i == len(sent_message) - 1: - BotDB.add_post_from_telegram_in_db(media_group_message_id, message.message_id, 1, file_path, post_caption) + BotDB.add_post_content_in_db(media_group_message_id, message.message_id, file_path) else: - BotDB.add_post_from_telegram_in_db(media_group_message_id, message.message_id, 0, file_path, post_caption) - return media_group_message_id + BotDB.add_post_content_in_db(media_group_message_id, message.message_id, file_path) async def send_media_group_message_to_private_chat(chat_id: int, message: types.Message, @@ -115,7 +113,8 @@ async def send_media_group_message_to_private_chat(chat_id: int, message: types. chat_id=chat_id, media=media_group, ) - await add_in_db_media(sent_message, post_caption=sent_message[-1].caption) + BotDB.add_post_in_db(sent_message[-1].message_id, sent_message[-1].caption, message.from_user.id) + await add_in_db_media(sent_message) message_id = sent_message[-1].message_id return message_id diff --git a/migrations/000_migrations_init.py b/migrations/000_migrations_init.py index db2a995..cc3374e 100644 --- a/migrations/000_migrations_init.py +++ b/migrations/000_migrations_init.py @@ -1,17 +1,14 @@ import os -from helper_bot.utils.base_dependency_factory import BaseDependencyFactory -# Получаем текущий рабочий каталог -current_dir = os.path.dirname(os.path.abspath(__file__)) +from database.db import BotDB -# Переходим на уровень выше, чтобы выйти из папки migrations/ +# Получаем текущую директорию +current_dir = os.path.dirname(__file__) + +# Переходим на уровень выше parent_dir = os.path.dirname(current_dir) -# Строим путь до файла -tg_bot_database_path = os.path.join(parent_dir, "tg-bot-database") - -bdf = BaseDependencyFactory() -BotDB = bdf.get_db() +BotDB = BotDB(parent_dir, 'database/tg-bot-database') def get_filename(): @@ -32,5 +29,6 @@ def main(): BotDB.create_table(migrations_init) BotDB.update_version(0, get_filename()) + if __name__ == "__main__": main() diff --git a/migrations/001_create_new_tables.py b/migrations/001_create_new_tables.py index c367ba3..9bc06f9 100644 --- a/migrations/001_create_new_tables.py +++ b/migrations/001_create_new_tables.py @@ -1,8 +1,14 @@ import os -from helper_bot.utils.base_dependency_factory import BaseDependencyFactory -bdf = BaseDependencyFactory() -BotDB = bdf.get_db() +from database.db import BotDB + +# Получаем текущую директорию +current_dir = os.path.dirname(__file__) + +# Переходим на уровень выше +parent_dir = os.path.dirname(current_dir) + +BotDB = BotDB(parent_dir, 'database/tg-bot-database') def get_filename(): diff --git a/migrations/002_create_tables_media_group.py b/migrations/002_create_tables_media_group.py new file mode 100644 index 0000000..2c4e382 --- /dev/null +++ b/migrations/002_create_tables_media_group.py @@ -0,0 +1,60 @@ +import os + +from database.db import BotDB + +# Получаем текущую директорию +current_dir = os.path.dirname(__file__) + +# Переходим на уровень выше +parent_dir = os.path.dirname(current_dir) + +BotDB = BotDB(parent_dir, 'database/tg-bot-database') + + +def get_filename(): + """Возвращает имя файла без расширения.""" + filename = os.path.basename(__file__) + filename = os.path.splitext(filename)[0] + return filename + + +def main(): + # Проверка версии миграций + current_version = BotDB.get_current_version() # Добавьте функцию для получения версии + + # Выполнение миграций и проверка последней версии + if current_version < 2: + # Скрипты миграции + create_table_sql_1 = """ + CREATE TABLE IF NOT EXISTS "post_from_telegram_suggest" + ( + message_id INTEGER not null, + text TEXT, + helper_text_message_id INTEGER, + author_id INTEGER, + created_at TEXT + ); + """ + create_table_sql_2 = """ + CREATE TABLE IF NOT EXISTS message_link_to_content ( + post_id INTEGER NOT NULL, + message_id INTEGER NOT NULL + ); + """ + create_table_sql_3 = """ + CREATE TABLE IF NOT EXISTS content_post_from_telegram ( + message_id INTEGER NOT NULL, + content_name TEXT NOT NULL + ); + """ + # Применение миграции + BotDB.create_table(create_table_sql_1) + BotDB.create_table(create_table_sql_2) + BotDB.create_table(create_table_sql_3) + filename = get_filename() + + BotDB.update_version(2, filename) + + +if __name__ == "__main__": + main() diff --git a/run_helper.py b/run_helper.py index efa1bb1..d7fa497 100644 --- a/run_helper.py +++ b/run_helper.py @@ -1,7 +1,7 @@ import asyncio + from helper_bot.main import start_bot from helper_bot.utils.base_dependency_factory import BaseDependencyFactory - if __name__ == '__main__': - asyncio.run(start_bot(BaseDependencyFactory())) \ No newline at end of file + asyncio.run(start_bot(BaseDependencyFactory()))