Enhance bot functionality and refactor database interactions

- Added `ca-certificates` installation to Dockerfile for improved network security.
- Updated health check command in Dockerfile to include better timeout handling.
- Refactored `run_helper.py` to implement proper signal handling and logging during shutdown.
- Transitioned database operations to an asynchronous model in `async_db.py`, improving performance and responsiveness.
- Updated database schema to support new foreign key relationships and optimized indexing for better query performance.
- Enhanced various bot handlers to utilize async database methods, improving overall efficiency and user experience.
- Removed obsolete database and fix scripts to streamline the project structure.
This commit is contained in:
2025-09-02 18:22:02 +03:00
parent 013892dcb7
commit 1c6a37bc12
59 changed files with 5682 additions and 4204 deletions

View File

@@ -0,0 +1,150 @@
from datetime import datetime
from typing import Optional, List, Tuple
from database.base import DatabaseConnection
from database.models import TelegramPost, PostContent, MessageContentLink
class PostRepository(DatabaseConnection):
"""Репозиторий для работы с постами из Telegram."""
async def create_tables(self):
"""Создание таблиц для постов."""
# Таблица постов из Telegram
post_query = '''
CREATE TABLE IF NOT EXISTS post_from_telegram_suggest (
message_id INTEGER NOT NULL PRIMARY KEY,
text TEXT,
helper_text_message_id INTEGER,
author_id INTEGER,
created_at INTEGER NOT NULL,
FOREIGN KEY (author_id) REFERENCES our_users (user_id) ON DELETE CASCADE
)
'''
await self._execute_query(post_query)
# Таблица контента постов
content_query = '''
CREATE TABLE IF NOT EXISTS content_post_from_telegram (
message_id INTEGER NOT NULL,
content_name TEXT NOT NULL,
content_type TEXT,
PRIMARY KEY (message_id, content_name),
FOREIGN KEY (message_id) REFERENCES post_from_telegram_suggest (message_id) ON DELETE CASCADE
)
'''
await self._execute_query(content_query)
# Таблица связи сообщений с контентом
link_query = '''
CREATE TABLE IF NOT EXISTS message_link_to_content (
post_id INTEGER NOT NULL,
message_id INTEGER NOT NULL,
PRIMARY KEY (post_id, message_id),
FOREIGN KEY (post_id) REFERENCES post_from_telegram_suggest (message_id) ON DELETE CASCADE
)
'''
await self._execute_query(link_query)
self.logger.info("Таблицы для постов созданы")
async def add_post(self, post: TelegramPost) -> None:
"""Добавление поста."""
if not post.created_at:
post.created_at = int(datetime.now().timestamp())
query = """
INSERT INTO post_from_telegram_suggest (message_id, text, author_id, created_at)
VALUES (?, ?, ?, ?)
"""
params = (post.message_id, post.text, post.author_id, post.created_at)
await self._execute_query(query, params)
self.logger.info(f"Пост добавлен: message_id={post.message_id}")
async def update_helper_message(self, message_id: int, helper_message_id: int) -> None:
"""Обновление helper сообщения."""
query = "UPDATE post_from_telegram_suggest SET helper_text_message_id = ? WHERE message_id = ?"
await self._execute_query(query, (helper_message_id, message_id))
async def add_post_content(self, post_id: int, message_id: int, content_name: str, content_type: str) -> bool:
"""Добавление контента поста."""
try:
# Сначала добавляем связь
link_query = "INSERT OR IGNORE INTO message_link_to_content (post_id, message_id) VALUES (?, ?)"
await self._execute_query(link_query, (post_id, message_id))
# Затем добавляем контент
content_query = """
INSERT OR IGNORE INTO content_post_from_telegram (message_id, content_name, content_type)
VALUES (?, ?, ?)
"""
await self._execute_query(content_query, (message_id, content_name, content_type))
self.logger.info(f"Контент поста добавлен: post_id={post_id}, message_id={message_id}")
return True
except Exception as e:
self.logger.error(f"Ошибка при добавлении контента поста: {e}")
return False
async def get_post_content_by_helper_id(self, helper_message_id: int) -> List[Tuple[str, str]]:
"""Получает контент поста по helper_text_message_id."""
query = """
SELECT cpft.content_name, cpft.content_type
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 = ?
"""
post_content = await self._execute_query_with_result(query, (helper_message_id,))
self.logger.info(f"Получен контент поста: {len(post_content)} элементов")
return post_content
async def get_post_text_by_helper_id(self, helper_message_id: int) -> Optional[str]:
"""Получает текст поста по helper_text_message_id."""
query = "SELECT text FROM post_from_telegram_suggest WHERE helper_text_message_id = ?"
rows = await self._execute_query_with_result(query, (helper_message_id,))
row = rows[0] if rows else None
if row:
self.logger.info(f"Получен текст поста для helper_message_id={helper_message_id}")
return row[0]
return None
async def get_post_ids_by_helper_id(self, helper_message_id: int) -> List[int]:
"""Получает ID сообщений по helper_text_message_id."""
query = """
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 = ?
"""
rows = await self._execute_query_with_result(query, (helper_message_id,))
post_ids = [row[0] for row in rows]
self.logger.info(f"Получены ID сообщений: {len(post_ids)} элементов")
return post_ids
async def get_author_id_by_message_id(self, message_id: int) -> Optional[int]:
"""Получает ID автора по message_id."""
query = "SELECT author_id FROM post_from_telegram_suggest WHERE message_id = ?"
rows = await self._execute_query_with_result(query, (message_id,))
row = rows[0] if rows else None
if row:
author_id = row[0]
self.logger.info(f"Получен author_id: {author_id} для message_id={message_id}")
return author_id
return None
async def get_author_id_by_helper_message_id(self, helper_message_id: int) -> Optional[int]:
"""Получает ID автора по helper_text_message_id."""
query = "SELECT author_id FROM post_from_telegram_suggest WHERE helper_text_message_id = ?"
rows = await self._execute_query_with_result(query, (helper_message_id,))
row = rows[0] if rows else None
if row:
author_id = row[0]
self.logger.info(f"Получен author_id: {author_id} для helper_message_id={helper_message_id}")
return author_id
return None