Обновление управления статусами сообщений и схемы базы данных
- Добавлены методы в `AsyncBotDB` и `PostRepository` для обновления статусов сообщений по идентификатору сообщения и для групп медиафайлов. - Добавлено поле `status` в модель `TelegramPost` и обновлена схема базы данных, чтобы включить это поле со значением по умолчанию 'suggest'. - Обновлен `PostPublishService` для установки статусов сообщений на 'approved' или 'declined' в процессе публикации.
This commit is contained in:
@@ -158,7 +158,19 @@ class AsyncBotDB:
|
||||
async def get_author_id_by_helper_message_id(self, helper_text_message_id: int) -> Optional[int]:
|
||||
"""Получает ID автора по helper_text_message_id."""
|
||||
return await self.factory.posts.get_author_id_by_helper_message_id(helper_text_message_id)
|
||||
|
||||
|
||||
async def update_status_by_message_id(self, message_id: int, status: str) -> None:
|
||||
"""Обновление статуса поста по message_id (одиночные посты)."""
|
||||
await self.factory.posts.update_status_by_message_id(message_id, status)
|
||||
|
||||
async def update_status_for_media_group_by_helper_id(
|
||||
self, helper_message_id: int, status: str
|
||||
) -> None:
|
||||
"""Обновление статуса постов медиагруппы по helper_message_id."""
|
||||
await self.factory.posts.update_status_for_media_group_by_helper_id(
|
||||
helper_message_id, status
|
||||
)
|
||||
|
||||
# Методы для работы с черным списком
|
||||
async def set_user_blacklist(self, user_id: int, user_name: str = None,
|
||||
message_for_user: str = None, date_to_unban: int = None):
|
||||
|
||||
@@ -45,6 +45,7 @@ class TelegramPost:
|
||||
author_id: int
|
||||
helper_text_message_id: Optional[int] = None
|
||||
created_at: Optional[int] = None
|
||||
status: str = "suggest"
|
||||
|
||||
|
||||
@dataclass
|
||||
|
||||
@@ -17,6 +17,7 @@ class PostRepository(DatabaseConnection):
|
||||
helper_text_message_id INTEGER,
|
||||
author_id INTEGER,
|
||||
created_at INTEGER NOT NULL,
|
||||
status TEXT NOT NULL DEFAULT 'suggest',
|
||||
FOREIGN KEY (author_id) REFERENCES our_users (user_id) ON DELETE CASCADE
|
||||
)
|
||||
'''
|
||||
@@ -51,13 +52,14 @@ class PostRepository(DatabaseConnection):
|
||||
"""Добавление поста."""
|
||||
if not post.created_at:
|
||||
post.created_at = int(datetime.now().timestamp())
|
||||
|
||||
status = post.status if post.status else "suggest"
|
||||
|
||||
query = """
|
||||
INSERT INTO post_from_telegram_suggest (message_id, text, author_id, created_at)
|
||||
VALUES (?, ?, ?, ?)
|
||||
INSERT INTO post_from_telegram_suggest (message_id, text, author_id, created_at, status)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
"""
|
||||
params = (post.message_id, post.text, post.author_id, post.created_at)
|
||||
|
||||
params = (post.message_id, post.text, post.author_id, post.created_at, status)
|
||||
|
||||
await self._execute_query(query, params)
|
||||
self.logger.info(f"Пост добавлен: message_id={post.message_id}")
|
||||
|
||||
@@ -65,7 +67,27 @@ class PostRepository(DatabaseConnection):
|
||||
"""Обновление 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 update_status_by_message_id(self, message_id: int, status: str) -> None:
|
||||
"""Обновление статуса поста по message_id (одиночные посты)."""
|
||||
query = "UPDATE post_from_telegram_suggest SET status = ? WHERE message_id = ?"
|
||||
await self._execute_query(query, (status, message_id))
|
||||
self.logger.info(f"Статус поста message_id={message_id} обновлён на {status}")
|
||||
|
||||
async def update_status_for_media_group_by_helper_id(
|
||||
self, helper_message_id: int, status: str
|
||||
) -> None:
|
||||
"""Обновление статуса постов медиагруппы по helper_text_message_id."""
|
||||
query = """
|
||||
UPDATE post_from_telegram_suggest
|
||||
SET status = ?
|
||||
WHERE message_id = ? OR helper_text_message_id = ?
|
||||
"""
|
||||
await self._execute_query(query, (status, helper_message_id, helper_message_id))
|
||||
self.logger.info(
|
||||
f"Статус медиагруппы helper_message_id={helper_message_id} обновлён на {status}"
|
||||
)
|
||||
|
||||
async def add_post_content(self, post_id: int, message_id: int, content_name: str, content_type: str) -> bool:
|
||||
"""Добавление контента поста."""
|
||||
try:
|
||||
|
||||
@@ -57,6 +57,7 @@ CREATE TABLE IF NOT EXISTS post_from_telegram_suggest (
|
||||
helper_text_message_id INTEGER,
|
||||
author_id INTEGER,
|
||||
created_at INTEGER NOT NULL,
|
||||
status TEXT NOT NULL DEFAULT 'suggest',
|
||||
FOREIGN KEY (author_id) REFERENCES our_users(user_id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
|
||||
@@ -80,7 +80,8 @@ class PostPublishService:
|
||||
"""Публикация текстового поста"""
|
||||
text_post = html.escape(str(call.message.text))
|
||||
author_id = await self._get_author_id(call.message.message_id)
|
||||
|
||||
|
||||
await self.db.update_status_by_message_id(call.message.message_id, "approved")
|
||||
await send_text_message(self.main_public, call.message, text_post)
|
||||
await self._delete_post_and_notify_author(call, author_id)
|
||||
logger.info(f'Текст сообщения опубликован в канале {self.main_public}.')
|
||||
@@ -91,7 +92,8 @@ class PostPublishService:
|
||||
"""Публикация поста с фото"""
|
||||
text_post_with_photo = html.escape(str(call.message.caption))
|
||||
author_id = await self._get_author_id(call.message.message_id)
|
||||
|
||||
|
||||
await self.db.update_status_by_message_id(call.message.message_id, "approved")
|
||||
await send_photo_message(self.main_public, call.message, call.message.photo[-1].file_id, text_post_with_photo)
|
||||
await self._delete_post_and_notify_author(call, author_id)
|
||||
logger.info(f'Пост с фото опубликован в канале {self.main_public}.')
|
||||
@@ -102,7 +104,8 @@ class PostPublishService:
|
||||
"""Публикация поста с видео"""
|
||||
text_post_with_photo = html.escape(str(call.message.caption))
|
||||
author_id = await self._get_author_id(call.message.message_id)
|
||||
|
||||
|
||||
await self.db.update_status_by_message_id(call.message.message_id, "approved")
|
||||
await send_video_message(self.main_public, call.message, call.message.video.file_id, text_post_with_photo)
|
||||
await self._delete_post_and_notify_author(call, author_id)
|
||||
logger.info(f'Пост с видео опубликован в канале {self.main_public}.')
|
||||
@@ -112,7 +115,8 @@ class PostPublishService:
|
||||
async def _publish_video_note_post(self, call: CallbackQuery) -> None:
|
||||
"""Публикация поста с кружком"""
|
||||
author_id = await self._get_author_id(call.message.message_id)
|
||||
|
||||
|
||||
await self.db.update_status_by_message_id(call.message.message_id, "approved")
|
||||
await send_video_note_message(self.main_public, call.message, call.message.video_note.file_id)
|
||||
await self._delete_post_and_notify_author(call, author_id)
|
||||
logger.info(f'Пост с кружком опубликован в канале {self.main_public}.')
|
||||
@@ -123,7 +127,8 @@ class PostPublishService:
|
||||
"""Публикация поста с аудио"""
|
||||
text_post_with_photo = html.escape(str(call.message.caption))
|
||||
author_id = await self._get_author_id(call.message.message_id)
|
||||
|
||||
|
||||
await self.db.update_status_by_message_id(call.message.message_id, "approved")
|
||||
await send_audio_message(self.main_public, call.message, call.message.audio.file_id, text_post_with_photo)
|
||||
await self._delete_post_and_notify_author(call, author_id)
|
||||
logger.info(f'Пост с аудио опубликован в канале {self.main_public}.')
|
||||
@@ -133,7 +138,8 @@ class PostPublishService:
|
||||
async def _publish_voice_post(self, call: CallbackQuery) -> None:
|
||||
"""Публикация поста с войсом"""
|
||||
author_id = await self._get_author_id(call.message.message_id)
|
||||
|
||||
|
||||
await self.db.update_status_by_message_id(call.message.message_id, "approved")
|
||||
await send_voice_message(self.main_public, call.message, call.message.voice.file_id)
|
||||
await self._delete_post_and_notify_author(call, author_id)
|
||||
logger.info(f'Пост с войсом опубликован в канале {self.main_public}.')
|
||||
@@ -177,7 +183,8 @@ class PostPublishService:
|
||||
post_content=post_content,
|
||||
post_text=post_text
|
||||
)
|
||||
|
||||
|
||||
await self.db.update_status_for_media_group_by_helper_id(helper_message_id, "approved")
|
||||
logger.debug(f"Удаляю медиагруппу и уведомляю автора {author_id}")
|
||||
await self._delete_media_group_and_notify_author(call, author_id)
|
||||
logger.info(f'Медиагруппа опубликована в канале {self.main_public}.')
|
||||
@@ -214,7 +221,8 @@ class PostPublishService:
|
||||
logger.debug(f"Отклоняю одиночный пост. Message ID: {call.message.message_id}")
|
||||
author_id = await self._get_author_id(call.message.message_id)
|
||||
logger.debug(f"ID автора получен: {author_id}")
|
||||
|
||||
|
||||
await self.db.update_status_by_message_id(call.message.message_id, "declined")
|
||||
logger.debug(f"Удаляю сообщение из группы {self.group_for_posts}")
|
||||
await self._get_bot(call.message).delete_message(chat_id=self.group_for_posts, message_id=call.message.message_id)
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ aiohttp==3.9.1
|
||||
# Network stability improvements
|
||||
aiohttp[speedups]>=3.9.1
|
||||
aiodns>=3.0.0
|
||||
cchardet>=2.1.7
|
||||
charset-normalizer>=3.0.0
|
||||
|
||||
# Development tools
|
||||
pluggy==1.5.0
|
||||
|
||||
82
scripts/backfill_post_status_legacy.py
Normal file
82
scripts/backfill_post_status_legacy.py
Normal file
@@ -0,0 +1,82 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Скрипт для проставления status='legacy' всем существующим записям в post_from_telegram_suggest.
|
||||
Добавляет колонку status, если её нет, затем обновляет все строки.
|
||||
"""
|
||||
import argparse
|
||||
import asyncio
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
project_root = Path(__file__).resolve().parent.parent
|
||||
sys.path.insert(0, str(project_root))
|
||||
|
||||
import aiosqlite
|
||||
|
||||
from logs.custom_logger import logger
|
||||
|
||||
DEFAULT_DB_PATH = "database/tg-bot-database.db"
|
||||
|
||||
|
||||
def _column_exists(rows: list, name: str) -> bool:
|
||||
"""PRAGMA table_info returns (cid, name, type, notnull, dflt_value, pk)."""
|
||||
for row in rows:
|
||||
if row[1] == name:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
async def main(db_path: str) -> None:
|
||||
db_path = os.path.abspath(db_path)
|
||||
if not os.path.exists(db_path):
|
||||
logger.error("База данных не найдена: %s", db_path)
|
||||
print(f"Ошибка: база данных не найдена: {db_path}")
|
||||
return
|
||||
|
||||
async with aiosqlite.connect(db_path) as conn:
|
||||
await conn.execute("PRAGMA foreign_keys = ON")
|
||||
|
||||
# Проверяем наличие колонки status
|
||||
cursor = await conn.execute(
|
||||
"PRAGMA table_info(post_from_telegram_suggest)"
|
||||
)
|
||||
rows = await cursor.fetchall()
|
||||
await cursor.close()
|
||||
|
||||
if not _column_exists(rows, "status"):
|
||||
logger.info("Добавление колонки status в post_from_telegram_suggest")
|
||||
await conn.execute(
|
||||
"ALTER TABLE post_from_telegram_suggest "
|
||||
"ADD COLUMN status TEXT NOT NULL DEFAULT 'suggest'"
|
||||
)
|
||||
await conn.commit()
|
||||
print("Колонка status добавлена.")
|
||||
else:
|
||||
print("Колонка status уже существует.")
|
||||
|
||||
# Обновляем все существующие записи на legacy
|
||||
await conn.execute(
|
||||
"UPDATE post_from_telegram_suggest SET status = 'legacy'"
|
||||
)
|
||||
await conn.commit()
|
||||
cursor = await conn.execute("SELECT changes()")
|
||||
row = await cursor.fetchone()
|
||||
updated = row[0] if row else 0
|
||||
await cursor.close()
|
||||
|
||||
logger.info("Обновлено записей в post_from_telegram_suggest: %d", updated)
|
||||
print(f"Обновлено записей: {updated}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Backfill status='legacy' для post_from_telegram_suggest"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--db",
|
||||
default=os.environ.get("DB_PATH", DEFAULT_DB_PATH),
|
||||
help="Путь к БД (или DB_PATH)",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
asyncio.run(main(args.db))
|
||||
Reference in New Issue
Block a user