Астат ты не вознесешься
This commit is contained in:
@@ -11,6 +11,7 @@ from sqlalchemy.ext.asyncio import (
|
||||
AsyncEngine
|
||||
)
|
||||
|
||||
from configs import settings
|
||||
from middleware.loggers import logger
|
||||
from .models import Base
|
||||
|
||||
@@ -26,7 +27,7 @@ class Database:
|
||||
session_factory: Фабрика сессий
|
||||
"""
|
||||
|
||||
def __init__(self, db_path: str = "banwords.db"):
|
||||
def __init__(self, db_path: str = settings.DATABASE_PATH):
|
||||
"""
|
||||
Args:
|
||||
db_path: Путь к SQLite файлу
|
||||
@@ -99,7 +100,7 @@ class Database:
|
||||
_db_instance: Database | None = None
|
||||
|
||||
|
||||
def get_db(db_path: str = "banwords.db") -> Database:
|
||||
def get_db(db_path: str = settings.DATABASE_PATH) -> Database:
|
||||
"""
|
||||
Возвращает глобальный экземпляр Database (Singleton).
|
||||
|
||||
|
||||
@@ -623,6 +623,98 @@ class BanWordsManager:
|
||||
await session.rollback()
|
||||
return False
|
||||
|
||||
# === AUTO COMMENTS ===
|
||||
|
||||
async def get_auto_comment_settings(self, channel_id: int) -> dict:
|
||||
"""
|
||||
Получает настройки автокомментариев для канала.
|
||||
|
||||
Args:
|
||||
channel_id: ID канала
|
||||
|
||||
Returns:
|
||||
dict: Настройки или значения по умолчанию
|
||||
"""
|
||||
from configs import settings
|
||||
|
||||
auto_comment = await self.repo.get_auto_comment(channel_id)
|
||||
|
||||
if auto_comment and auto_comment.is_enabled:
|
||||
return {
|
||||
'text': auto_comment.text,
|
||||
'button_text': auto_comment.button_text,
|
||||
'button_url': auto_comment.button_url,
|
||||
'photo_url': auto_comment.photo_url,
|
||||
'is_enabled': auto_comment.is_enabled,
|
||||
}
|
||||
|
||||
# Возвращаем настройки по умолчанию из .env
|
||||
return {
|
||||
'text': settings.AUTO_COMMENT_TEXT,
|
||||
'button_text': settings.AUTO_COMMENT_BUTTON_TEXT,
|
||||
'button_url': settings.AUTO_COMMENT_BUTTON_URL,
|
||||
'photo_url': settings.AUTO_COMMENT_PHOTO_URL,
|
||||
'is_enabled': False, # По умолчанию выключено
|
||||
}
|
||||
|
||||
async def save_auto_comment_settings(
|
||||
self,
|
||||
channel_id: int,
|
||||
text: str,
|
||||
button_text: str,
|
||||
button_url: str,
|
||||
photo_url: str,
|
||||
updated_by: Optional[int] = None
|
||||
) -> bool:
|
||||
"""Сохраняет настройки автокомментариев"""
|
||||
return await self.repo.set_auto_comment(
|
||||
channel_id=channel_id,
|
||||
text=text,
|
||||
button_text=button_text,
|
||||
button_url=button_url,
|
||||
photo_url=photo_url,
|
||||
updated_by=updated_by,
|
||||
is_enabled=True
|
||||
)
|
||||
|
||||
async def update_auto_comment_text(
|
||||
self,
|
||||
channel_id: int,
|
||||
text: str,
|
||||
updated_by: Optional[int] = None
|
||||
) -> bool:
|
||||
"""Обновляет текст автокомментария"""
|
||||
return await self.repo.update_auto_comment_field(
|
||||
channel_id, 'text', text, updated_by
|
||||
)
|
||||
|
||||
async def update_auto_comment_button(
|
||||
self,
|
||||
channel_id: int,
|
||||
button_text: str,
|
||||
button_url: str,
|
||||
updated_by: Optional[int] = None
|
||||
) -> bool:
|
||||
"""Обновляет кнопку автокомментария"""
|
||||
success_text = await self.repo.update_auto_comment_field(
|
||||
channel_id, 'button_text', button_text, updated_by
|
||||
)
|
||||
success_url = await self.repo.update_auto_comment_field(
|
||||
channel_id, 'button_url', button_url, updated_by
|
||||
)
|
||||
return success_text and success_url
|
||||
|
||||
async def update_auto_comment_photo(
|
||||
self,
|
||||
channel_id: int,
|
||||
photo_url: str,
|
||||
updated_by: Optional[int] = None
|
||||
) -> bool:
|
||||
"""Обновляет фото автокомментария"""
|
||||
return await self.repo.update_auto_comment_field(
|
||||
channel_id, 'photo_url', photo_url, updated_by
|
||||
)
|
||||
|
||||
|
||||
# Глобальный экземпляр менеджера
|
||||
_manager_instance: Optional[BanWordsManager] = None
|
||||
|
||||
@@ -19,6 +19,7 @@ __all__ = (
|
||||
"Setting",
|
||||
"SpamStat",
|
||||
"SpamLog",
|
||||
"AutoComment",
|
||||
)
|
||||
|
||||
|
||||
@@ -252,3 +253,44 @@ class SpamLog(Base):
|
||||
DateTime,
|
||||
default=lambda: datetime.now(timezone.utc)
|
||||
)
|
||||
|
||||
class AutoComment(Base):
|
||||
"""
|
||||
Настройки автокомментариев для каналов.
|
||||
|
||||
Attributes:
|
||||
id: Уникальный ID
|
||||
channel_id: ID канала (-100...)
|
||||
text: Текст комментария (HTML)
|
||||
button_text: Текст кнопки
|
||||
button_url: URL кнопки
|
||||
photo_url: URL фото для preview
|
||||
is_enabled: Включены ли автокомментарии для этого канала
|
||||
created_at: Дата создания
|
||||
updated_at: Дата последнего обновления
|
||||
updated_by: ID админа, который последним изменил
|
||||
"""
|
||||
__tablename__ = "auto_comments"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
|
||||
channel_id: Mapped[int] = mapped_column(BigInteger, nullable=False, unique=True, index=True)
|
||||
text: Mapped[str] = mapped_column(Text, nullable=False)
|
||||
button_text: Mapped[str] = mapped_column(String(100), nullable=False)
|
||||
button_url: Mapped[str] = mapped_column(String(500), nullable=False)
|
||||
photo_url: Mapped[str] = mapped_column(String(500), nullable=False)
|
||||
is_enabled: Mapped[bool] = mapped_column(Integer, default=1, nullable=False)
|
||||
created_at: Mapped[datetime] = mapped_column(
|
||||
DateTime,
|
||||
default=lambda: datetime.now(timezone.utc),
|
||||
nullable=False
|
||||
)
|
||||
updated_at: Mapped[datetime] = mapped_column(
|
||||
DateTime,
|
||||
default=lambda: datetime.now(timezone.utc),
|
||||
onupdate=lambda: datetime.now(timezone.utc),
|
||||
nullable=False
|
||||
)
|
||||
updated_by: Mapped[Optional[int]] = mapped_column(Integer, nullable=True)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"<AutoComment(channel_id={self.channel_id}, enabled={self.is_enabled})>"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
Repository для работы с банвордами через SQLAlchemy ORM.
|
||||
"""
|
||||
from typing import Set, List, Optional
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import datetime, timedelta, timezone
|
||||
|
||||
from sqlalchemy import select, delete, func, and_
|
||||
|
||||
@@ -15,7 +15,8 @@ from .models import (
|
||||
Admin,
|
||||
Setting,
|
||||
SpamStat,
|
||||
BanWordType
|
||||
BanWordType,
|
||||
AutoComment
|
||||
)
|
||||
|
||||
__all__ = ("BanWordsRepository",)
|
||||
@@ -796,3 +797,252 @@ class BanWordsRepository:
|
||||
log_type="DATABASE"
|
||||
)
|
||||
return {}
|
||||
|
||||
# === AUTO COMMENTS ===
|
||||
|
||||
async def get_auto_comment(self, channel_id: int) -> Optional['AutoComment']:
|
||||
"""
|
||||
Получает настройки автокомментариев для канала.
|
||||
|
||||
Args:
|
||||
channel_id: ID канала
|
||||
|
||||
Returns:
|
||||
AutoComment или None
|
||||
"""
|
||||
try:
|
||||
async with self.db.get_session() as session:
|
||||
result = await session.execute(
|
||||
select(AutoComment).where(AutoComment.channel_id == channel_id)
|
||||
)
|
||||
return result.scalar_one_or_none()
|
||||
except Exception as e:
|
||||
logger.error(
|
||||
f"Ошибка получения автокомментария: {e}",
|
||||
log_type="DATABASE"
|
||||
)
|
||||
return None
|
||||
|
||||
async def set_auto_comment(
|
||||
self,
|
||||
channel_id: int,
|
||||
text: str,
|
||||
button_text: str,
|
||||
button_url: str,
|
||||
photo_url: str,
|
||||
updated_by: Optional[int] = None,
|
||||
is_enabled: bool = True
|
||||
) -> bool:
|
||||
"""
|
||||
Сохраняет или обновляет настройки автокомментариев.
|
||||
|
||||
Args:
|
||||
channel_id: ID канала
|
||||
text: Текст комментария
|
||||
button_text: Текст кнопки
|
||||
button_url: URL кнопки
|
||||
photo_url: URL фото
|
||||
updated_by: ID админа
|
||||
is_enabled: Включены ли комментарии
|
||||
|
||||
Returns:
|
||||
bool: True если успешно
|
||||
"""
|
||||
try:
|
||||
async with self.db.get_session() as session:
|
||||
# Проверяем существование
|
||||
result = await session.execute(
|
||||
select(AutoComment).where(AutoComment.channel_id == channel_id)
|
||||
)
|
||||
auto_comment = result.scalar_one_or_none()
|
||||
|
||||
if auto_comment:
|
||||
# Обновляем существующую
|
||||
auto_comment.text = text
|
||||
auto_comment.button_text = button_text
|
||||
auto_comment.button_url = button_url
|
||||
auto_comment.photo_url = photo_url
|
||||
auto_comment.is_enabled = is_enabled
|
||||
auto_comment.updated_by = updated_by
|
||||
auto_comment.updated_at = datetime.now(timezone.utc)
|
||||
else:
|
||||
# Создаём новую
|
||||
auto_comment = AutoComment(
|
||||
channel_id=channel_id,
|
||||
text=text,
|
||||
button_text=button_text,
|
||||
button_url=button_url,
|
||||
photo_url=photo_url,
|
||||
is_enabled=is_enabled,
|
||||
updated_by=updated_by
|
||||
)
|
||||
session.add(auto_comment)
|
||||
|
||||
await session.commit()
|
||||
|
||||
logger.info(
|
||||
f"Автокомментарий для канала {channel_id} обновлён",
|
||||
log_type="DATABASE"
|
||||
)
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
logger.error(
|
||||
f"Ошибка сохранения автокомментария: {e}",
|
||||
log_type="DATABASE"
|
||||
)
|
||||
return False
|
||||
|
||||
async def update_auto_comment_field(
|
||||
self,
|
||||
channel_id: int,
|
||||
field: str,
|
||||
value: str,
|
||||
updated_by: Optional[int] = None
|
||||
) -> bool:
|
||||
"""
|
||||
Обновляет одно поле автокомментария.
|
||||
|
||||
Args:
|
||||
channel_id: ID канала
|
||||
field: Имя поля (text, button_text, button_url, photo_url)
|
||||
value: Новое значение
|
||||
updated_by: ID админа
|
||||
|
||||
Returns:
|
||||
bool: True если успешно
|
||||
"""
|
||||
try:
|
||||
|
||||
async with self.db.get_session() as session:
|
||||
result = await session.execute(
|
||||
select(AutoComment).where(AutoComment.channel_id == channel_id)
|
||||
)
|
||||
auto_comment = result.scalar_one_or_none()
|
||||
|
||||
if not auto_comment:
|
||||
return False
|
||||
|
||||
# Обновляем поле
|
||||
if hasattr(auto_comment, field):
|
||||
setattr(auto_comment, field, value)
|
||||
auto_comment.updated_by = updated_by
|
||||
auto_comment.updated_at = datetime.now(timezone.utc)
|
||||
await session.commit()
|
||||
|
||||
logger.info(
|
||||
f"Поле '{field}' автокомментария для канала {channel_id} обновлено",
|
||||
log_type="DATABASE"
|
||||
)
|
||||
return True
|
||||
else:
|
||||
logger.error(
|
||||
f"Поле '{field}' не существует в AutoComment",
|
||||
log_type="DATABASE"
|
||||
)
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
logger.error(
|
||||
f"Ошибка обновления поля автокомментария: {e}",
|
||||
log_type="DATABASE"
|
||||
)
|
||||
return False
|
||||
|
||||
async def toggle_auto_comment(
|
||||
self,
|
||||
channel_id: int,
|
||||
is_enabled: bool,
|
||||
updated_by: Optional[int] = None
|
||||
) -> bool:
|
||||
"""
|
||||
Включает/выключает автокомментарии для канала.
|
||||
|
||||
Args:
|
||||
channel_id: ID канала
|
||||
is_enabled: True - включить, False - выключить
|
||||
updated_by: ID админа
|
||||
|
||||
Returns:
|
||||
bool: True если успешно
|
||||
"""
|
||||
try:
|
||||
|
||||
async with self.db.get_session() as session:
|
||||
result = await session.execute(
|
||||
select(AutoComment).where(AutoComment.channel_id == channel_id)
|
||||
)
|
||||
auto_comment = result.scalar_one_or_none()
|
||||
|
||||
if not auto_comment:
|
||||
return False
|
||||
|
||||
auto_comment.is_enabled = is_enabled
|
||||
auto_comment.updated_by = updated_by
|
||||
auto_comment.updated_at = datetime.now(timezone.utc)
|
||||
await session.commit()
|
||||
|
||||
logger.info(
|
||||
f"Автокомментарии для канала {channel_id} {'включены' if is_enabled else 'выключены'}",
|
||||
log_type="DATABASE"
|
||||
)
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
logger.error(
|
||||
f"Ошибка переключения автокомментария: {e}",
|
||||
log_type="DATABASE"
|
||||
)
|
||||
return False
|
||||
|
||||
async def get_all_auto_comments(self) -> list['AutoComment']:
|
||||
"""
|
||||
Получает все настройки автокомментариев.
|
||||
|
||||
Returns:
|
||||
List[AutoComment]: Список всех автокомментариев
|
||||
"""
|
||||
try:
|
||||
|
||||
async with self.db.get_session() as session:
|
||||
result = await session.execute(select(AutoComment))
|
||||
return list(result.scalars().all())
|
||||
except Exception as e:
|
||||
logger.error(
|
||||
f"Ошибка получения всех автокомментариев: {e}",
|
||||
log_type="DATABASE"
|
||||
)
|
||||
return []
|
||||
|
||||
async def delete_auto_comment(self, channel_id: int) -> bool:
|
||||
"""
|
||||
Удаляет настройки автокомментариев для канала.
|
||||
|
||||
Args:
|
||||
channel_id: ID канала
|
||||
|
||||
Returns:
|
||||
bool: True если удалено
|
||||
"""
|
||||
try:
|
||||
|
||||
async with self.db.get_session() as session:
|
||||
result = await session.execute(
|
||||
delete(AutoComment).where(AutoComment.channel_id == channel_id)
|
||||
)
|
||||
await session.commit()
|
||||
deleted = result.rowcount > 0
|
||||
|
||||
if deleted:
|
||||
logger.info(
|
||||
f"Автокомментарий для канала {channel_id} удалён",
|
||||
log_type="DATABASE"
|
||||
)
|
||||
return deleted
|
||||
|
||||
except Exception as e:
|
||||
logger.error(
|
||||
f"Ошибка удаления автокомментария: {e}",
|
||||
log_type="DATABASE"
|
||||
)
|
||||
return False
|
||||
|
||||
Reference in New Issue
Block a user