diff --git a/database/db.py b/database/db.py index d5923bf..bd3c13c 100644 --- a/database/db.py +++ b/database/db.py @@ -856,11 +856,31 @@ class BotDB: result = self.cursor.execute("SELECT content_name " "FROM posts_from_telegram WHERE group_message_id = ?", (main_post,)) 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() + def get_post_ids_from_telegram_by_last_id(self, last_post_id: int): + self.logger.info( + 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] + 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() + def get_post_text_from_telegram_by_last_id(self, last_post_id: int): self.logger.info(f"Запуск функции get_post_text_from_telegram_by_last_id, идентификатор поста {last_post_id}") try: diff --git a/helper_bot/handlers/callback/callback_handlers.py b/helper_bot/handlers/callback/callback_handlers.py index 888b4e9..66003a2 100644 --- a/helper_bot/handlers/callback/callback_handlers.py +++ b/helper_bot/handlers/callback/callback_handlers.py @@ -8,7 +8,7 @@ from helper_bot.keyboards.main import create_keyboard_with_pagination, get_reply create_keyboard_for_ban_reason from helper_bot.utils.base_dependency_factory import BaseDependencyFactory from helper_bot.utils.helper_func import send_text_message, send_photo_message, get_banned_users_list, \ - get_banned_users_buttons, delete_user_blacklist, get_help_message_id, send_media_group_with_caption + get_banned_users_buttons, delete_user_blacklist, get_help_message_id, send_media_group_to_channel from logs.custom_logger import logger callback_router = Router() @@ -56,21 +56,35 @@ async def post_for_group(call: CallbackQuery, state: FSMContext): await call.answer(text='Что-то пошло не так!', show_alert=True, cache_time=3) elif call.message.text == "^": user_data = await state.get_data() - # Получил идентификатор последнего предложенного сообщения из кэша + + # Получаем идентификатор последнего предложенного сообщения из кэша help_message = get_help_message_id(call.message.message_id, user_data) - media_group_id = help_message-1 + + # Получаем идентификатор медиагруппы + 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) - await send_media_group_with_caption(bot=call.bot, chat_id=MAIN_PUBLIC, post_content=post_content, post_text=post_text) - await call.answer(text='Выложено!', show_alert=True, cache_time=3) + post_ids = BotDB.get_post_ids_from_telegram_by_last_id(media_group_id) + # Преобразуем результат в список + message_ids = [row[0] for row in post_ids] + + # Добавляем help_message в список + message_ids.append(help_message) + + # Выкладываем пост в канал + await send_media_group_to_channel(bot=call.bot, chat_id=MAIN_PUBLIC, post_content=post_content, + post_text=post_text) + await call.bot.delete_messages(chat_id=GROUP_FOR_POST, message_ids=message_ids) + await call.answer(text='Выложено!', show_alert=True, cache_time=3) @callback_router.callback_query( F.data == "decline" ) async def decline_post_for_group(call: CallbackQuery, state: FSMContext): - logger.info( f'Получен callback-запрос с данными: {call.data} от пользователя {call.from_user.full_name} (ID: {call.from_user.id})') try: @@ -150,12 +164,12 @@ async def change_page(call: CallbackQuery): await call.bot.edit_message_reply_markup(chat_id=call.message.chat.id, message_id=call.message.message_id, reply_markup=keyboard) else: - #Готовим сообщения + # Готовим сообщения message_user = get_banned_users_list(int(page_number) * 7 - 7) await call.bot.edit_message_text(chat_id=call.message.chat.id, message_id=call.message.message_id, text=message_user) - #Готовим клавиатуру + # Готовим клавиатуру buttons = get_banned_users_buttons() keyboard = create_keyboard_with_pagination(int(call.data[5:]), len(buttons), buttons, 'unlock') await call.bot.edit_message_reply_markup(chat_id=call.message.chat.id, message_id=call.message.message_id, diff --git a/helper_bot/handlers/private/private_handlers.py b/helper_bot/handlers/private/private_handlers.py index 7821d27..b3e51fa 100644 --- a/helper_bot/handlers/private/private_handlers.py +++ b/helper_bot/handlers/private/private_handlers.py @@ -17,10 +17,9 @@ from helper_bot.middlewares.blacklist_middleware import BlacklistMiddleware from helper_bot.utils import messages from helper_bot.utils.base_dependency_factory import BaseDependencyFactory from helper_bot.utils.helper_func import get_first_name, get_text_message, send_text_message, send_photo_message, \ - send_media_group_message, process_photo_album, check_username_and_full_name + send_media_group_message_to_private_chat, prepare_media_group_from_middlewares, check_username_and_full_name from logs.custom_logger import logger - private_router = Router() private_router.message.middleware(AlbumMiddleware()) @@ -65,8 +64,10 @@ async def handle_start_message(message: types.Message, state: FSMContext): is_need_update = check_username_and_full_name(user_id, username, full_name) if is_need_update: BotDB.update_username_and_full_name(user_id, username, full_name) - await message.answer(f"Давно не виделись! Вижу что ты изменился;) Теперь буду звать тебя: {full_name} и ник @{username}") - await message.bot.send_message(chat_id=GROUP_FOR_LOGS, text=f'Для пользователя: {user_id} обновлены данные в БД.\nНовое имя: {full_name}\nНовый ник:{username}') + await message.answer( + f"Давно не виделись! Вижу что ты изменился;) Теперь буду звать тебя: {full_name} и ник @{username}") + await message.bot.send_message(chat_id=GROUP_FOR_LOGS, + text=f'Для пользователя: {user_id} обновлены данные в БД.\nНовое имя: {full_name}\nНовый ник:{username}') sleep(1) BotDB.update_date_for_user(date, user_id) await state.set_state("START") @@ -161,57 +162,63 @@ async def suggest_router(message: types.Message, state: FSMContext, album: list try: if message.content_type == 'text': lower_text = message.text.lower() - post_text, is_anonymous = get_text_message(lower_text, message.from_user.full_name, - message.from_user.username) + # Получаем текст сообщения и преобразовываем его по правилам + post_text = get_text_message(lower_text, message.from_user.full_name, + message.from_user.username) + + # Получаем клавиатуру для поста markup = get_reply_keyboard_for_post() - if is_anonymous: - await send_text_message(GROUP_FOR_POST, message, post_text, markup) - else: - await send_text_message(GROUP_FOR_POST, message, post_text, markup) + + # Отправляем сообщение в приватный канал + await send_text_message(GROUP_FOR_POST, message, post_text, markup) + + # Отправляем юзеру ответ, что сообщение отравлено и возвращаем его в меню markup_for_user = get_reply_keyboard(BotDB, message.from_user.id) success_send_message = messages.get_message(get_first_name(message), 'SUCCESS_SEND_MESSAGE') await message.answer(success_send_message, reply_markup=markup_for_user) await state.set_state("START") + elif message.content_type == 'photo' and message.media_group_id is None: lower_caption = message.caption.lower() markup = get_reply_keyboard_for_post() - post_caption, is_anonymous = get_text_message(lower_caption, message.from_user.full_name, - message.from_user.username) - #TODO: тут какая-то шляпа - if is_anonymous: - await send_photo_message(GROUP_FOR_POST, message, - message.photo[-1].file_id, post_caption, markup) - else: - await send_photo_message(GROUP_FOR_POST, message, - message.photo[-1].file_id, post_caption, markup) + # Получаем текст сообщения и преобразовываем его по правилам + post_caption = get_text_message(lower_caption, message.from_user.full_name, + message.from_user.username) + + # Отправляем фото и текст в приватный канал + await send_photo_message(GROUP_FOR_POST, message, + message.photo[-1].file_id, post_caption, markup) + + # Отправляем юзеру ответ и возвращаем его в меню markup_for_user = get_reply_keyboard(BotDB, message.from_user.id) success_send_message = messages.get_message(get_first_name(message), 'SUCCESS_SEND_MESSAGE') await message.answer(success_send_message, reply_markup=markup_for_user) await state.set_state("START") + elif message.media_group_id is not None: post_caption = " " # Получаем сообщение и проверяем есть ли подпись. Если подпись есть, то преобразуем ее через функцию if album[0].caption: lower_caption = album[0].caption.lower() - post_caption, is_anonymous = get_text_message(lower_caption, message.from_user.full_name, - message.from_user.username) + post_caption = get_text_message(lower_caption, message.from_user.full_name, + message.from_user.username) - #Иначе обрабатываем фото и получаем медиагруппу - media_group = await process_photo_album(album, post_caption) + # Иначе обрабатываем фото и получаем медиагруппу + media_group = await prepare_media_group_from_middlewares(album, post_caption) - #Отправляем медиагруппу в секретный чат - media_group_message_id = await send_media_group_message(GROUP_FOR_POST, message, media_group) + # Отправляем медиагруппу в секретный чат + media_group_message_id = await send_media_group_message_to_private_chat(GROUP_FOR_POST, message, media_group) sleep(0.2) - #Получаем клавиатуру и отправляем еще одно текстовое сообщение с кнопками + # Получаем клавиатуру и отправляем еще одно текстовое сообщение с кнопками markup = get_reply_keyboard_for_post() help_message_id = await send_text_message(GROUP_FOR_POST, message, "^", markup) - #Записываем в state идентификаторы текстового сообщения И последнего сообщения медиагруппы + # Записываем в state идентификаторы текстового сообщения И последнего сообщения медиагруппы await state.update_data(media_group_message_id=media_group_message_id, help_message_id=help_message_id) - #Получаем клавиатуру для пользователя, благодарим за пост, и возвращаем в дефолтное сообщение + # Получаем клавиатуру для пользователя, благодарим за пост, и возвращаем в дефолтное сообщение markup_for_user = get_reply_keyboard(BotDB, message.from_user.id) success_send_message = messages.get_message(get_first_name(message), 'SUCCESS_SEND_MESSAGE') await message.answer(success_send_message, reply_markup=markup_for_user) @@ -283,11 +290,3 @@ async def resend_message_in_group_for_message(message: types.Message, state: FSM elif user_state == "CHAT": markup = get_reply_keyboard_leave_chat() await message.answer(question, reply_markup=markup) - -# @private_router.message( -# ChatTypeFilter(chat_type=["private"]) -# ) -# async def default(message: types.Message, state: FSMContext): -# markup = get_reply_keyboard(BotDB, message.from_user.id) -# await message.answer('Кажется ты заблудился. Держи клавиатуру, твое состояние сброшено на начало', reply_markup=markup) -# await state.set_state("START") diff --git a/helper_bot/keyboards/__pycache__/main.cpython-312.pyc b/helper_bot/keyboards/__pycache__/main.cpython-312.pyc index 08b8286..7c259e9 100644 Binary files a/helper_bot/keyboards/__pycache__/main.cpython-312.pyc and b/helper_bot/keyboards/__pycache__/main.cpython-312.pyc differ diff --git a/helper_bot/keyboards/main.py b/helper_bot/keyboards/main.py index 41e238a..9318b99 100644 --- a/helper_bot/keyboards/main.py +++ b/helper_bot/keyboards/main.py @@ -5,9 +5,10 @@ from aiogram.utils.keyboard import ReplyKeyboardBuilder, InlineKeyboardBuilder def get_reply_keyboard_for_post(): builder = InlineKeyboardBuilder() builder.row(types.InlineKeyboardButton( - text="Опубликовать", callback_data="publish"), - types.InlineKeyboardButton( - text="Отклонить", callback_data="decline") + text="Опубликовать", callback_data="publish") + ) + builder.row(types.InlineKeyboardButton( + text="Отклонить", callback_data="decline") ) markup = builder.as_markup(resize_keyboard=True, one_time_keyboard=True) return markup diff --git a/helper_bot/utils/__pycache__/helper_func.cpython-312.pyc b/helper_bot/utils/__pycache__/helper_func.cpython-312.pyc index 229091a..ca80510 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/helper_func.py b/helper_bot/utils/helper_func.py index 9dbd94b..2d800cb 100644 --- a/helper_bot/utils/helper_func.py +++ b/helper_bot/utils/helper_func.py @@ -27,17 +27,14 @@ def get_text_message(post_text: str, first_name: str, username: str): Returns: Кортеж из двух элементов: - Сформированный текст сообщения. - - Флаг, указывающий, является ли пост анонимным (True - анонимный, False - не анонимный). + - Флаг, указывающий, является ли пост анонимным (True - анонимный, False - не анонимный) """ if "неанон" in post_text or "не анон" in post_text: - is_anonymous = False - return f'Пост из ТГ:\n{post_text}\n\nАвтор поста: {first_name} @{username}', is_anonymous + return f'Пост из ТГ:\n{post_text}\n\nАвтор поста: {first_name} @{username}' elif "анон" in post_text: - is_anonymous = True - return f'Пост из ТГ:\n{post_text}\n\nПост опубликован анонимно', is_anonymous + return f'Пост из ТГ:\n{post_text}\n\nПост опубликован анонимно' else: - is_anonymous = False - return f'Пост из ТГ:\n{post_text}\n\nАвтор поста: {first_name} @{username}', is_anonymous + return f'Пост из ТГ:\n{post_text}\n\nАвтор поста: {first_name} @{username}' async def download_photo(message: types.Message, file_id: str): @@ -46,11 +43,11 @@ async def download_photo(message: types.Message, file_id: str): Args: message: сообщение - file_id: File ID фотографии. - filename: Имя файла, под которым будет сохранено фото. + file_id: File ID фотографии + filename: Имя файла, под которым будет сохранено фото Returns: - Путь к сохраненному файлу, если файл был скачан успешно, иначе None. + Путь к сохраненному файлу, если файл был скачан успешно, иначе None """ try: file = await message.bot.get_file(file_id) @@ -62,29 +59,30 @@ async def download_photo(message: types.Message, file_id: str): return None -async def process_photo_album(album, post_caption: str = ''): +async def prepare_media_group_from_middlewares(album, post_caption: str = ''): """ - Создает список InputMediaPhoto для альбома. + Создает MediaGroup. Args: album: Album объект из Telegram API. post_caption: Текст подписи к первому фото. Returns: - Список InputMediaPhoto. + Список InputMediaPhoto (MediaGroup). """ - photo_media = [] - #Циклом проходимся по собранному миддлварью объекту album + media_group = [] + # Циклом проходимся по собранному миддлварью объекту album + for i, message in enumerate(album): file_id = message.photo[-1].file_id - file_path = await download_photo(message, file_id=file_id) + # Если это последняя фото в массиве, то добавляем подпись. Остальные фото просто преобразуем в InputMediaPhoto # и формируем объект MediaGroup if i == len(album) - 1: - photo_media.append(InputMediaPhoto(media=message.photo[-1].file_id, caption=post_caption)) + media_group.append(InputMediaPhoto(media=file_id, caption=post_caption)) else: - photo_media.append(InputMediaPhoto(media=message.photo[-1].file_id)) - return photo_media # Возвращаем идентификатор медиа-группы + media_group.append(InputMediaPhoto(media=file_id)) + return media_group # Возвращаем MediaGroup async def add_in_db_media(sent_message, post_caption: str = ''): @@ -111,7 +109,8 @@ async def add_in_db_media(sent_message, post_caption: str = ''): return media_group_message_id -async def send_media_group_message(chat_id: int, message: types.Message, media_group: list[InputMediaPhoto]): +async def send_media_group_message_to_private_chat(chat_id: int, message: types.Message, + media_group: list[InputMediaPhoto]): sent_message = await message.bot.send_media_group( chat_id=chat_id, media=media_group, @@ -121,7 +120,7 @@ async def send_media_group_message(chat_id: int, message: types.Message, media_g return message_id -async def send_media_group_with_caption(bot, chat_id: int, post_content: list[tuple[str]], post_text: str): +async def send_media_group_to_channel(bot, chat_id: int, post_content: list[tuple[str]], post_text: str): """ Отправляет медиа-группу с подписью к последнему файлу. @@ -165,7 +164,8 @@ async def send_text_message(chat_id, message: types.Message, post_text: str, mar return message_id -async def send_photo_message(chat_id, message: types.Message, photo: str, post_text: str, markup: types.ReplyKeyboardMarkup = None): +async def send_photo_message(chat_id, message: types.Message, photo: str, post_text: str, + markup: types.ReplyKeyboardMarkup = None): if markup is None: await message.bot.send_photo( chat_id=chat_id, @@ -271,4 +271,4 @@ def unban_notifier(self): message += f"ID: {user_id}, Имя: {user_name}\n" # Отправка сообщения в канал - self.bot.send_message(self.GROUP_FOR_MESSAGE, message) \ No newline at end of file + self.bot.send_message(self.GROUP_FOR_MESSAGE, message)