Обновление управления статусами сообщений и схемы базы данных
- Добавлены методы в `AsyncBotDB` и `PostRepository` для обновления статусов сообщений по идентификатору сообщения и для групп медиафайлов. - Добавлено поле `status` в модель `TelegramPost` и обновлена схема базы данных, чтобы включить это поле со значением по умолчанию 'suggest'. - Обновлен `PostPublishService` для установки статусов сообщений на 'approved' или 'declined' в процессе публикации.
This commit is contained in:
@@ -159,6 +159,18 @@ class AsyncBotDB:
|
|||||||
"""Получает ID автора по helper_text_message_id."""
|
"""Получает ID автора по helper_text_message_id."""
|
||||||
return await self.factory.posts.get_author_id_by_helper_message_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,
|
async def set_user_blacklist(self, user_id: int, user_name: str = None,
|
||||||
message_for_user: str = None, date_to_unban: int = None):
|
message_for_user: str = None, date_to_unban: int = None):
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ class TelegramPost:
|
|||||||
author_id: int
|
author_id: int
|
||||||
helper_text_message_id: Optional[int] = None
|
helper_text_message_id: Optional[int] = None
|
||||||
created_at: Optional[int] = None
|
created_at: Optional[int] = None
|
||||||
|
status: str = "suggest"
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ class PostRepository(DatabaseConnection):
|
|||||||
helper_text_message_id INTEGER,
|
helper_text_message_id INTEGER,
|
||||||
author_id INTEGER,
|
author_id INTEGER,
|
||||||
created_at INTEGER NOT NULL,
|
created_at INTEGER NOT NULL,
|
||||||
|
status TEXT NOT NULL DEFAULT 'suggest',
|
||||||
FOREIGN KEY (author_id) REFERENCES our_users (user_id) ON DELETE CASCADE
|
FOREIGN KEY (author_id) REFERENCES our_users (user_id) ON DELETE CASCADE
|
||||||
)
|
)
|
||||||
'''
|
'''
|
||||||
@@ -51,12 +52,13 @@ class PostRepository(DatabaseConnection):
|
|||||||
"""Добавление поста."""
|
"""Добавление поста."""
|
||||||
if not post.created_at:
|
if not post.created_at:
|
||||||
post.created_at = int(datetime.now().timestamp())
|
post.created_at = int(datetime.now().timestamp())
|
||||||
|
status = post.status if post.status else "suggest"
|
||||||
|
|
||||||
query = """
|
query = """
|
||||||
INSERT INTO post_from_telegram_suggest (message_id, text, author_id, created_at)
|
INSERT INTO post_from_telegram_suggest (message_id, text, author_id, created_at, status)
|
||||||
VALUES (?, ?, ?, ?)
|
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)
|
await self._execute_query(query, params)
|
||||||
self.logger.info(f"Пост добавлен: message_id={post.message_id}")
|
self.logger.info(f"Пост добавлен: message_id={post.message_id}")
|
||||||
@@ -66,6 +68,26 @@ class PostRepository(DatabaseConnection):
|
|||||||
query = "UPDATE post_from_telegram_suggest SET helper_text_message_id = ? WHERE message_id = ?"
|
query = "UPDATE post_from_telegram_suggest SET helper_text_message_id = ? WHERE message_id = ?"
|
||||||
await self._execute_query(query, (helper_message_id, 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:
|
async def add_post_content(self, post_id: int, message_id: int, content_name: str, content_type: str) -> bool:
|
||||||
"""Добавление контента поста."""
|
"""Добавление контента поста."""
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ CREATE TABLE IF NOT EXISTS post_from_telegram_suggest (
|
|||||||
helper_text_message_id INTEGER,
|
helper_text_message_id INTEGER,
|
||||||
author_id INTEGER,
|
author_id INTEGER,
|
||||||
created_at INTEGER NOT NULL,
|
created_at INTEGER NOT NULL,
|
||||||
|
status TEXT NOT NULL DEFAULT 'suggest',
|
||||||
FOREIGN KEY (author_id) REFERENCES our_users(user_id) ON DELETE CASCADE
|
FOREIGN KEY (author_id) REFERENCES our_users(user_id) ON DELETE CASCADE
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ class PostPublishService:
|
|||||||
text_post = html.escape(str(call.message.text))
|
text_post = html.escape(str(call.message.text))
|
||||||
author_id = await self._get_author_id(call.message.message_id)
|
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 send_text_message(self.main_public, call.message, text_post)
|
||||||
await self._delete_post_and_notify_author(call, author_id)
|
await self._delete_post_and_notify_author(call, author_id)
|
||||||
logger.info(f'Текст сообщения опубликован в канале {self.main_public}.')
|
logger.info(f'Текст сообщения опубликован в канале {self.main_public}.')
|
||||||
@@ -92,6 +93,7 @@ class PostPublishService:
|
|||||||
text_post_with_photo = html.escape(str(call.message.caption))
|
text_post_with_photo = html.escape(str(call.message.caption))
|
||||||
author_id = await self._get_author_id(call.message.message_id)
|
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 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)
|
await self._delete_post_and_notify_author(call, author_id)
|
||||||
logger.info(f'Пост с фото опубликован в канале {self.main_public}.')
|
logger.info(f'Пост с фото опубликован в канале {self.main_public}.')
|
||||||
@@ -103,6 +105,7 @@ class PostPublishService:
|
|||||||
text_post_with_photo = html.escape(str(call.message.caption))
|
text_post_with_photo = html.escape(str(call.message.caption))
|
||||||
author_id = await self._get_author_id(call.message.message_id)
|
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 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)
|
await self._delete_post_and_notify_author(call, author_id)
|
||||||
logger.info(f'Пост с видео опубликован в канале {self.main_public}.')
|
logger.info(f'Пост с видео опубликован в канале {self.main_public}.')
|
||||||
@@ -113,6 +116,7 @@ class PostPublishService:
|
|||||||
"""Публикация поста с кружком"""
|
"""Публикация поста с кружком"""
|
||||||
author_id = await self._get_author_id(call.message.message_id)
|
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 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)
|
await self._delete_post_and_notify_author(call, author_id)
|
||||||
logger.info(f'Пост с кружком опубликован в канале {self.main_public}.')
|
logger.info(f'Пост с кружком опубликован в канале {self.main_public}.')
|
||||||
@@ -124,6 +128,7 @@ class PostPublishService:
|
|||||||
text_post_with_photo = html.escape(str(call.message.caption))
|
text_post_with_photo = html.escape(str(call.message.caption))
|
||||||
author_id = await self._get_author_id(call.message.message_id)
|
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 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)
|
await self._delete_post_and_notify_author(call, author_id)
|
||||||
logger.info(f'Пост с аудио опубликован в канале {self.main_public}.')
|
logger.info(f'Пост с аудио опубликован в канале {self.main_public}.')
|
||||||
@@ -134,6 +139,7 @@ class PostPublishService:
|
|||||||
"""Публикация поста с войсом"""
|
"""Публикация поста с войсом"""
|
||||||
author_id = await self._get_author_id(call.message.message_id)
|
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 send_voice_message(self.main_public, call.message, call.message.voice.file_id)
|
||||||
await self._delete_post_and_notify_author(call, author_id)
|
await self._delete_post_and_notify_author(call, author_id)
|
||||||
logger.info(f'Пост с войсом опубликован в канале {self.main_public}.')
|
logger.info(f'Пост с войсом опубликован в канале {self.main_public}.')
|
||||||
@@ -178,6 +184,7 @@ class PostPublishService:
|
|||||||
post_text=post_text
|
post_text=post_text
|
||||||
)
|
)
|
||||||
|
|
||||||
|
await self.db.update_status_for_media_group_by_helper_id(helper_message_id, "approved")
|
||||||
logger.debug(f"Удаляю медиагруппу и уведомляю автора {author_id}")
|
logger.debug(f"Удаляю медиагруппу и уведомляю автора {author_id}")
|
||||||
await self._delete_media_group_and_notify_author(call, author_id)
|
await self._delete_media_group_and_notify_author(call, author_id)
|
||||||
logger.info(f'Медиагруппа опубликована в канале {self.main_public}.')
|
logger.info(f'Медиагруппа опубликована в канале {self.main_public}.')
|
||||||
@@ -215,6 +222,7 @@ class PostPublishService:
|
|||||||
author_id = await self._get_author_id(call.message.message_id)
|
author_id = await self._get_author_id(call.message.message_id)
|
||||||
logger.debug(f"ID автора получен: {author_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}")
|
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)
|
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
|
# Network stability improvements
|
||||||
aiohttp[speedups]>=3.9.1
|
aiohttp[speedups]>=3.9.1
|
||||||
aiodns>=3.0.0
|
aiodns>=3.0.0
|
||||||
cchardet>=2.1.7
|
charset-normalizer>=3.0.0
|
||||||
|
|
||||||
# Development tools
|
# Development tools
|
||||||
pluggy==1.5.0
|
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