Merge pull request #8 from KerradKerridi/merge-voice-1
Merge voice 1
This commit was merged in pull request #8.
This commit is contained in:
233
database/db.py
233
database/db.py
@@ -111,27 +111,8 @@ class BotDB:
|
|||||||
finally:
|
finally:
|
||||||
self.close()
|
self.close()
|
||||||
|
|
||||||
# TODO: Deprecated. Остался только в voice боте, удалить и оттуда
|
|
||||||
def get_error_message_from_db(self, id: int):
|
|
||||||
"""
|
|
||||||
@deprecated
|
|
||||||
Функция для запроса к базе данных и получения сообщений ошибки. В аргументы передаются:
|
|
||||||
id - идентификатор ошибки
|
|
||||||
"""
|
|
||||||
# Подключаемся к базе
|
|
||||||
try:
|
|
||||||
self.connect()
|
|
||||||
self.cursor.execute(f"SELECT * FROM error_messages WHERE id=?", (id,))
|
|
||||||
response_from_database = str(self.cursor.fetchone()[1])
|
|
||||||
return response_from_database
|
|
||||||
except sqlite3.Error as error:
|
|
||||||
self.logger.error(f"Ошибка при получении сообщения об ошибка voice_bot: {error}")
|
|
||||||
finally:
|
|
||||||
self.close()
|
|
||||||
|
|
||||||
def add_new_user_in_db(self, user_id: int, first_name: str, full_name: str, username: str, is_bot: bool,
|
def add_new_user_in_db(self, user_id: int, first_name: str, full_name: str, username: str, is_bot: bool,
|
||||||
language_code: str, date_added: str,
|
language_code: str, emoji: str, date_added: str, date_changed: str):
|
||||||
date_changed: str):
|
|
||||||
"""
|
"""
|
||||||
Добавляет нового пользователя в базу данных.
|
Добавляет нового пользователя в базу данных.
|
||||||
|
|
||||||
@@ -142,6 +123,7 @@ class BotDB:
|
|||||||
username (str): Username пользователя в Telegram.
|
username (str): Username пользователя в Telegram.
|
||||||
is_bot (bool): Флаг, указывающий, является ли пользователь ботом.
|
is_bot (bool): Флаг, указывающий, является ли пользователь ботом.
|
||||||
language_code (str): Код языка пользователя.
|
language_code (str): Код языка пользователя.
|
||||||
|
emoji (str): Эмодзи закрепленная за пользователем
|
||||||
date_added (str): Дата добавления пользователя в базу.
|
date_added (str): Дата добавления пользователя в базу.
|
||||||
date_changed (str): Дата последнего изменения данных пользователя.
|
date_changed (str): Дата последнего изменения данных пользователя.
|
||||||
|
|
||||||
@@ -152,12 +134,26 @@ class BotDB:
|
|||||||
self.logger.info(f"Попытка добавить пользователя в базу данных: user_id={user_id}, first_name={first_name}")
|
self.logger.info(f"Попытка добавить пользователя в базу данных: user_id={user_id}, first_name={first_name}")
|
||||||
try:
|
try:
|
||||||
self.connect()
|
self.connect()
|
||||||
self.cursor.execute("INSERT INTO 'our_users' ('user_id', 'first_name', 'full_name', 'username', 'is_bot', "
|
try:
|
||||||
|
# Новая схема с колонкой emoji
|
||||||
|
self.cursor.execute(
|
||||||
|
"INSERT INTO 'our_users' ('user_id', 'first_name', 'full_name', 'username', 'is_bot', "
|
||||||
|
"'language_code', 'emoji', 'date_added', 'date_changed') VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||||
|
(user_id, first_name, full_name, username, is_bot, language_code, emoji, date_added, date_changed)
|
||||||
|
)
|
||||||
|
except sqlite3.OperationalError as e:
|
||||||
|
# Обратная совместимость: старая схема без колонки emoji
|
||||||
|
if 'no column named emoji' in str(e):
|
||||||
|
self.cursor.execute(
|
||||||
|
"INSERT INTO 'our_users' ('user_id', 'first_name', 'full_name', 'username', 'is_bot', "
|
||||||
"'language_code', 'date_added', 'date_changed') VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
|
"'language_code', 'date_added', 'date_changed') VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
|
||||||
(user_id, first_name, full_name,
|
(user_id, first_name, full_name, username, is_bot, language_code, date_added, date_changed)
|
||||||
username, is_bot, language_code, date_added, date_changed))
|
)
|
||||||
|
else:
|
||||||
|
raise
|
||||||
self.conn.commit()
|
self.conn.commit()
|
||||||
self.logger.info(f"Новый пользователь добавлен в базу: user_id={user_id}, first_name={first_name}")
|
self.logger.info(
|
||||||
|
f"Новый пользователь добавлен в базу: user_id={user_id}, first_name={first_name}, emoji={emoji}")
|
||||||
return None
|
return None
|
||||||
except sqlite3.Error as error:
|
except sqlite3.Error as error:
|
||||||
self.logger.error(f"Ошибка при добавлении пользователя в базу: {error}. "
|
self.logger.error(f"Ошибка при добавлении пользователя в базу: {error}. "
|
||||||
@@ -720,15 +716,15 @@ class BotDB:
|
|||||||
def update_date_for_user(self, date: str, user_id: int):
|
def update_date_for_user(self, date: str, user_id: int):
|
||||||
"""
|
"""
|
||||||
#TODO: Не возвращается ошибка sqlite3. Error. Тест не перехватывает. Возвращается no such table: our_users
|
#TODO: Не возвращается ошибка sqlite3. Error. Тест не перехватывает. Возвращается no such table: our_users
|
||||||
Обновляет дату последнего изменения данных пользователя в базе.
|
Обновляет дату последнего изменения данных пользователя в базе
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
date (str): Новая дата изменения.
|
date (str): Новая дата изменения
|
||||||
user_id (int): Идентификатор пользователя в Telegram.
|
user_id (int): Идентификатор пользователя в Telegram
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
None: Если обновление прошло успешно.
|
None: Если обновление прошло успешно
|
||||||
sqlite3. Error: Если произошла ошибка при выполнении запроса.
|
sqlite3. Error: Если произошла ошибка при выполнении запроса
|
||||||
"""
|
"""
|
||||||
self.logger.info(f"Запуск функции update_date_for_user: user_id={user_id}, date={date}")
|
self.logger.info(f"Запуск функции update_date_for_user: user_id={user_id}, date={date}")
|
||||||
try:
|
try:
|
||||||
@@ -744,6 +740,107 @@ class BotDB:
|
|||||||
finally:
|
finally:
|
||||||
self.close()
|
self.close()
|
||||||
|
|
||||||
|
def check_emoji(self, emoji: str):
|
||||||
|
"""
|
||||||
|
Проверяет, есть ли уже такой emoji в таблице.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
emoji: emoji для проверки.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
True, если эмодзи уже есть, иначе False.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
None: В случае ошибки возвращается None
|
||||||
|
"""
|
||||||
|
self.logger.info(f"Запуск функции check_emoji: emoji={emoji}")
|
||||||
|
try:
|
||||||
|
self.connect()
|
||||||
|
self.cursor.execute("SELECT 1 FROM our_users WHERE emoji = ?", (emoji,))
|
||||||
|
result = self.cursor.fetchone()
|
||||||
|
return bool(result)
|
||||||
|
except sqlite3.Error as error:
|
||||||
|
self.logger.error(f"Ошибка проверки эмодзи в базе: {error}")
|
||||||
|
return None
|
||||||
|
finally:
|
||||||
|
self.close()
|
||||||
|
|
||||||
|
def update_emoji_for_user(self, user_id: int, emoji: str):
|
||||||
|
"""
|
||||||
|
Обновляет эмодзи для пользователя в базе если его ранее не было установлено
|
||||||
|
|
||||||
|
Args:
|
||||||
|
user_id (int): Идентификатор пользователя в Telegram
|
||||||
|
emoji (str): Эмодзи пользователя
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None: Если обновление прошло успешно
|
||||||
|
sqlite3. Error: Если произошла ошибка при выполнении запроса
|
||||||
|
"""
|
||||||
|
self.logger.info(f"Запуск функции update_emoji_for_user: user_id={user_id}, emoji={emoji}")
|
||||||
|
try:
|
||||||
|
self.connect()
|
||||||
|
self.cursor.execute("UPDATE our_users SET emoji = ? WHERE user_id = ?",
|
||||||
|
(emoji, user_id,))
|
||||||
|
self.conn.commit()
|
||||||
|
self.logger.info(f"Эмоджи обновлен для пользователя: user_id={user_id}")
|
||||||
|
except sqlite3.Error as error:
|
||||||
|
self.logger.error(f"Ошибка обновления эмодзи для пользователя: {error}")
|
||||||
|
return error
|
||||||
|
finally:
|
||||||
|
self.close()
|
||||||
|
|
||||||
|
def check_emoji_for_user(self, user_id: int):
|
||||||
|
"""
|
||||||
|
Проверяет, есть ли уже у пользователя назначенный emoji.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
user_id: user_id пользователя.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
True, если эмодзи такого нет, иначе False.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
error: В случае ошибки возвращается error
|
||||||
|
"""
|
||||||
|
self.logger.info(f"Запуск функции check_emoji_for_user: user_id={user_id}")
|
||||||
|
try:
|
||||||
|
self.connect()
|
||||||
|
self.cursor.execute("SELECT emoji FROM our_users WHERE user_id = ?", (user_id,))
|
||||||
|
pre_result = self.cursor.fetchone()
|
||||||
|
# Возвращаем "Смайл не определен", если pre_result или pre_result[0] is None
|
||||||
|
result = pre_result[0] if pre_result else None
|
||||||
|
return str(result) if result is not None else "Смайл еще не определен"
|
||||||
|
except sqlite3.Error as error:
|
||||||
|
self.logger.error(f"Ошибка проверки эмодзи в базе: {error}")
|
||||||
|
return error
|
||||||
|
finally:
|
||||||
|
self.close()
|
||||||
|
|
||||||
|
def refresh_listen_audio(self, user_id: int):
|
||||||
|
"""
|
||||||
|
Очищает всю информацию о прослушанных аудио пользователем
|
||||||
|
|
||||||
|
Args:
|
||||||
|
user_id: user_id пользователя.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None - если все очищено успешно
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
error: В случае ошибки возвращается error
|
||||||
|
"""
|
||||||
|
self.logger.info(f"Запуск функции check_emoji_for_user: user_id={user_id}")
|
||||||
|
try:
|
||||||
|
self.connect()
|
||||||
|
self.cursor.execute("DELETE FROM listen_audio_users WHERE user_id = ?", (user_id,))
|
||||||
|
return None
|
||||||
|
except sqlite3.Error as error:
|
||||||
|
self.logger.error(f"Ошибка проверки эмодзи в базе: {error}")
|
||||||
|
return error
|
||||||
|
finally:
|
||||||
|
self.close()
|
||||||
|
|
||||||
def is_admin(self, user_id: int):
|
def is_admin(self, user_id: int):
|
||||||
"""
|
"""
|
||||||
Проверяет, является ли пользователь администратором.
|
Проверяет, является ли пользователь администратором.
|
||||||
@@ -764,7 +861,7 @@ class BotDB:
|
|||||||
result = self.cursor.fetchone()
|
result = self.cursor.fetchone()
|
||||||
return bool(result)
|
return bool(result)
|
||||||
except sqlite3.Error as error:
|
except sqlite3.Error as error:
|
||||||
self.logger.error(f"Ошибка добавления сообщения в базу данных: {error}")
|
self.logger.error(f"Ошибка проверки прав пользователя админа: {error}")
|
||||||
return None
|
return None
|
||||||
finally:
|
finally:
|
||||||
self.close()
|
self.close()
|
||||||
@@ -1008,6 +1105,62 @@ class BotDB:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.logger.error(f"Ошибка в функции get_author_id_by_helper_message_id {str(e)}")
|
self.logger.error(f"Ошибка в функции get_author_id_by_helper_message_id {str(e)}")
|
||||||
|
|
||||||
|
def get_user_id_by_message_id_for_voice_bot(self, message_id: int):
|
||||||
|
self.logger.info(f"Запуск функции get_user_id_by_message_id_for_voice_bot, идентификатор поста "
|
||||||
|
f"{message_id}")
|
||||||
|
try:
|
||||||
|
self.connect()
|
||||||
|
result = self.cursor.execute("SELECT user_id "
|
||||||
|
"FROM audio_moderate WHERE message_id = ?",
|
||||||
|
(message_id,))
|
||||||
|
user_id = result.fetchone()[0]
|
||||||
|
self.logger.info(f"Функция get_user_id_by_message_id_for_voice_bot получила author_id {user_id}")
|
||||||
|
return user_id
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.error(f"Ошибка в функции get_user_id_by_message_id_for_voice_bot {str(e)}")
|
||||||
|
|
||||||
|
def set_user_id_and_message_id_for_voice_bot(self, message_id: int, user_id: int):
|
||||||
|
self.logger.info(f"Запуск функции set_user_id_and_message_id_for_voice_bot, идентификатор поста "
|
||||||
|
f"{message_id}, user_id {user_id}")
|
||||||
|
try:
|
||||||
|
self.connect()
|
||||||
|
result = self.cursor.execute(
|
||||||
|
"INSERT INTO audio_moderate (message_id, user_id)"
|
||||||
|
"VALUES (?, ?)", (message_id, user_id))
|
||||||
|
self.conn.commit()
|
||||||
|
self.logger.info(f"Функция set_user_id_and_message_id_for_voice_bot отработала успешно")
|
||||||
|
return True
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.error(f"Ошибка в функции set_user_id_and_message_id_for_voice_bot {str(e)}")
|
||||||
|
|
||||||
|
def get_user_id_by_file_name(self, file_name: str):
|
||||||
|
self.logger.info(f"Запуск функции get_user_id_by_file_name, идентификатор файла "
|
||||||
|
f"{file_name}")
|
||||||
|
try:
|
||||||
|
self.connect()
|
||||||
|
result = self.cursor.execute("SELECT author_id "
|
||||||
|
"FROM audio_message_reference WHERE file_name = ?",
|
||||||
|
(file_name,))
|
||||||
|
user_id = result.fetchone()[0]
|
||||||
|
self.logger.info(f"Функция get_user_id_by_file_name получила user_id {user_id}")
|
||||||
|
return user_id
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.error(f"Ошибка в функции get_user_id_by_file_name {str(e)}")
|
||||||
|
|
||||||
|
def get_date_by_file_name(self, file_name: str):
|
||||||
|
self.logger.info(f"Запуск функции get_date_by_file_name, идентификатор файла "
|
||||||
|
f"{file_name}")
|
||||||
|
try:
|
||||||
|
self.connect()
|
||||||
|
result = self.cursor.execute("SELECT date_added "
|
||||||
|
"FROM audio_message_reference WHERE file_name = ?",
|
||||||
|
(file_name,))
|
||||||
|
date_added = result.fetchone()[0]
|
||||||
|
self.logger.info(f"Функция get_date_by_file_name получила date_added {date_added}")
|
||||||
|
return date_added
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.error(f"Ошибка в функции get_date_by_file_name {str(e)}")
|
||||||
|
|
||||||
def add_post_content_in_db(self, post_id: int, message_id: int, content_name: str, type_content: str):
|
def add_post_content_in_db(self, post_id: int, message_id: int, content_name: str, type_content: str):
|
||||||
self.logger.info(
|
self.logger.info(
|
||||||
f"Запуск функции add_post_content_in_db: post_id={post_id}, message_id={message_id}, "
|
f"Запуск функции add_post_content_in_db: post_id={post_id}, message_id={message_id}, "
|
||||||
@@ -1078,7 +1231,7 @@ class BotDB:
|
|||||||
f"date_added = {date_added}")
|
f"date_added = {date_added}")
|
||||||
return None
|
return None
|
||||||
except sqlite3.Error as error:
|
except sqlite3.Error as error:
|
||||||
print(error)
|
self.logger.error(f"Ошибка при добавлении войса в базу: {error}")
|
||||||
raise
|
raise
|
||||||
finally:
|
finally:
|
||||||
self.close()
|
self.close()
|
||||||
@@ -1118,6 +1271,24 @@ class BotDB:
|
|||||||
finally:
|
finally:
|
||||||
self.close()
|
self.close()
|
||||||
|
|
||||||
|
def delete_listen_count_for_user(self, user_id):
|
||||||
|
"""Удаляет данные о прослушанных пользователем аудио"""
|
||||||
|
self.logger.info(
|
||||||
|
f"Запуск функции delete_listen_count_for_user. user_id={user_id}")
|
||||||
|
try:
|
||||||
|
self.connect()
|
||||||
|
self.cursor.execute("DELETE FROM `listen_audio_users` WHERE `user_id` = ?",
|
||||||
|
(user_id,))
|
||||||
|
self.conn.commit()
|
||||||
|
self.logger.info(
|
||||||
|
f"Функция delete_listen_count_for_user успешно отработала")
|
||||||
|
return None
|
||||||
|
except sqlite3.Error as error:
|
||||||
|
self.logger.error(f"Ошибка удаления записей прослушивания по пользователю: {error}")
|
||||||
|
raise
|
||||||
|
finally:
|
||||||
|
self.close()
|
||||||
|
|
||||||
def get_id_for_audio_record(self, user_id):
|
def get_id_for_audio_record(self, user_id):
|
||||||
"""Получает ID аудио сообщения пользователя"""
|
"""Получает ID аудио сообщения пользователя"""
|
||||||
self.logger.info(
|
self.logger.info(
|
||||||
|
|||||||
@@ -18,8 +18,9 @@ from helper_bot.middlewares.blacklist_middleware import BlacklistMiddleware
|
|||||||
from helper_bot.utils import messages
|
from helper_bot.utils import messages
|
||||||
from helper_bot.utils.base_dependency_factory import get_global_instance
|
from helper_bot.utils.base_dependency_factory import get_global_instance
|
||||||
from helper_bot.utils.helper_func import get_first_name, get_text_message, send_text_message, send_photo_message, \
|
from helper_bot.utils.helper_func import get_first_name, get_text_message, send_text_message, send_photo_message, \
|
||||||
send_media_group_message_to_private_chat, prepare_media_group_from_middlewares, check_username_and_full_name, \
|
send_media_group_message_to_private_chat, prepare_media_group_from_middlewares, send_video_message, \
|
||||||
send_video_message, send_video_note_message, send_audio_message, send_voice_message, add_in_db_media
|
send_video_note_message, send_audio_message, send_voice_message, add_in_db_media, \
|
||||||
|
check_user_emoji, check_username_and_full_name
|
||||||
from logs.custom_logger import logger
|
from logs.custom_logger import logger
|
||||||
|
|
||||||
private_router = Router()
|
private_router = Router()
|
||||||
@@ -42,6 +43,35 @@ BotDB = bdf.get_db()
|
|||||||
# Expose sleep for tests (tests patch helper_bot.handlers.private.private_handlers.sleep)
|
# Expose sleep for tests (tests patch helper_bot.handlers.private.private_handlers.sleep)
|
||||||
sleep = asyncio.sleep
|
sleep = asyncio.sleep
|
||||||
|
|
||||||
|
@private_router.message(
|
||||||
|
ChatTypeFilter(chat_type=["private"]),
|
||||||
|
Command("emoji")
|
||||||
|
)
|
||||||
|
async def handle_emoji_message(message: types.Message, state: FSMContext):
|
||||||
|
await message.forward(chat_id=GROUP_FOR_LOGS)
|
||||||
|
user_emoji = check_user_emoji(message)
|
||||||
|
await state.set_state("START")
|
||||||
|
if user_emoji is not None:
|
||||||
|
await message.answer(f'Твоя эмодзя - {user_emoji}', parse_mode='HTML')
|
||||||
|
|
||||||
|
|
||||||
|
@private_router.message(
|
||||||
|
ChatTypeFilter(chat_type=["private"]),
|
||||||
|
Command("restart")
|
||||||
|
)
|
||||||
|
async def handle_restart_message(message: types.Message, state: FSMContext):
|
||||||
|
try:
|
||||||
|
markup = get_reply_keyboard(BotDB, message.from_user.id)
|
||||||
|
await message.forward(chat_id=GROUP_FOR_LOGS)
|
||||||
|
await state.set_state("START")
|
||||||
|
await update_user_info('love', message)
|
||||||
|
check_user_emoji(message)
|
||||||
|
await message.answer('Я перезапущен!', reply_markup=markup, parse_mode='HTML')
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Произошла ошибка handle_restart_message. Ошибка:{str(e)}")
|
||||||
|
await message.bot.send_message(chat_id=IMPORTANT_LOGS,
|
||||||
|
text=f"Произошла ошибка handle_restart_message: {str(e)}\n\nTraceback:\n{traceback.format_exc()}")
|
||||||
|
|
||||||
|
|
||||||
@private_router.message(
|
@private_router.message(
|
||||||
ChatTypeFilter(chat_type=["private"]),
|
ChatTypeFilter(chat_type=["private"]),
|
||||||
@@ -74,7 +104,8 @@ async def handle_start_message(message: types.Message, state: FSMContext):
|
|||||||
current_date = datetime.now()
|
current_date = datetime.now()
|
||||||
date = current_date.strftime("%Y-%m-%d %H:%M:%S")
|
date = current_date.strftime("%Y-%m-%d %H:%M:%S")
|
||||||
if not BotDB.user_exists(user_id):
|
if not BotDB.user_exists(user_id):
|
||||||
BotDB.add_new_user_in_db(user_id, first_name, full_name, username, is_bot, language_code, date,
|
# Для первоначального добавления эмодзи пока не назначаем (совместимость)
|
||||||
|
BotDB.add_new_user_in_db(user_id, first_name, full_name, username, is_bot, language_code, "", date,
|
||||||
date)
|
date)
|
||||||
else:
|
else:
|
||||||
is_need_update = check_username_and_full_name(user_id, username, full_name, BotDB)
|
is_need_update = check_username_and_full_name(user_id, username, full_name, BotDB)
|
||||||
|
|||||||
@@ -1,13 +1,32 @@
|
|||||||
import html
|
import html
|
||||||
import os
|
import os
|
||||||
|
import random
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
from time import sleep
|
||||||
|
|
||||||
|
try:
|
||||||
|
import emoji as _emoji_lib
|
||||||
|
except Exception:
|
||||||
|
_emoji_lib = None
|
||||||
from aiogram import types
|
from aiogram import types
|
||||||
from aiogram.types import InputMediaPhoto, FSInputFile, InputMediaVideo, InputMediaAudio
|
from aiogram.types import InputMediaPhoto, FSInputFile, InputMediaVideo, InputMediaAudio
|
||||||
|
|
||||||
from helper_bot.utils.base_dependency_factory import BaseDependencyFactory
|
from helper_bot.utils.base_dependency_factory import BaseDependencyFactory, get_global_instance
|
||||||
from logs.custom_logger import logger
|
from logs.custom_logger import logger
|
||||||
|
|
||||||
|
bdf = get_global_instance()
|
||||||
|
BotDB = bdf.get_db()
|
||||||
|
GROUP_FOR_LOGS = bdf.settings['Telegram']['group_for_logs']
|
||||||
|
|
||||||
|
if _emoji_lib is not None:
|
||||||
|
emoji_list = list(_emoji_lib.EMOJI_DATA.keys())
|
||||||
|
else:
|
||||||
|
# Fallback minimal emoji set for environments without the 'emoji' package (e.g., CI tests)
|
||||||
|
emoji_list = [
|
||||||
|
"🙂", "😀", "😉", "😎", "🤖", "🦄", "🐱", "🐶", "🍀", "🔥",
|
||||||
|
"🌟", "🎉", "💡", "🚀", "🌈"
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
def safe_html_escape(text: str) -> str:
|
def safe_html_escape(text: str) -> str:
|
||||||
"""
|
"""
|
||||||
@@ -458,3 +477,52 @@ def unban_notifier(self):
|
|||||||
|
|
||||||
# Отправка сообщения в канал
|
# Отправка сообщения в канал
|
||||||
self.bot.send_message(self.GROUP_FOR_MESSAGE, message)
|
self.bot.send_message(self.GROUP_FOR_MESSAGE, message)
|
||||||
|
|
||||||
|
|
||||||
|
async def update_user_info(source: str, message: types.Message):
|
||||||
|
# Собираем данные
|
||||||
|
full_name = message.from_user.full_name
|
||||||
|
username = message.from_user.username
|
||||||
|
first_name = get_first_name(message)
|
||||||
|
is_bot = message.from_user.is_bot
|
||||||
|
language_code = message.from_user.language_code
|
||||||
|
user_id = message.from_user.id
|
||||||
|
current_date = datetime.now()
|
||||||
|
date = current_date.strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
# Выбираем эмодзю, пробегаемся циклом и смотрим что в базе такого еще не было
|
||||||
|
user_emoji = get_random_emoji()
|
||||||
|
|
||||||
|
if not BotDB.user_exists(user_id):
|
||||||
|
BotDB.add_new_user_in_db(user_id, first_name, full_name, username, is_bot, language_code, user_emoji, date,
|
||||||
|
date)
|
||||||
|
else:
|
||||||
|
is_need_update = check_username_and_full_name(user_id, username, full_name, BotDB)
|
||||||
|
if is_need_update:
|
||||||
|
BotDB.update_username_and_full_name(user_id, username, full_name)
|
||||||
|
if source != 'voice':
|
||||||
|
await message.answer(
|
||||||
|
f"Давно не виделись! Вижу что ты изменился;) Теперь буду звать тебя: {full_name}")
|
||||||
|
await message.bot.send_message(chat_id=GROUP_FOR_LOGS,
|
||||||
|
text=f'Для пользователя: {user_id} обновлены данные в БД.\nНовое имя: {full_name}\nНовый ник:{username}. Новый эмодзи:{user_emoji}')
|
||||||
|
sleep(1)
|
||||||
|
BotDB.update_date_for_user(date, user_id)
|
||||||
|
|
||||||
|
|
||||||
|
def check_user_emoji(message: types.Message):
|
||||||
|
user_id = message.from_user.id
|
||||||
|
user_emoji = BotDB.check_emoji_for_user(user_id=user_id)
|
||||||
|
if user_emoji is None or user_emoji in ("Смайл еще не определен", "Эмоджи не определен", ""):
|
||||||
|
user_emoji = get_random_emoji()
|
||||||
|
BotDB.update_emoji_for_user(user_id=user_id, emoji=user_emoji)
|
||||||
|
return user_emoji
|
||||||
|
|
||||||
|
|
||||||
|
def get_random_emoji():
|
||||||
|
attempts = 0
|
||||||
|
while attempts < 100:
|
||||||
|
user_emoji = random.choice(emoji_list)
|
||||||
|
if not BotDB.check_emoji(user_emoji):
|
||||||
|
return user_emoji
|
||||||
|
attempts += 1
|
||||||
|
logger.error("Не удалось найти уникальный эмодзи после нескольких попыток.")
|
||||||
|
return "Эмоджи не определен"
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ def get_message(username: str, type_message: str):
|
|||||||
"&Мы рассмотрим и ответим тебе в ближайшее время☺️❤️",
|
"&Мы рассмотрим и ответим тебе в ближайшее время☺️❤️",
|
||||||
"DEL_MESSAGE": "username, напиши свое обращение или предложение✍"
|
"DEL_MESSAGE": "username, напиши свое обращение или предложение✍"
|
||||||
"&Мы рассмотрим и ответим тебе в ближайшее время☺❤",
|
"&Мы рассмотрим и ответим тебе в ближайшее время☺❤",
|
||||||
"BYE_MESSAGE": "Если позднее захочешь предложить еще один пост или обратиться к админам с вопросом, то просто пришли в чат команду 👉 /start"
|
"BYE_MESSAGE": "Если позднее захочешь предложить еще один пост или обратиться к админам с вопросом, то просто пришли в чат команду 👉 /restart"
|
||||||
"&&И тебе пока!👋🏼❤️",
|
"&&И тебе пока!👋🏼❤️",
|
||||||
"USER_ERROR": "Увы, я не понимаю тебя😐💔 Выбери один из пунктов в нижнем меню, а затем пиши.",
|
"USER_ERROR": "Увы, я не понимаю тебя😐💔 Выбери один из пунктов в нижнем меню, а затем пиши.",
|
||||||
"QUESTION": "Сообщение успешно отправлено❤️ Ответим, как только сможем😉",
|
"QUESTION": "Сообщение успешно отправлено❤️ Ответим, как только сможем😉",
|
||||||
|
|||||||
@@ -20,3 +20,4 @@ attrs~=23.2.0
|
|||||||
typing_extensions~=4.12.2
|
typing_extensions~=4.12.2
|
||||||
aiohttp~=3.9.5
|
aiohttp~=3.9.5
|
||||||
aiogram~=3.10.0
|
aiogram~=3.10.0
|
||||||
|
emoji~=2.14.0
|
||||||
@@ -1,4 +1,11 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# Ensure project root is on sys.path for module resolution
|
||||||
|
CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
if CURRENT_DIR not in sys.path:
|
||||||
|
sys.path.insert(0, CURRENT_DIR)
|
||||||
|
|
||||||
from helper_bot.main import start_bot
|
from helper_bot.main import start_bot
|
||||||
from helper_bot.utils.base_dependency_factory import get_global_instance
|
from helper_bot.utils.base_dependency_factory import get_global_instance
|
||||||
|
|||||||
@@ -252,12 +252,13 @@ def test_add_new_user_in_db(bot):
|
|||||||
username = "@petr_ivanov"
|
username = "@petr_ivanov"
|
||||||
is_bot = False
|
is_bot = False
|
||||||
language_code = "ru"
|
language_code = "ru"
|
||||||
|
emoji = '🦀'
|
||||||
date_added = "2024-07-09"
|
date_added = "2024-07-09"
|
||||||
date_changed = "2024-07-09"
|
date_changed = "2024-07-09"
|
||||||
|
|
||||||
# Вызываем функцию add_new_user_in_db
|
# Вызываем функцию add_new_user_in_db
|
||||||
bot.add_new_user_in_db(
|
bot.add_new_user_in_db(
|
||||||
user_id, first_name, full_name, username, is_bot, language_code, date_added, date_changed
|
user_id, first_name, full_name, username, is_bot, language_code, emoji, date_added, date_changed
|
||||||
)
|
)
|
||||||
|
|
||||||
# Проверяем наличие записи в базе данных
|
# Проверяем наличие записи в базе данных
|
||||||
@@ -285,7 +286,7 @@ def test_add_new_user_in_db_duplicate_user_id(bot, setup_db):
|
|||||||
# Попытка добавить пользователя с тем же user_id
|
# Попытка добавить пользователя с тем же user_id
|
||||||
with pytest.raises(sqlite3.IntegrityError):
|
with pytest.raises(sqlite3.IntegrityError):
|
||||||
bot.add_new_user_in_db(
|
bot.add_new_user_in_db(
|
||||||
user_id, "Марина", "Марина Альфредовна", "marina", False, "bg", "2024-07-09", "2024-07-09"
|
user_id, "Марина", "Марина Альфредовна", "marina", False, "bg", "🦀", "2024-07-09", "2024-07-09"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -297,12 +298,13 @@ def test_add_new_user_in_db_empty_first_name(bot):
|
|||||||
username = "@boris"
|
username = "@boris"
|
||||||
is_bot = False
|
is_bot = False
|
||||||
language_code = "fr"
|
language_code = "fr"
|
||||||
|
emoji = "🦀"
|
||||||
date_added = "2024-07-09"
|
date_added = "2024-07-09"
|
||||||
date_changed = "2024-07-09"
|
date_changed = "2024-07-09"
|
||||||
|
|
||||||
# Вызываем функцию add_new_user_in_db
|
# Вызываем функцию add_new_user_in_db
|
||||||
bot.add_new_user_in_db(
|
bot.add_new_user_in_db(
|
||||||
user_id, first_name, full_name, username, is_bot, language_code, date_added, date_changed
|
user_id, first_name, full_name, username, is_bot, language_code, emoji, date_added, date_changed
|
||||||
)
|
)
|
||||||
|
|
||||||
# Проверяем наличие записи в базе данных
|
# Проверяем наличие записи в базе данных
|
||||||
|
|||||||
68
voice_bot/handlers/callback_handler.py
Normal file
68
voice_bot/handlers/callback_handler.py
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
import time
|
||||||
|
from datetime import datetime
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from aiogram import Router, F
|
||||||
|
from aiogram.types import CallbackQuery
|
||||||
|
|
||||||
|
from helper_bot.utils.base_dependency_factory import BaseDependencyFactory
|
||||||
|
|
||||||
|
callback_router = Router()
|
||||||
|
|
||||||
|
bdf = BaseDependencyFactory()
|
||||||
|
|
||||||
|
GROUP_FOR_LOGS = bdf.settings['Telegram']['group_for_logs']
|
||||||
|
GROUP_FOR_POST = bdf.settings['Telegram']['group_for_posts']
|
||||||
|
IMPORTANT_LOGS = bdf.settings['Telegram']['important_logs']
|
||||||
|
PREVIEW_LINK = bdf.settings['Telegram']['preview_link']
|
||||||
|
LOGS = bdf.settings['Settings']['logs']
|
||||||
|
TEST = bdf.settings['Settings']['test']
|
||||||
|
|
||||||
|
BotDB = bdf.get_db()
|
||||||
|
|
||||||
|
|
||||||
|
@callback_router.callback_query(
|
||||||
|
F.data == "save"
|
||||||
|
)
|
||||||
|
async def save_voice_message(call: CallbackQuery):
|
||||||
|
file_name = ''
|
||||||
|
file_id = 1
|
||||||
|
user_id = BotDB.get_user_id_by_message_id_for_voice_bot(call.message.message_id)
|
||||||
|
# Проверяем что запись о файле есть в базе данных
|
||||||
|
is_having_audio_from_user = BotDB.get_last_user_audio_record(user_id=user_id)
|
||||||
|
if is_having_audio_from_user is False:
|
||||||
|
# Если нет, то генерируем имя файла
|
||||||
|
file_name = f'message_from_{user_id}_number_{file_id}'
|
||||||
|
else:
|
||||||
|
# Иначе берем последнюю запись из БД, добавляем к ней 1, и создаем новую запись
|
||||||
|
file_name = BotDB.get_path_for_audio_record(user_id=user_id)
|
||||||
|
file_id = BotDB.get_id_for_audio_record(user_id) + 1
|
||||||
|
path = Path(f'voice_users/{file_name}.ogg')
|
||||||
|
if path.exists():
|
||||||
|
file_name = f'message_from_{user_id}_number_{file_id}'
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
# Собираем инфо о сообщении
|
||||||
|
time_UTC = int(time.time())
|
||||||
|
date_added = datetime.fromtimestamp(time_UTC)
|
||||||
|
|
||||||
|
# Сохраняем в базку
|
||||||
|
BotDB.add_audio_record(file_name, user_id, date_added, 0, file_id)
|
||||||
|
|
||||||
|
file_info = await call.message.bot.get_file(file_id=call.message.voice.file_id)
|
||||||
|
downloaded_file = await call.message.bot.download_file(file_path=file_info.file_path)
|
||||||
|
with open(f'voice_users/{file_name}.ogg', 'wb') as new_file:
|
||||||
|
new_file.write(downloaded_file.read())
|
||||||
|
|
||||||
|
await call.bot.delete_message(chat_id=GROUP_FOR_POST, message_id=call.message.message_id)
|
||||||
|
await call.answer(text='Сохранено!', cache_time=3)
|
||||||
|
|
||||||
|
|
||||||
|
@callback_router.callback_query(
|
||||||
|
F.data == "delete"
|
||||||
|
)
|
||||||
|
async def delete_voice_message(call: CallbackQuery):
|
||||||
|
# Получаем из базы автора + отправляем сообщение + удаляем сообщение из предложки
|
||||||
|
|
||||||
|
await call.bot.delete_message(chat_id=GROUP_FOR_POST, message_id=call.message.message_id)
|
||||||
|
await call.answer(text='Удалено!', cache_time=3)
|
||||||
@@ -9,9 +9,11 @@ from aiogram.fsm.context import FSMContext
|
|||||||
from aiogram.types import FSInputFile
|
from aiogram.types import FSInputFile
|
||||||
|
|
||||||
from helper_bot.filters.main import ChatTypeFilter
|
from helper_bot.filters.main import ChatTypeFilter
|
||||||
|
from helper_bot.middlewares.blacklist_middleware import BlacklistMiddleware
|
||||||
from helper_bot.utils.base_dependency_factory import get_global_instance
|
from helper_bot.utils.base_dependency_factory import get_global_instance
|
||||||
|
from helper_bot.utils.helper_func import update_user_info, check_user_emoji, send_voice_message
|
||||||
from logs.custom_logger import logger
|
from logs.custom_logger import logger
|
||||||
from voice_bot.keyboards.keyboards import get_main_keyboard
|
from voice_bot.keyboards.keyboards import get_main_keyboard, get_reply_keyboard_for_voice
|
||||||
from voice_bot.utils.helper_func import last_message
|
from voice_bot.utils.helper_func import last_message
|
||||||
|
|
||||||
voice_router = Router()
|
voice_router = Router()
|
||||||
@@ -19,12 +21,14 @@ voice_router = Router()
|
|||||||
bdf = get_global_instance()
|
bdf = get_global_instance()
|
||||||
|
|
||||||
GROUP_FOR_LOGS = bdf.settings['Telegram']['group_for_logs']
|
GROUP_FOR_LOGS = bdf.settings['Telegram']['group_for_logs']
|
||||||
|
GROUP_FOR_POST = bdf.settings['Telegram']['group_for_posts']
|
||||||
IMPORTANT_LOGS = bdf.settings['Telegram']['important_logs']
|
IMPORTANT_LOGS = bdf.settings['Telegram']['important_logs']
|
||||||
PREVIEW_LINK = bdf.settings['Telegram']['preview_link']
|
PREVIEW_LINK = bdf.settings['Telegram']['preview_link']
|
||||||
LOGS = bdf.settings['Settings']['logs']
|
LOGS = bdf.settings['Settings']['logs']
|
||||||
TEST = bdf.settings['Settings']['test']
|
TEST = bdf.settings['Settings']['test']
|
||||||
|
|
||||||
BotDB = bdf.get_db()
|
BotDB = bdf.get_db()
|
||||||
|
voice_router.message.middleware(BlacklistMiddleware())
|
||||||
|
|
||||||
|
|
||||||
@voice_router.message(
|
@voice_router.message(
|
||||||
@@ -33,21 +37,36 @@ BotDB = bdf.get_db()
|
|||||||
)
|
)
|
||||||
async def restart_function(message: types.Message, state: FSMContext):
|
async def restart_function(message: types.Message, state: FSMContext):
|
||||||
await message.forward(chat_id=GROUP_FOR_LOGS)
|
await message.forward(chat_id=GROUP_FOR_LOGS)
|
||||||
|
await update_user_info('voice', message)
|
||||||
|
check_user_emoji(message)
|
||||||
markup = get_main_keyboard()
|
markup = get_main_keyboard()
|
||||||
await message.answer(text='Я перезапущен!',
|
await message.answer(text='Я перезапущен!',
|
||||||
reply_markup=markup)
|
reply_markup=markup)
|
||||||
await state.set_state('START')
|
await state.set_state('START')
|
||||||
|
|
||||||
|
|
||||||
|
@voice_router.message(
|
||||||
|
ChatTypeFilter(chat_type=["private"]),
|
||||||
|
Command("emoji")
|
||||||
|
)
|
||||||
|
async def handle_emoji_message(message: types.Message, state: FSMContext):
|
||||||
|
await message.forward(chat_id=GROUP_FOR_LOGS)
|
||||||
|
user_emoji = check_user_emoji(message)
|
||||||
|
await state.set_state("START")
|
||||||
|
if user_emoji is not None:
|
||||||
|
await message.answer(f'Твоя эмодзя - {user_emoji}', parse_mode='HTML')
|
||||||
|
|
||||||
|
|
||||||
@voice_router.message(
|
@voice_router.message(
|
||||||
ChatTypeFilter(chat_type=["private"]),
|
ChatTypeFilter(chat_type=["private"]),
|
||||||
Command("help")
|
Command("help")
|
||||||
)
|
)
|
||||||
async def help_function(message: types.Message, state: FSMContext):
|
async def help_function(message: types.Message, state: FSMContext):
|
||||||
await message.forward(chat_id=GROUP_FOR_LOGS)
|
await message.forward(chat_id=GROUP_FOR_LOGS)
|
||||||
|
await update_user_info('voice', message)
|
||||||
await message.answer(
|
await message.answer(
|
||||||
text='Скорее всего ответы на твои вопросы есть здесь, ознакомься: https://telegra.ph/Instrukciya-k-botu-Golosa-Bijsk-10-11-2'
|
text='Скорее всего ответы на твои вопросы есть здесь, ознакомься: https://telegra.ph/Instrukciya-k-botu-Golosa-Bijsk-10-11-2'
|
||||||
'\nЕсли это не поможет, пиши в тг: @Kerrad1', disable_web_page_preview=not PREVIEW_LINK)
|
'\nЕсли это не поможет, пиши в личку: @Kerrad1', disable_web_page_preview=not PREVIEW_LINK)
|
||||||
await state.set_state('START')
|
await state.set_state('START')
|
||||||
|
|
||||||
|
|
||||||
@@ -58,6 +77,8 @@ async def help_function(message: types.Message, state: FSMContext):
|
|||||||
async def start(message: types.Message, state: FSMContext):
|
async def start(message: types.Message, state: FSMContext):
|
||||||
await state.set_state("START")
|
await state.set_state("START")
|
||||||
await message.forward(chat_id=GROUP_FOR_LOGS)
|
await message.forward(chat_id=GROUP_FOR_LOGS)
|
||||||
|
await update_user_info('voice', message)
|
||||||
|
user_emoji = check_user_emoji(message)
|
||||||
try:
|
try:
|
||||||
name_stick_hello = list(Path('Stick').rglob('Hello_*'))
|
name_stick_hello = list(Path('Stick').rglob('Hello_*'))
|
||||||
random_stick_hello = random.choice(name_stick_hello)
|
random_stick_hello = random.choice(name_stick_hello)
|
||||||
@@ -98,15 +119,36 @@ async def start(message: types.Message, state: FSMContext):
|
|||||||
parse_mode='html', reply_markup=markup,
|
parse_mode='html', reply_markup=markup,
|
||||||
disable_web_page_preview=not PREVIEW_LINK)
|
disable_web_page_preview=not PREVIEW_LINK)
|
||||||
await asyncio.sleep(0.8)
|
await asyncio.sleep(0.8)
|
||||||
|
await message.answer(text=f"Любые войсы будут помечены эмоджи. <b>Твой эмоджи - </b>{user_emoji}"
|
||||||
|
f"Таким эмоджи будут помечены твои сообщения для других "
|
||||||
|
f"Но другие люди не узнают кто за каким эмоджи скрывается:)",
|
||||||
|
parse_mode='html', reply_markup=markup,
|
||||||
|
disable_web_page_preview=not PREVIEW_LINK)
|
||||||
|
await asyncio.sleep(0.8)
|
||||||
await message.answer(text="Так же можешь ознакомиться с инструкцией к боту по команде /help",
|
await message.answer(text="Так же можешь ознакомиться с инструкцией к боту по команде /help",
|
||||||
parse_mode='html', reply_markup=markup,
|
parse_mode='html', reply_markup=markup,
|
||||||
disable_web_page_preview=not PREVIEW_LINK)
|
disable_web_page_preview=not PREVIEW_LINK)
|
||||||
await asyncio.sleep(0.8)
|
await asyncio.sleep(0.8)
|
||||||
await message.answer(text="<b>ну всё, достаточно инструкций. записывайся! Микрофон твой - </b> 🎤",
|
await message.answer(text="<b>Ну всё, достаточно инструкций. записывайся! Микрофон твой - </b> 🎤",
|
||||||
parse_mode='html', reply_markup=markup,
|
parse_mode='html', reply_markup=markup,
|
||||||
disable_web_page_preview=not PREVIEW_LINK)
|
disable_web_page_preview=not PREVIEW_LINK)
|
||||||
|
|
||||||
|
|
||||||
|
@voice_router.message(
|
||||||
|
ChatTypeFilter(chat_type=["private"]),
|
||||||
|
Command("refresh")
|
||||||
|
)
|
||||||
|
async def refresh_listen_function(message: types.Message, state: FSMContext):
|
||||||
|
await message.forward(chat_id=GROUP_FOR_LOGS)
|
||||||
|
await update_user_info('voice', message)
|
||||||
|
markup = get_main_keyboard()
|
||||||
|
BotDB.delete_listen_count_for_user(message.from_user.id)
|
||||||
|
await message.answer(
|
||||||
|
text='Прослушивания очищены. Можешь начать слушать заново🤗', disable_web_page_preview=not PREVIEW_LINK,
|
||||||
|
markup=markup)
|
||||||
|
await state.set_state('START')
|
||||||
|
|
||||||
|
|
||||||
@voice_router.message(
|
@voice_router.message(
|
||||||
StateFilter("START"),
|
StateFilter("START"),
|
||||||
ChatTypeFilter(chat_type=["private"]),
|
ChatTypeFilter(chat_type=["private"]),
|
||||||
@@ -116,53 +158,33 @@ async def standup_write(message: types.Message, state: FSMContext):
|
|||||||
await message.forward(chat_id=GROUP_FOR_LOGS)
|
await message.forward(chat_id=GROUP_FOR_LOGS)
|
||||||
markup = types.ReplyKeyboardRemove()
|
markup = types.ReplyKeyboardRemove()
|
||||||
await message.answer(text='Хорошо, теперь пришли мне свое голосовое сообщение', reply_markup=markup)
|
await message.answer(text='Хорошо, теперь пришли мне свое голосовое сообщение', reply_markup=markup)
|
||||||
|
try:
|
||||||
message_with_date = last_message()
|
message_with_date = last_message()
|
||||||
await message.answer(text=message_with_date, parse_mode="html")
|
await message.answer(text=message_with_date, parse_mode="html")
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f'Не удалось получить дату последнего сообщения - {e}')
|
||||||
await state.set_state('STANDUP_WRITE')
|
await state.set_state('STANDUP_WRITE')
|
||||||
|
|
||||||
|
|
||||||
@voice_router.message(
|
@voice_router.message(
|
||||||
StateFilter("STANDUP_WRITE"),
|
StateFilter("STANDUP_WRITE"),
|
||||||
ChatTypeFilter(chat_type=["private"])
|
ChatTypeFilter(chat_type=["private"]),
|
||||||
)
|
)
|
||||||
async def save_voice_message(message: types.Message, state: FSMContext):
|
async def suggest_voice(message: types.Message, state: FSMContext):
|
||||||
|
logger.info(
|
||||||
|
f"Вызов функции suggest_voice. Пользователь: {message.from_user.id} Имя автора сообщения: {message.from_user.full_name}")
|
||||||
|
await message.forward(chat_id=GROUP_FOR_LOGS)
|
||||||
markup = get_main_keyboard()
|
markup = get_main_keyboard()
|
||||||
if message.content_type == 'voice':
|
if message.content_type == 'voice':
|
||||||
await message.forward(chat_id=GROUP_FOR_LOGS)
|
markup_for_voice = get_reply_keyboard_for_voice()
|
||||||
file_name = ''
|
# Отправляем аудио в приватный канал
|
||||||
file_id = 1
|
sent_message = await send_voice_message(GROUP_FOR_POST, message,
|
||||||
# Проверяем что запись о файле есть в базе данных
|
message.voice.file_id, markup_for_voice)
|
||||||
is_having_audio_from_user = BotDB.get_last_user_audio_record(user_id=message.from_user.id)
|
|
||||||
if is_having_audio_from_user is False:
|
|
||||||
# Если нет, то генерируем имя файла
|
|
||||||
file_name = f'message_from_{message.from_user.id}_number_{file_id}'
|
|
||||||
else:
|
|
||||||
# Иначе берем последнюю запись из БД, добавляем к ней 1, и создаем новую запись
|
|
||||||
file_name = BotDB.get_path_for_audio_record(user_id=message.from_user.id)
|
|
||||||
file_id = BotDB.get_id_for_audio_record(message.from_user.id) + 1
|
|
||||||
path = Path(f'voice_users/{file_name}.ogg')
|
|
||||||
if path.exists():
|
|
||||||
file_name = f'message_from_{message.from_user.id}_number_{file_id}'
|
|
||||||
else:
|
|
||||||
pass
|
|
||||||
# Собираем инфо о сообщении
|
|
||||||
author_id = message.from_user.id
|
|
||||||
time_UTC = int(datetime.now().timestamp())
|
|
||||||
date_added = datetime.fromtimestamp(time_UTC)
|
|
||||||
|
|
||||||
# Сохраняем в базку
|
# Сохраняем в базу инфо о посте
|
||||||
BotDB.add_audio_record(file_name, author_id, date_added, 0, file_id)
|
BotDB.set_user_id_and_message_id_for_voice_bot(sent_message.message_id, message.from_user.id)
|
||||||
|
|
||||||
# Сохраняем файл на сервер
|
# Отправляем юзеру ответ и возвращаем его в меню
|
||||||
# file_info = message.bot.get_file(file_id=message.voice.file_id)
|
|
||||||
# downloaded_file = message.bot.download_file(file_path=file_info.file_path)
|
|
||||||
# with open(f'voice_users/{file_name}.ogg', 'wb') as new_file:
|
|
||||||
# new_file.write(downloaded_file)
|
|
||||||
|
|
||||||
file_info = await message.bot.get_file(file_id=message.voice.file_id)
|
|
||||||
downloaded_file = await message.bot.download_file(file_path=file_info.file_path)
|
|
||||||
with open(f'voice_users/{file_name}.ogg', 'wb') as new_file:
|
|
||||||
new_file.write(downloaded_file.read())
|
|
||||||
await message.answer(text='Окей, сохранил!👌', reply_markup=markup)
|
await message.answer(text='Окей, сохранил!👌', reply_markup=markup)
|
||||||
await state.set_state('START')
|
await state.set_state('START')
|
||||||
else:
|
else:
|
||||||
@@ -177,24 +199,38 @@ async def save_voice_message(message: types.Message, state: FSMContext):
|
|||||||
ChatTypeFilter(chat_type=["private"]),
|
ChatTypeFilter(chat_type=["private"]),
|
||||||
F.text == '🎧Послушать'
|
F.text == '🎧Послушать'
|
||||||
)
|
)
|
||||||
async def standup_listen_audio(message: types.Message, state: FSMContext):
|
async def standup_listen_audio(message: types.Message):
|
||||||
check_audio = BotDB.check_listen_audio(user_id=message.from_user.id)
|
check_audio = BotDB.check_listen_audio(user_id=message.from_user.id)
|
||||||
list_audio = list(check_audio)
|
list_audio = list(check_audio)
|
||||||
markup = get_main_keyboard()
|
markup = get_main_keyboard()
|
||||||
await message.forward(chat_id=GROUP_FOR_LOGS)
|
|
||||||
if not list_audio:
|
if not list_audio:
|
||||||
await message.answer(text='Прости, ты прослушал все аудио😔. Возвращайся позже, возможно наша база пополнится',
|
await message.answer(text='Прости, ты прослушал все аудио😔. Возвращайся позже, возможно наша база пополнится',
|
||||||
reply_markup=markup)
|
reply_markup=markup)
|
||||||
|
try:
|
||||||
message_with_date = last_message()
|
message_with_date = last_message()
|
||||||
message.send_message(chat_id=message.chat.id, text=message_with_date, parse_mode="html")
|
await message.answer(text=message_with_date, parse_mode="html")
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f'Не удалось получить последнюю дату {e}')
|
||||||
else:
|
else:
|
||||||
|
# Получаем ссылку на аудио сообщение пользователя
|
||||||
number_element = random.randint(0, len(list_audio) - 1)
|
number_element = random.randint(0, len(list_audio) - 1)
|
||||||
audio_for_user = check_audio[number_element]
|
audio_for_user = check_audio[number_element]
|
||||||
|
|
||||||
|
# Получаем автора записи + эмодзи по нему
|
||||||
|
user_id = BotDB.get_user_id_by_file_name(audio_for_user)
|
||||||
|
date_added = BotDB.get_date_by_file_name(audio_for_user)
|
||||||
|
user_emoji = BotDB.check_emoji_for_user(user_id)
|
||||||
|
|
||||||
path = Path(f'voice_users/{audio_for_user}.ogg')
|
path = Path(f'voice_users/{audio_for_user}.ogg')
|
||||||
# voice = open(path, 'rb')
|
|
||||||
voice = FSInputFile(path)
|
voice = FSInputFile(path)
|
||||||
|
|
||||||
# Маркируем сообщение как прослушанное
|
# Маркируем сообщение как прослушанное
|
||||||
BotDB.mark_listened_audio(audio_for_user, user_id=message.from_user.id)
|
BotDB.mark_listened_audio(audio_for_user, user_id=message.from_user.id)
|
||||||
await message.bot.send_voice(message.chat.id, voice=voice, reply_markup=markup)
|
|
||||||
await message.forward(chat_id=GROUP_FOR_LOGS)
|
# Формируем подпись
|
||||||
await state.set_state('START')
|
if user_emoji:
|
||||||
|
caption = f'{user_emoji}\nДата записи: {date_added}'
|
||||||
|
else:
|
||||||
|
caption = f'Дата записи: {date_added}'
|
||||||
|
await message.bot.send_voice(chat_id=message.chat.id, voice=voice, caption=caption, reply_markup=markup)
|
||||||
|
await message.answer(text=f'Осталось непрослушанных: <b>{len(check_audio) - 1}</b>', reply_markup=markup)
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
from aiogram import types
|
from aiogram import types
|
||||||
from aiogram.utils.keyboard import ReplyKeyboardBuilder
|
from aiogram.utils.keyboard import ReplyKeyboardBuilder, InlineKeyboardBuilder
|
||||||
|
|
||||||
|
|
||||||
def get_main_keyboard():
|
def get_main_keyboard():
|
||||||
@@ -8,3 +8,15 @@ def get_main_keyboard():
|
|||||||
builder.add(types.KeyboardButton(text="🎧Послушать"))
|
builder.add(types.KeyboardButton(text="🎧Послушать"))
|
||||||
markup = builder.as_markup(resize_keyboard=True)
|
markup = builder.as_markup(resize_keyboard=True)
|
||||||
return markup
|
return markup
|
||||||
|
|
||||||
|
|
||||||
|
def get_reply_keyboard_for_voice():
|
||||||
|
builder = InlineKeyboardBuilder()
|
||||||
|
builder.row(types.InlineKeyboardButton(
|
||||||
|
text="Сохранить", callback_data="save")
|
||||||
|
)
|
||||||
|
builder.row(types.InlineKeyboardButton(
|
||||||
|
text="Удалить", callback_data="delete")
|
||||||
|
)
|
||||||
|
markup = builder.as_markup(resize_keyboard=True, one_time_keyboard=True)
|
||||||
|
return markup
|
||||||
|
|||||||
@@ -1,9 +1,19 @@
|
|||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# Ensure project root is on sys.path for module resolution when running voice bot directly
|
||||||
|
CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
PROJECT_ROOT = os.path.dirname(CURRENT_DIR)
|
||||||
|
if PROJECT_ROOT not in sys.path:
|
||||||
|
sys.path.insert(0, PROJECT_ROOT)
|
||||||
|
|
||||||
from aiogram import Bot, Dispatcher
|
from aiogram import Bot, Dispatcher
|
||||||
from aiogram.client.default import DefaultBotProperties
|
from aiogram.client.default import DefaultBotProperties
|
||||||
from aiogram.fsm.storage.memory import MemoryStorage
|
from aiogram.fsm.storage.memory import MemoryStorage
|
||||||
from aiogram.fsm.strategy import FSMStrategy
|
from aiogram.fsm.strategy import FSMStrategy
|
||||||
|
|
||||||
from voice_bot.voice_handler.voice_handler import voice_router
|
from voice_bot.handlers.callback_handler import callback_router
|
||||||
|
from voice_bot.handlers.voice_handler import voice_router
|
||||||
|
|
||||||
|
|
||||||
async def start_bot(bdf):
|
async def start_bot(bdf):
|
||||||
@@ -13,6 +23,6 @@ async def start_bot(bdf):
|
|||||||
link_preview_is_disabled=bdf.settings['Telegram']['preview_link']
|
link_preview_is_disabled=bdf.settings['Telegram']['preview_link']
|
||||||
))
|
))
|
||||||
dp = Dispatcher(storage=MemoryStorage(), fsm_strategy=FSMStrategy.GLOBAL_USER)
|
dp = Dispatcher(storage=MemoryStorage(), fsm_strategy=FSMStrategy.GLOBAL_USER)
|
||||||
dp.include_routers(voice_router)
|
dp.include_routers(voice_router, callback_router)
|
||||||
await bot.delete_webhook(drop_pending_updates=True)
|
await bot.delete_webhook(drop_pending_updates=True)
|
||||||
await dp.start_polling(bot, skip_updates=True)
|
await dp.start_polling(bot, skip_updates=True)
|
||||||
|
|||||||
@@ -12,6 +12,9 @@ BotDB = bdf.get_db()
|
|||||||
def last_message():
|
def last_message():
|
||||||
# функция с отображением сообщения "Последнее сообщение было записано"
|
# функция с отображением сообщения "Последнее сообщение было записано"
|
||||||
date_from_db = BotDB.last_date_audio()
|
date_from_db = BotDB.last_date_audio()
|
||||||
|
if date_from_db is None:
|
||||||
|
return None
|
||||||
|
|
||||||
parse_date = datetime.strptime(date_from_db, "%Y-%m-%d %H:%M:%S")
|
parse_date = datetime.strptime(date_from_db, "%Y-%m-%d %H:%M:%S")
|
||||||
last_voice_time_timestamp = time.mktime(parse_date.timetuple())
|
last_voice_time_timestamp = time.mktime(parse_date.timetuple())
|
||||||
time_now_timestamp = time.time()
|
time_now_timestamp = time.time()
|
||||||
|
|||||||
Reference in New Issue
Block a user