fix quality code
This commit is contained in:
@@ -20,6 +20,11 @@ from .post_repository import PostRepository
|
||||
from .user_repository import UserRepository
|
||||
|
||||
__all__ = [
|
||||
'UserRepository', 'BlacklistRepository', 'BlacklistHistoryRepository',
|
||||
'MessageRepository', 'PostRepository', 'AdminRepository', 'AudioRepository'
|
||||
"UserRepository",
|
||||
"BlacklistRepository",
|
||||
"BlacklistHistoryRepository",
|
||||
"MessageRepository",
|
||||
"PostRepository",
|
||||
"AdminRepository",
|
||||
"AudioRepository",
|
||||
]
|
||||
|
||||
@@ -6,70 +6,68 @@ from database.models import Admin
|
||||
|
||||
class AdminRepository(DatabaseConnection):
|
||||
"""Репозиторий для работы с администраторами."""
|
||||
|
||||
|
||||
async def create_tables(self):
|
||||
"""Создание таблицы администраторов."""
|
||||
# Включаем поддержку внешних ключей
|
||||
await self._execute_query("PRAGMA foreign_keys = ON")
|
||||
|
||||
query = '''
|
||||
|
||||
query = """
|
||||
CREATE TABLE IF NOT EXISTS admins (
|
||||
user_id INTEGER NOT NULL PRIMARY KEY,
|
||||
role TEXT DEFAULT 'admin',
|
||||
created_at INTEGER DEFAULT (strftime('%s', 'now')),
|
||||
FOREIGN KEY (user_id) REFERENCES our_users (user_id) ON DELETE CASCADE
|
||||
)
|
||||
'''
|
||||
"""
|
||||
await self._execute_query(query)
|
||||
self.logger.info("Таблица администраторов создана")
|
||||
|
||||
|
||||
async def add_admin(self, admin: Admin) -> None:
|
||||
"""Добавление администратора."""
|
||||
query = "INSERT INTO admins (user_id, role) VALUES (?, ?)"
|
||||
params = (admin.user_id, admin.role)
|
||||
|
||||
|
||||
await self._execute_query(query, params)
|
||||
self.logger.info(f"Администратор добавлен: user_id={admin.user_id}, role={admin.role}")
|
||||
|
||||
self.logger.info(
|
||||
f"Администратор добавлен: user_id={admin.user_id}, role={admin.role}"
|
||||
)
|
||||
|
||||
async def remove_admin(self, user_id: int) -> None:
|
||||
"""Удаление администратора."""
|
||||
query = "DELETE FROM admins WHERE user_id = ?"
|
||||
await self._execute_query(query, (user_id,))
|
||||
self.logger.info(f"Администратор удален: user_id={user_id}")
|
||||
|
||||
|
||||
async def is_admin(self, user_id: int) -> bool:
|
||||
"""Проверка, является ли пользователь администратором."""
|
||||
query = "SELECT 1 FROM admins WHERE user_id = ?"
|
||||
rows = await self._execute_query_with_result(query, (user_id,))
|
||||
row = rows[0] if rows else None
|
||||
return bool(row)
|
||||
|
||||
|
||||
async def get_admin(self, user_id: int) -> Optional[Admin]:
|
||||
"""Получение информации об администраторе."""
|
||||
query = "SELECT user_id, role, created_at FROM admins WHERE user_id = ?"
|
||||
rows = await self._execute_query_with_result(query, (user_id,))
|
||||
row = rows[0] if rows else None
|
||||
|
||||
|
||||
if row:
|
||||
return Admin(
|
||||
user_id=row[0],
|
||||
role=row[1],
|
||||
created_at=row[2] if len(row) > 2 else None
|
||||
user_id=row[0], role=row[1], created_at=row[2] if len(row) > 2 else None
|
||||
)
|
||||
return None
|
||||
|
||||
|
||||
async def get_all_admins(self) -> list[Admin]:
|
||||
"""Получение всех администраторов."""
|
||||
query = "SELECT user_id, role, created_at FROM admins ORDER BY created_at DESC"
|
||||
rows = await self._execute_query_with_result(query)
|
||||
|
||||
|
||||
admins = []
|
||||
for row in rows:
|
||||
admin = Admin(
|
||||
user_id=row[0],
|
||||
role=row[1],
|
||||
created_at=row[2] if len(row) > 2 else None
|
||||
user_id=row[0], role=row[1], created_at=row[2] if len(row) > 2 else None
|
||||
)
|
||||
admins.append(admin)
|
||||
|
||||
|
||||
return admins
|
||||
|
||||
@@ -7,15 +7,15 @@ from database.models import AudioListenRecord, AudioMessage, AudioModerate
|
||||
|
||||
class AudioRepository(DatabaseConnection):
|
||||
"""Репозиторий для работы с аудио сообщениями."""
|
||||
|
||||
|
||||
async def enable_foreign_keys(self):
|
||||
"""Включает поддержку внешних ключей."""
|
||||
await self._execute_query("PRAGMA foreign_keys = ON;")
|
||||
|
||||
|
||||
async def create_tables(self):
|
||||
"""Создание таблиц для аудио."""
|
||||
# Таблица аудио сообщений
|
||||
audio_query = '''
|
||||
audio_query = """
|
||||
CREATE TABLE IF NOT EXISTS audio_message_reference (
|
||||
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
file_name TEXT NOT NULL UNIQUE,
|
||||
@@ -23,33 +23,33 @@ class AudioRepository(DatabaseConnection):
|
||||
date_added INTEGER NOT NULL,
|
||||
FOREIGN KEY (author_id) REFERENCES our_users (user_id) ON DELETE CASCADE
|
||||
)
|
||||
'''
|
||||
"""
|
||||
await self._execute_query(audio_query)
|
||||
|
||||
|
||||
# Таблица прослушивания аудио
|
||||
listen_query = '''
|
||||
listen_query = """
|
||||
CREATE TABLE IF NOT EXISTS user_audio_listens (
|
||||
file_name TEXT NOT NULL,
|
||||
user_id INTEGER NOT NULL,
|
||||
PRIMARY KEY (file_name, user_id),
|
||||
FOREIGN KEY (user_id) REFERENCES our_users (user_id) ON DELETE CASCADE
|
||||
)
|
||||
'''
|
||||
"""
|
||||
await self._execute_query(listen_query)
|
||||
|
||||
|
||||
# Таблица для voice bot
|
||||
voice_query = '''
|
||||
voice_query = """
|
||||
CREATE TABLE IF NOT EXISTS audio_moderate (
|
||||
user_id INTEGER NOT NULL,
|
||||
message_id INTEGER,
|
||||
PRIMARY KEY (user_id, message_id),
|
||||
FOREIGN KEY (user_id) REFERENCES our_users (user_id) ON DELETE CASCADE
|
||||
)
|
||||
'''
|
||||
"""
|
||||
await self._execute_query(voice_query)
|
||||
|
||||
|
||||
self.logger.info("Таблицы для аудио созданы")
|
||||
|
||||
|
||||
async def add_audio_record(self, audio: AudioMessage) -> None:
|
||||
"""Добавляет информацию о войсе пользователя."""
|
||||
query = """
|
||||
@@ -63,13 +63,17 @@ class AudioRepository(DatabaseConnection):
|
||||
date_timestamp = int(audio.date_added.timestamp())
|
||||
else:
|
||||
date_timestamp = audio.date_added
|
||||
|
||||
|
||||
params = (audio.file_name, audio.author_id, date_timestamp)
|
||||
|
||||
|
||||
await self._execute_query(query, params)
|
||||
self.logger.info(f"Аудио добавлено: file_name={audio.file_name}, author_id={audio.author_id}")
|
||||
|
||||
async def add_audio_record_simple(self, file_name: str, user_id: int, date_added) -> None:
|
||||
self.logger.info(
|
||||
f"Аудио добавлено: file_name={audio.file_name}, author_id={audio.author_id}"
|
||||
)
|
||||
|
||||
async def add_audio_record_simple(
|
||||
self, file_name: str, user_id: int, date_added
|
||||
) -> None:
|
||||
"""Добавляет информацию о войсе пользователя (упрощенная версия)."""
|
||||
query = """
|
||||
INSERT INTO audio_message_reference (file_name, author_id, date_added)
|
||||
@@ -82,30 +86,30 @@ class AudioRepository(DatabaseConnection):
|
||||
date_timestamp = int(date_added.timestamp())
|
||||
else:
|
||||
date_timestamp = date_added
|
||||
|
||||
|
||||
params = (file_name, user_id, date_timestamp)
|
||||
|
||||
|
||||
await self._execute_query(query, params)
|
||||
self.logger.info(f"Аудио добавлено: file_name={file_name}, user_id={user_id}")
|
||||
|
||||
|
||||
async def get_last_date_audio(self) -> Optional[int]:
|
||||
"""Получает дату последнего войса."""
|
||||
query = "SELECT date_added FROM audio_message_reference ORDER BY date_added DESC LIMIT 1"
|
||||
rows = await self._execute_query_with_result(query)
|
||||
row = rows[0] if rows else None
|
||||
|
||||
|
||||
if row:
|
||||
self.logger.info(f"Последняя дата аудио: {row[0]}")
|
||||
return row[0]
|
||||
return None
|
||||
|
||||
|
||||
async def get_user_audio_records_count(self, user_id: int) -> int:
|
||||
"""Получает количество записей пользователя."""
|
||||
query = "SELECT COUNT(*) FROM audio_message_reference WHERE author_id = ?"
|
||||
rows = await self._execute_query_with_result(query, (user_id,))
|
||||
row = rows[0] if rows else None
|
||||
return row[0] if row else 0
|
||||
|
||||
|
||||
async def get_path_for_audio_record(self, user_id: int) -> Optional[str]:
|
||||
"""Получает название последнего файла пользователя."""
|
||||
query = """
|
||||
@@ -115,7 +119,7 @@ class AudioRepository(DatabaseConnection):
|
||||
rows = await self._execute_query_with_result(query, (user_id,))
|
||||
row = rows[0] if rows else None
|
||||
return row[0] if row else None
|
||||
|
||||
|
||||
async def check_listen_audio(self, user_id: int) -> List[str]:
|
||||
"""Проверяет непрослушанные аудио для пользователя."""
|
||||
query = """
|
||||
@@ -125,115 +129,129 @@ class AudioRepository(DatabaseConnection):
|
||||
WHERE l.user_id = ? AND l.file_name IS NOT NULL
|
||||
"""
|
||||
listened_files = await self._execute_query_with_result(query, (user_id,))
|
||||
|
||||
|
||||
# Получаем все аудио, кроме созданных пользователем
|
||||
all_audio_query = 'SELECT file_name FROM audio_message_reference WHERE author_id <> ?'
|
||||
all_audio_query = (
|
||||
"SELECT file_name FROM audio_message_reference WHERE author_id <> ?"
|
||||
)
|
||||
all_files = await self._execute_query_with_result(all_audio_query, (user_id,))
|
||||
|
||||
|
||||
# Находим непрослушанные
|
||||
listened_set = {row[0] for row in listened_files}
|
||||
all_set = {row[0] for row in all_files}
|
||||
new_files = list(all_set - listened_set)
|
||||
|
||||
self.logger.info(f"Найдено {len(new_files)} непрослушанных аудио для пользователя {user_id}")
|
||||
|
||||
self.logger.info(
|
||||
f"Найдено {len(new_files)} непрослушанных аудио для пользователя {user_id}"
|
||||
)
|
||||
return new_files
|
||||
|
||||
|
||||
async def mark_listened_audio(self, file_name: str, user_id: int) -> None:
|
||||
"""Отмечает аудио прослушанным для пользователя."""
|
||||
query = "INSERT OR IGNORE INTO user_audio_listens (file_name, user_id) VALUES (?, ?)"
|
||||
params = (file_name, user_id)
|
||||
|
||||
|
||||
await self._execute_query(query, params)
|
||||
self.logger.info(f"Аудио {file_name} отмечено как прослушанное для пользователя {user_id}")
|
||||
|
||||
self.logger.info(
|
||||
f"Аудио {file_name} отмечено как прослушанное для пользователя {user_id}"
|
||||
)
|
||||
|
||||
async def get_user_id_by_file_name(self, file_name: str) -> Optional[int]:
|
||||
"""Получает user_id пользователя по имени файла."""
|
||||
query = "SELECT author_id FROM audio_message_reference WHERE file_name = ?"
|
||||
rows = await self._execute_query_with_result(query, (file_name,))
|
||||
row = rows[0] if rows else None
|
||||
|
||||
|
||||
if row:
|
||||
user_id = row[0]
|
||||
self.logger.info(f"Получен user_id {user_id} для файла {file_name}")
|
||||
return user_id
|
||||
return None
|
||||
|
||||
|
||||
async def get_date_by_file_name(self, file_name: str) -> Optional[str]:
|
||||
"""Получает дату добавления файла."""
|
||||
query = "SELECT date_added FROM audio_message_reference WHERE file_name = ?"
|
||||
rows = await self._execute_query_with_result(query, (file_name,))
|
||||
row = rows[0] if rows else None
|
||||
|
||||
|
||||
if row:
|
||||
date_added = row[0]
|
||||
# Преобразуем UNIX timestamp в читаемую дату
|
||||
readable_date = datetime.fromtimestamp(date_added).strftime('%d.%m.%Y %H:%M')
|
||||
readable_date = datetime.fromtimestamp(date_added).strftime(
|
||||
"%d.%m.%Y %H:%M"
|
||||
)
|
||||
self.logger.info(f"Получена дата {readable_date} для файла {file_name}")
|
||||
return readable_date
|
||||
return None
|
||||
|
||||
|
||||
async def refresh_listen_audio(self, user_id: int) -> None:
|
||||
"""Очищает всю информацию о прослушанных аудио пользователем."""
|
||||
query = "DELETE FROM user_audio_listens WHERE user_id = ?"
|
||||
await self._execute_query(query, (user_id,))
|
||||
self.logger.info(f"Очищены записи прослушивания для пользователя {user_id}")
|
||||
|
||||
|
||||
async def delete_listen_count_for_user(self, user_id: int) -> None:
|
||||
"""Удаляет данные о прослушанных пользователем аудио."""
|
||||
query = "DELETE FROM user_audio_listens WHERE user_id = ?"
|
||||
await self._execute_query(query, (user_id,))
|
||||
self.logger.info(f"Удалены записи прослушивания для пользователя {user_id}")
|
||||
|
||||
|
||||
# Методы для voice bot
|
||||
async def set_user_id_and_message_id_for_voice_bot(self, message_id: int, user_id: int) -> bool:
|
||||
async def set_user_id_and_message_id_for_voice_bot(
|
||||
self, message_id: int, user_id: int
|
||||
) -> bool:
|
||||
"""Устанавливает связь между message_id и user_id для voice bot."""
|
||||
try:
|
||||
query = "INSERT OR IGNORE INTO audio_moderate (user_id, message_id) VALUES (?, ?)"
|
||||
params = (user_id, message_id)
|
||||
|
||||
|
||||
await self._execute_query(query, params)
|
||||
self.logger.info(f"Связь установлена: message_id={message_id}, user_id={user_id}")
|
||||
self.logger.info(
|
||||
f"Связь установлена: message_id={message_id}, user_id={user_id}"
|
||||
)
|
||||
return True
|
||||
except Exception as e:
|
||||
self.logger.error(f"Ошибка установки связи: {e}")
|
||||
return False
|
||||
|
||||
async def get_user_id_by_message_id_for_voice_bot(self, message_id: int) -> Optional[int]:
|
||||
|
||||
async def get_user_id_by_message_id_for_voice_bot(
|
||||
self, message_id: int
|
||||
) -> Optional[int]:
|
||||
"""Получает user_id пользователя по message_id для voice bot."""
|
||||
query = "SELECT user_id FROM audio_moderate WHERE message_id = ?"
|
||||
rows = await self._execute_query_with_result(query, (message_id,))
|
||||
row = rows[0] if rows else None
|
||||
|
||||
|
||||
if row:
|
||||
user_id = row[0]
|
||||
self.logger.info(f"Получен user_id {user_id} для message_id {message_id}")
|
||||
return user_id
|
||||
return None
|
||||
|
||||
|
||||
async def delete_audio_moderate_record(self, message_id: int) -> None:
|
||||
"""Удаляет запись из таблицы audio_moderate по message_id."""
|
||||
query = "DELETE FROM audio_moderate WHERE message_id = ?"
|
||||
await self._execute_query(query, (message_id,))
|
||||
self.logger.info(f"Удалена запись из audio_moderate для message_id {message_id}")
|
||||
|
||||
self.logger.info(
|
||||
f"Удалена запись из audio_moderate для message_id {message_id}"
|
||||
)
|
||||
|
||||
async def get_all_audio_records(self) -> List[Dict[str, Any]]:
|
||||
"""Получить все записи аудио сообщений."""
|
||||
query = "SELECT file_name, author_id, date_added FROM audio_message_reference"
|
||||
rows = await self._execute_query_with_result(query)
|
||||
|
||||
|
||||
records = []
|
||||
for row in rows:
|
||||
records.append({
|
||||
'file_name': row[0],
|
||||
'author_id': row[1],
|
||||
'date_added': row[2]
|
||||
})
|
||||
|
||||
records.append(
|
||||
{"file_name": row[0], "author_id": row[1], "date_added": row[2]}
|
||||
)
|
||||
|
||||
self.logger.info(f"Получено {len(records)} записей аудио сообщений")
|
||||
return records
|
||||
|
||||
|
||||
async def delete_audio_record_by_file_name(self, file_name: str) -> None:
|
||||
"""Удалить запись аудио сообщения по имени файла."""
|
||||
query = "DELETE FROM audio_message_reference WHERE file_name = ?"
|
||||
await self._execute_query(query, (file_name,))
|
||||
self.logger.info(f"Удалена запись аудио сообщения: {file_name}")
|
||||
self.logger.info(f"Удалена запись аудио сообщения: {file_name}")
|
||||
|
||||
@@ -6,10 +6,10 @@ from database.models import BlacklistHistoryRecord
|
||||
|
||||
class BlacklistHistoryRepository(DatabaseConnection):
|
||||
"""Репозиторий для работы с историей банов/разбанов."""
|
||||
|
||||
|
||||
async def create_tables(self):
|
||||
"""Создание таблицы истории банов/разбанов."""
|
||||
query = '''
|
||||
query = """
|
||||
CREATE TABLE IF NOT EXISTS blacklist_history (
|
||||
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
user_id INTEGER NOT NULL,
|
||||
@@ -22,9 +22,9 @@ class BlacklistHistoryRepository(DatabaseConnection):
|
||||
FOREIGN KEY (user_id) REFERENCES our_users(user_id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (ban_author) REFERENCES our_users(user_id) ON DELETE SET NULL
|
||||
)
|
||||
'''
|
||||
"""
|
||||
await self._execute_query(query)
|
||||
|
||||
|
||||
# Создаем индексы
|
||||
await self._execute_query(
|
||||
"CREATE INDEX IF NOT EXISTS idx_blacklist_history_user_id ON blacklist_history(user_id)"
|
||||
@@ -35,9 +35,9 @@ class BlacklistHistoryRepository(DatabaseConnection):
|
||||
await self._execute_query(
|
||||
"CREATE INDEX IF NOT EXISTS idx_blacklist_history_date_unban ON blacklist_history(date_unban)"
|
||||
)
|
||||
|
||||
|
||||
self.logger.info("Таблица истории банов/разбанов создана")
|
||||
|
||||
|
||||
async def add_record_on_ban(self, record: BlacklistHistoryRecord) -> None:
|
||||
"""Добавляет запись о бане в историю."""
|
||||
query = """
|
||||
@@ -48,8 +48,9 @@ class BlacklistHistoryRepository(DatabaseConnection):
|
||||
"""
|
||||
# Используем текущее время, если не указано
|
||||
from datetime import datetime
|
||||
|
||||
current_timestamp = int(datetime.now().timestamp())
|
||||
|
||||
|
||||
params = (
|
||||
record.user_id,
|
||||
record.message_for_user,
|
||||
@@ -59,28 +60,29 @@ class BlacklistHistoryRepository(DatabaseConnection):
|
||||
record.created_at if record.created_at is not None else current_timestamp,
|
||||
record.updated_at if record.updated_at is not None else current_timestamp,
|
||||
)
|
||||
|
||||
|
||||
await self._execute_query(query, params)
|
||||
self.logger.info(
|
||||
f"Запись о бане добавлена в историю: user_id={record.user_id}, "
|
||||
f"date_ban={record.date_ban}"
|
||||
)
|
||||
|
||||
|
||||
async def set_unban_date(self, user_id: int, date_unban: int) -> bool:
|
||||
"""
|
||||
Обновляет date_unban и updated_at в последней записи (date_unban IS NULL) для пользователя.
|
||||
|
||||
|
||||
Args:
|
||||
user_id: ID пользователя
|
||||
date_unban: Timestamp даты разбана
|
||||
|
||||
|
||||
Returns:
|
||||
True если запись обновлена, False если не найдена открытая запись
|
||||
"""
|
||||
try:
|
||||
from datetime import datetime
|
||||
|
||||
current_timestamp = int(datetime.now().timestamp())
|
||||
|
||||
|
||||
# SQLite не поддерживает ORDER BY в UPDATE, поэтому используем подзапрос
|
||||
# Сначала проверяем, есть ли открытая запись
|
||||
check_query = """
|
||||
@@ -90,13 +92,13 @@ class BlacklistHistoryRepository(DatabaseConnection):
|
||||
LIMIT 1
|
||||
"""
|
||||
rows = await self._execute_query_with_result(check_query, (user_id,))
|
||||
|
||||
|
||||
if not rows:
|
||||
self.logger.warning(
|
||||
f"Не найдена открытая запись в истории для обновления: user_id={user_id}"
|
||||
)
|
||||
return False
|
||||
|
||||
|
||||
# Обновляем найденную запись
|
||||
update_query = """
|
||||
UPDATE blacklist_history
|
||||
@@ -104,11 +106,11 @@ class BlacklistHistoryRepository(DatabaseConnection):
|
||||
updated_at = ?
|
||||
WHERE id = ?
|
||||
"""
|
||||
|
||||
|
||||
record_id = rows[0][0]
|
||||
params = (date_unban, current_timestamp, record_id)
|
||||
await self._execute_query(update_query, params)
|
||||
|
||||
|
||||
self.logger.info(
|
||||
f"Дата разбана обновлена в истории: user_id={user_id}, date_unban={date_unban}"
|
||||
)
|
||||
|
||||
@@ -6,10 +6,10 @@ from database.models import BlacklistUser
|
||||
|
||||
class BlacklistRepository(DatabaseConnection):
|
||||
"""Репозиторий для работы с черным списком."""
|
||||
|
||||
|
||||
async def create_tables(self):
|
||||
"""Создание таблицы черного списка."""
|
||||
query = '''
|
||||
query = """
|
||||
CREATE TABLE IF NOT EXISTS blacklist (
|
||||
user_id INTEGER NOT NULL PRIMARY KEY,
|
||||
message_for_user TEXT,
|
||||
@@ -19,10 +19,10 @@ class BlacklistRepository(DatabaseConnection):
|
||||
FOREIGN KEY (user_id) REFERENCES our_users (user_id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (ban_author) REFERENCES our_users (user_id) ON DELETE SET NULL
|
||||
)
|
||||
'''
|
||||
"""
|
||||
await self._execute_query(query)
|
||||
self.logger.info("Таблица черного списка создана")
|
||||
|
||||
|
||||
async def add_user(self, blacklist_user: BlacklistUser) -> None:
|
||||
"""Добавляет пользователя в черный список."""
|
||||
query = """
|
||||
@@ -35,29 +35,35 @@ class BlacklistRepository(DatabaseConnection):
|
||||
blacklist_user.date_to_unban,
|
||||
blacklist_user.ban_author,
|
||||
)
|
||||
|
||||
|
||||
await self._execute_query(query, params)
|
||||
self.logger.info(f"Пользователь добавлен в черный список: user_id={blacklist_user.user_id}")
|
||||
|
||||
self.logger.info(
|
||||
f"Пользователь добавлен в черный список: user_id={blacklist_user.user_id}"
|
||||
)
|
||||
|
||||
async def remove_user(self, user_id: int) -> bool:
|
||||
"""Удаляет пользователя из черного списка."""
|
||||
try:
|
||||
query = "DELETE FROM blacklist WHERE user_id = ?"
|
||||
await self._execute_query(query, (user_id,))
|
||||
self.logger.info(f"Пользователь с идентификатором {user_id} успешно удален из черного списка.")
|
||||
self.logger.info(
|
||||
f"Пользователь с идентификатором {user_id} успешно удален из черного списка."
|
||||
)
|
||||
return True
|
||||
except Exception as e:
|
||||
self.logger.error(f"Ошибка удаления пользователя с идентификатором {user_id} "
|
||||
f"из таблицы blacklist. Ошибка: {str(e)}")
|
||||
self.logger.error(
|
||||
f"Ошибка удаления пользователя с идентификатором {user_id} "
|
||||
f"из таблицы blacklist. Ошибка: {str(e)}"
|
||||
)
|
||||
return False
|
||||
|
||||
|
||||
async def user_exists(self, user_id: int) -> bool:
|
||||
"""Проверяет, существует ли запись с данным user_id в blacklist."""
|
||||
query = "SELECT 1 FROM blacklist WHERE user_id = ?"
|
||||
rows = await self._execute_query_with_result(query, (user_id,))
|
||||
self.logger.info(f"Существует ли пользователь: user_id={user_id} Итог: {rows}")
|
||||
return bool(rows)
|
||||
|
||||
|
||||
async def get_user(self, user_id: int) -> Optional[BlacklistUser]:
|
||||
"""Возвращает информацию о пользователе в черном списке по user_id."""
|
||||
query = """
|
||||
@@ -67,7 +73,7 @@ class BlacklistRepository(DatabaseConnection):
|
||||
"""
|
||||
rows = await self._execute_query_with_result(query, (user_id,))
|
||||
row = rows[0] if rows else None
|
||||
|
||||
|
||||
if row:
|
||||
return BlacklistUser(
|
||||
user_id=row[0],
|
||||
@@ -77,8 +83,10 @@ class BlacklistRepository(DatabaseConnection):
|
||||
ban_author=row[4] if len(row) > 4 else None,
|
||||
)
|
||||
return None
|
||||
|
||||
async def get_all_users(self, offset: int = 0, limit: int = 10) -> List[BlacklistUser]:
|
||||
|
||||
async def get_all_users(
|
||||
self, offset: int = 0, limit: int = 10
|
||||
) -> List[BlacklistUser]:
|
||||
"""Возвращает список пользователей в черном списке."""
|
||||
query = """
|
||||
SELECT user_id, message_for_user, date_to_unban, created_at, ban_author
|
||||
@@ -86,7 +94,7 @@ class BlacklistRepository(DatabaseConnection):
|
||||
LIMIT ?, ?
|
||||
"""
|
||||
rows = await self._execute_query_with_result(query, (offset, limit))
|
||||
|
||||
|
||||
users = []
|
||||
for row in rows:
|
||||
users.append(
|
||||
@@ -98,10 +106,12 @@ class BlacklistRepository(DatabaseConnection):
|
||||
ban_author=row[4] if len(row) > 4 else None,
|
||||
)
|
||||
)
|
||||
|
||||
self.logger.info(f"Получен список пользователей в черном списке (offset={offset}, limit={limit}): {len(users)}")
|
||||
|
||||
self.logger.info(
|
||||
f"Получен список пользователей в черном списке (offset={offset}, limit={limit}): {len(users)}"
|
||||
)
|
||||
return users
|
||||
|
||||
|
||||
async def get_all_users_no_limit(self) -> List[BlacklistUser]:
|
||||
"""Возвращает список всех пользователей в черном списке без лимитов."""
|
||||
query = """
|
||||
@@ -109,7 +119,7 @@ class BlacklistRepository(DatabaseConnection):
|
||||
FROM blacklist
|
||||
"""
|
||||
rows = await self._execute_query_with_result(query)
|
||||
|
||||
|
||||
users = []
|
||||
for row in rows:
|
||||
users.append(
|
||||
@@ -121,19 +131,23 @@ class BlacklistRepository(DatabaseConnection):
|
||||
ban_author=row[4] if len(row) > 4 else None,
|
||||
)
|
||||
)
|
||||
|
||||
self.logger.info(f"Получен список всех пользователей в черном списке: {len(users)}")
|
||||
|
||||
self.logger.info(
|
||||
f"Получен список всех пользователей в черном списке: {len(users)}"
|
||||
)
|
||||
return users
|
||||
|
||||
async def get_users_for_unblock_today(self, current_timestamp: int) -> Dict[int, int]:
|
||||
|
||||
async def get_users_for_unblock_today(
|
||||
self, current_timestamp: int
|
||||
) -> Dict[int, int]:
|
||||
"""Возвращает список пользователей, у которых истек срок блокировки."""
|
||||
query = "SELECT user_id FROM blacklist WHERE date_to_unban IS NOT NULL AND date_to_unban <= ?"
|
||||
rows = await self._execute_query_with_result(query, (current_timestamp,))
|
||||
|
||||
|
||||
users = {user_id: user_id for user_id, in rows}
|
||||
self.logger.info(f"Получен список пользователей для разблокировки: {users}")
|
||||
return users
|
||||
|
||||
|
||||
async def get_count(self) -> int:
|
||||
"""Получение количества пользователей в черном списке."""
|
||||
query = "SELECT COUNT(*) FROM blacklist"
|
||||
|
||||
@@ -7,10 +7,10 @@ from database.models import UserMessage
|
||||
|
||||
class MessageRepository(DatabaseConnection):
|
||||
"""Репозиторий для работы с сообщениями пользователей."""
|
||||
|
||||
|
||||
async def create_tables(self):
|
||||
"""Создание таблицы сообщений пользователей."""
|
||||
query = '''
|
||||
query = """
|
||||
CREATE TABLE IF NOT EXISTS user_messages (
|
||||
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
message_text TEXT,
|
||||
@@ -19,24 +19,31 @@ class MessageRepository(DatabaseConnection):
|
||||
date INTEGER NOT NULL,
|
||||
FOREIGN KEY (user_id) REFERENCES our_users (user_id) ON DELETE CASCADE
|
||||
)
|
||||
'''
|
||||
"""
|
||||
await self._execute_query(query)
|
||||
self.logger.info("Таблица сообщений пользователей создана")
|
||||
|
||||
|
||||
async def add_message(self, message: UserMessage) -> None:
|
||||
"""Добавление сообщения пользователя."""
|
||||
if message.date is None:
|
||||
message.date = int(datetime.now().timestamp())
|
||||
|
||||
|
||||
query = """
|
||||
INSERT INTO user_messages (message_text, user_id, telegram_message_id, date)
|
||||
VALUES (?, ?, ?, ?)
|
||||
"""
|
||||
params = (message.message_text, message.user_id, message.telegram_message_id, message.date)
|
||||
|
||||
params = (
|
||||
message.message_text,
|
||||
message.user_id,
|
||||
message.telegram_message_id,
|
||||
message.date,
|
||||
)
|
||||
|
||||
await self._execute_query(query, params)
|
||||
self.logger.info(f"Новое сообщение добавлено: telegram_message_id={message.telegram_message_id}")
|
||||
|
||||
self.logger.info(
|
||||
f"Новое сообщение добавлено: telegram_message_id={message.telegram_message_id}"
|
||||
)
|
||||
|
||||
async def get_user_by_message_id(self, message_id: int) -> Optional[int]:
|
||||
"""Получение пользователя по message_id."""
|
||||
query = "SELECT user_id FROM user_messages WHERE telegram_message_id = ?"
|
||||
|
||||
@@ -7,11 +7,11 @@ from database.models import MessageContentLink, PostContent, TelegramPost
|
||||
|
||||
class PostRepository(DatabaseConnection):
|
||||
"""Репозиторий для работы с постами из Telegram."""
|
||||
|
||||
|
||||
async def create_tables(self):
|
||||
"""Создание таблиц для постов."""
|
||||
# Таблица постов из Telegram
|
||||
post_query = '''
|
||||
post_query = """
|
||||
CREATE TABLE IF NOT EXISTS post_from_telegram_suggest (
|
||||
message_id INTEGER NOT NULL PRIMARY KEY,
|
||||
text TEXT,
|
||||
@@ -23,9 +23,9 @@ class PostRepository(DatabaseConnection):
|
||||
published_message_id INTEGER,
|
||||
FOREIGN KEY (author_id) REFERENCES our_users (user_id) ON DELETE CASCADE
|
||||
)
|
||||
'''
|
||||
"""
|
||||
await self._execute_query(post_query)
|
||||
|
||||
|
||||
# Добавляем поле published_message_id если его нет (для существующих БД)
|
||||
try:
|
||||
check_column_query = """
|
||||
@@ -34,19 +34,27 @@ class PostRepository(DatabaseConnection):
|
||||
"""
|
||||
existing_columns = await self._execute_query_with_result(check_column_query)
|
||||
if not existing_columns:
|
||||
await self._execute_query('ALTER TABLE post_from_telegram_suggest ADD COLUMN published_message_id INTEGER')
|
||||
self.logger.info("Столбец published_message_id добавлен в post_from_telegram_suggest")
|
||||
await self._execute_query(
|
||||
"ALTER TABLE post_from_telegram_suggest ADD COLUMN published_message_id INTEGER"
|
||||
)
|
||||
self.logger.info(
|
||||
"Столбец published_message_id добавлен в post_from_telegram_suggest"
|
||||
)
|
||||
except Exception as e:
|
||||
# Если проверка не удалась, пытаемся добавить столбец (может быть уже существует)
|
||||
try:
|
||||
await self._execute_query('ALTER TABLE post_from_telegram_suggest ADD COLUMN published_message_id INTEGER')
|
||||
self.logger.info("Столбец published_message_id добавлен в post_from_telegram_suggest (fallback)")
|
||||
await self._execute_query(
|
||||
"ALTER TABLE post_from_telegram_suggest ADD COLUMN published_message_id INTEGER"
|
||||
)
|
||||
self.logger.info(
|
||||
"Столбец published_message_id добавлен в post_from_telegram_suggest (fallback)"
|
||||
)
|
||||
except Exception:
|
||||
# Столбец уже существует, игнорируем ошибку
|
||||
pass
|
||||
|
||||
|
||||
# Таблица контента постов
|
||||
content_query = '''
|
||||
content_query = """
|
||||
CREATE TABLE IF NOT EXISTS content_post_from_telegram (
|
||||
message_id INTEGER NOT NULL,
|
||||
content_name TEXT NOT NULL,
|
||||
@@ -54,22 +62,22 @@ class PostRepository(DatabaseConnection):
|
||||
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 = '''
|
||||
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)
|
||||
|
||||
|
||||
# Таблица контента опубликованных постов
|
||||
published_content_query = '''
|
||||
published_content_query = """
|
||||
CREATE TABLE IF NOT EXISTS published_post_content (
|
||||
published_message_id INTEGER NOT NULL,
|
||||
content_name TEXT NOT NULL,
|
||||
@@ -77,38 +85,55 @@ class PostRepository(DatabaseConnection):
|
||||
published_at INTEGER NOT NULL,
|
||||
PRIMARY KEY (published_message_id, content_name)
|
||||
)
|
||||
'''
|
||||
"""
|
||||
await self._execute_query(published_content_query)
|
||||
|
||||
|
||||
# Создаем индексы
|
||||
try:
|
||||
await self._execute_query('CREATE INDEX IF NOT EXISTS idx_published_post_content_message_id ON published_post_content(published_message_id)')
|
||||
await self._execute_query('CREATE INDEX IF NOT EXISTS idx_post_from_telegram_suggest_published ON post_from_telegram_suggest(published_message_id)')
|
||||
await self._execute_query(
|
||||
"CREATE INDEX IF NOT EXISTS idx_published_post_content_message_id ON published_post_content(published_message_id)"
|
||||
)
|
||||
await self._execute_query(
|
||||
"CREATE INDEX IF NOT EXISTS idx_post_from_telegram_suggest_published ON post_from_telegram_suggest(published_message_id)"
|
||||
)
|
||||
except Exception:
|
||||
# Индексы уже существуют, игнорируем ошибку
|
||||
pass
|
||||
|
||||
|
||||
self.logger.info("Таблицы для постов созданы")
|
||||
|
||||
|
||||
async def add_post(self, post: TelegramPost) -> None:
|
||||
"""Добавление поста."""
|
||||
if not post.created_at:
|
||||
post.created_at = int(datetime.now().timestamp())
|
||||
status = post.status if post.status else "suggest"
|
||||
# Преобразуем bool в int для SQLite (True -> 1, False -> 0, None -> None)
|
||||
is_anonymous_int = None if post.is_anonymous is None else (1 if post.is_anonymous else 0)
|
||||
is_anonymous_int = (
|
||||
None if post.is_anonymous is None else (1 if post.is_anonymous else 0)
|
||||
)
|
||||
|
||||
# Используем INSERT OR IGNORE чтобы избежать ошибок при повторном создании
|
||||
query = """
|
||||
INSERT OR IGNORE INTO post_from_telegram_suggest (message_id, text, author_id, created_at, status, is_anonymous)
|
||||
VALUES (?, ?, ?, ?, ?, ?)
|
||||
"""
|
||||
params = (post.message_id, post.text, post.author_id, post.created_at, status, is_anonymous_int)
|
||||
params = (
|
||||
post.message_id,
|
||||
post.text,
|
||||
post.author_id,
|
||||
post.created_at,
|
||||
status,
|
||||
is_anonymous_int,
|
||||
)
|
||||
|
||||
await self._execute_query(query, params)
|
||||
self.logger.info(f"Пост добавлен (или уже существует): message_id={post.message_id}, text длина={len(post.text) if post.text else 0}, is_anonymous={is_anonymous_int}")
|
||||
|
||||
async def update_helper_message(self, message_id: int, helper_message_id: int) -> None:
|
||||
self.logger.info(
|
||||
f"Пост добавлен (или уже существует): message_id={post.message_id}, text длина={len(post.text) if post.text else 0}, is_anonymous={is_anonymous_int}"
|
||||
)
|
||||
|
||||
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))
|
||||
@@ -131,12 +156,16 @@ class PostRepository(DatabaseConnection):
|
||||
f"update_status_by_message_id: 0 строк обновлено для message_id={message_id}, status={status}"
|
||||
)
|
||||
else:
|
||||
self.logger.info(f"Статус поста message_id={message_id} обновлён на {status}")
|
||||
self.logger.info(
|
||||
f"Статус поста message_id={message_id} обновлён на {status}"
|
||||
)
|
||||
return n
|
||||
except Exception as e:
|
||||
if conn:
|
||||
await conn.rollback()
|
||||
self.logger.error(f"Ошибка при обновлении статуса message_id={message_id}: {e}")
|
||||
self.logger.error(
|
||||
f"Ошибка при обновлении статуса message_id={message_id}: {e}"
|
||||
)
|
||||
raise
|
||||
finally:
|
||||
if conn:
|
||||
@@ -182,39 +211,53 @@ class PostRepository(DatabaseConnection):
|
||||
if conn:
|
||||
await conn.close()
|
||||
|
||||
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:
|
||||
# Сначала добавляем связь
|
||||
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}")
|
||||
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 add_message_link(self, post_id: int, message_id: int) -> bool:
|
||||
"""Добавляет связь между post_id и message_id в таблицу message_link_to_content."""
|
||||
try:
|
||||
self.logger.info(f"Добавление связи: post_id={post_id}, message_id={message_id}")
|
||||
self.logger.info(
|
||||
f"Добавление связи: post_id={post_id}, message_id={message_id}"
|
||||
)
|
||||
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))
|
||||
self.logger.info(f"Связь успешно добавлена: post_id={post_id}, message_id={message_id}")
|
||||
self.logger.info(
|
||||
f"Связь успешно добавлена: post_id={post_id}, message_id={message_id}"
|
||||
)
|
||||
return True
|
||||
except Exception as e:
|
||||
self.logger.error(f"Ошибка при добавлении связи post_id={post_id}, message_id={message_id}: {e}")
|
||||
self.logger.error(
|
||||
f"Ошибка при добавлении связи post_id={post_id}, message_id={message_id}: {e}"
|
||||
)
|
||||
return False
|
||||
|
||||
async def get_post_content_by_helper_id(self, helper_message_id: int) -> List[Tuple[str, str]]:
|
||||
|
||||
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
|
||||
@@ -223,12 +266,16 @@ class PostRepository(DatabaseConnection):
|
||||
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,))
|
||||
|
||||
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_content_by_message_id(self, message_id: int) -> List[Tuple[str, str]]:
|
||||
|
||||
async def get_post_content_by_message_id(
|
||||
self, message_id: int
|
||||
) -> List[Tuple[str, str]]:
|
||||
"""Получает контент одиночного поста по message_id."""
|
||||
query = """
|
||||
SELECT cpft.content_name, cpft.content_type
|
||||
@@ -238,21 +285,25 @@ class PostRepository(DatabaseConnection):
|
||||
WHERE pft.message_id = ? AND pft.helper_text_message_id IS NULL
|
||||
"""
|
||||
post_content = await self._execute_query_with_result(query, (message_id,))
|
||||
|
||||
self.logger.info(f"Получен контент одиночного поста: {len(post_content)} элементов для message_id={message_id}")
|
||||
|
||||
self.logger.info(
|
||||
f"Получен контент одиночного поста: {len(post_content)} элементов для message_id={message_id}"
|
||||
)
|
||||
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}")
|
||||
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 = """
|
||||
@@ -262,98 +313,129 @@ class PostRepository(DatabaseConnection):
|
||||
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}")
|
||||
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]:
|
||||
|
||||
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}")
|
||||
self.logger.info(
|
||||
f"Получен author_id: {author_id} для helper_message_id={helper_message_id}"
|
||||
)
|
||||
return author_id
|
||||
return None
|
||||
|
||||
async def get_post_text_and_anonymity_by_message_id(self, message_id: int) -> Tuple[Optional[str], Optional[bool]]:
|
||||
|
||||
async def get_post_text_and_anonymity_by_message_id(
|
||||
self, message_id: int
|
||||
) -> Tuple[Optional[str], Optional[bool]]:
|
||||
"""Получает текст и is_anonymous поста по message_id."""
|
||||
query = "SELECT text, is_anonymous 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:
|
||||
text = row[0] or ""
|
||||
is_anonymous_int = row[1]
|
||||
# Преобразуем int в bool (1 -> True, 0 -> False, NULL -> None)
|
||||
is_anonymous = None if is_anonymous_int is None else bool(is_anonymous_int)
|
||||
self.logger.info(f"Получены текст и is_anonymous для message_id={message_id}")
|
||||
self.logger.info(
|
||||
f"Получены текст и is_anonymous для message_id={message_id}"
|
||||
)
|
||||
return text, is_anonymous
|
||||
return None, None
|
||||
|
||||
async def get_post_text_and_anonymity_by_helper_id(self, helper_message_id: int) -> Tuple[Optional[str], Optional[bool]]:
|
||||
|
||||
async def get_post_text_and_anonymity_by_helper_id(
|
||||
self, helper_message_id: int
|
||||
) -> Tuple[Optional[str], Optional[bool]]:
|
||||
"""Получает текст и is_anonymous поста по helper_text_message_id."""
|
||||
query = "SELECT text, is_anonymous 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:
|
||||
text = row[0] or ""
|
||||
is_anonymous_int = row[1]
|
||||
# Преобразуем int в bool (1 -> True, 0 -> False, NULL -> None)
|
||||
is_anonymous = None if is_anonymous_int is None else bool(is_anonymous_int)
|
||||
self.logger.info(f"Получены текст и is_anonymous для helper_message_id={helper_message_id}")
|
||||
self.logger.info(
|
||||
f"Получены текст и is_anonymous для helper_message_id={helper_message_id}"
|
||||
)
|
||||
return text, is_anonymous
|
||||
return None, None
|
||||
|
||||
async def update_published_message_id(self, original_message_id: int, published_message_id: int) -> None:
|
||||
|
||||
async def update_published_message_id(
|
||||
self, original_message_id: int, published_message_id: int
|
||||
) -> None:
|
||||
"""Обновляет published_message_id для опубликованного поста."""
|
||||
query = "UPDATE post_from_telegram_suggest SET published_message_id = ? WHERE message_id = ?"
|
||||
await self._execute_query(query, (published_message_id, original_message_id))
|
||||
self.logger.info(f"Обновлен published_message_id: {original_message_id} -> {published_message_id}")
|
||||
|
||||
self.logger.info(
|
||||
f"Обновлен published_message_id: {original_message_id} -> {published_message_id}"
|
||||
)
|
||||
|
||||
async def add_published_post_content(
|
||||
self, published_message_id: int, content_path: str, content_type: str
|
||||
) -> bool:
|
||||
"""Добавляет контент опубликованного поста."""
|
||||
try:
|
||||
from datetime import datetime
|
||||
|
||||
published_at = int(datetime.now().timestamp())
|
||||
|
||||
|
||||
query = """
|
||||
INSERT OR IGNORE INTO published_post_content
|
||||
(published_message_id, content_name, content_type, published_at)
|
||||
VALUES (?, ?, ?, ?)
|
||||
"""
|
||||
await self._execute_query(query, (published_message_id, content_path, content_type, published_at))
|
||||
self.logger.info(f"Добавлен контент опубликованного поста: published_message_id={published_message_id}, type={content_type}")
|
||||
await self._execute_query(
|
||||
query, (published_message_id, content_path, content_type, published_at)
|
||||
)
|
||||
self.logger.info(
|
||||
f"Добавлен контент опубликованного поста: published_message_id={published_message_id}, type={content_type}"
|
||||
)
|
||||
return True
|
||||
except Exception as e:
|
||||
self.logger.error(f"Ошибка при добавлении контента опубликованного поста: {e}")
|
||||
self.logger.error(
|
||||
f"Ошибка при добавлении контента опубликованного поста: {e}"
|
||||
)
|
||||
return False
|
||||
|
||||
async def get_published_post_content(self, published_message_id: int) -> List[Tuple[str, str]]:
|
||||
|
||||
async def get_published_post_content(
|
||||
self, published_message_id: int
|
||||
) -> List[Tuple[str, str]]:
|
||||
"""Получает контент опубликованного поста."""
|
||||
query = """
|
||||
SELECT content_name, content_type
|
||||
FROM published_post_content
|
||||
WHERE published_message_id = ?
|
||||
"""
|
||||
post_content = await self._execute_query_with_result(query, (published_message_id,))
|
||||
self.logger.info(f"Получен контент опубликованного поста: {len(post_content)} элементов для published_message_id={published_message_id}")
|
||||
post_content = await self._execute_query_with_result(
|
||||
query, (published_message_id,)
|
||||
)
|
||||
self.logger.info(
|
||||
f"Получен контент опубликованного поста: {len(post_content)} элементов для published_message_id={published_message_id}"
|
||||
)
|
||||
return post_content
|
||||
|
||||
@@ -7,10 +7,10 @@ from database.models import User
|
||||
|
||||
class UserRepository(DatabaseConnection):
|
||||
"""Репозиторий для работы с пользователями."""
|
||||
|
||||
|
||||
async def create_tables(self):
|
||||
"""Создание таблицы пользователей."""
|
||||
query = '''
|
||||
query = """
|
||||
CREATE TABLE IF NOT EXISTS our_users (
|
||||
user_id INTEGER NOT NULL PRIMARY KEY,
|
||||
first_name TEXT,
|
||||
@@ -24,42 +24,56 @@ class UserRepository(DatabaseConnection):
|
||||
date_changed INTEGER NOT NULL,
|
||||
voice_bot_welcome_received BOOLEAN DEFAULT 0
|
||||
)
|
||||
'''
|
||||
"""
|
||||
await self._execute_query(query)
|
||||
self.logger.info("Таблица пользователей создана")
|
||||
|
||||
|
||||
async def user_exists(self, user_id: int) -> bool:
|
||||
"""Проверяет, существует ли пользователь в базе данных."""
|
||||
query = "SELECT user_id FROM our_users WHERE user_id = ?"
|
||||
rows = await self._execute_query_with_result(query, (user_id,))
|
||||
self.logger.info(f"Проверка существования пользователя: user_id={user_id}, результат={rows}")
|
||||
self.logger.info(
|
||||
f"Проверка существования пользователя: user_id={user_id}, результат={rows}"
|
||||
)
|
||||
return bool(len(rows))
|
||||
|
||||
|
||||
async def add_user(self, user: User) -> None:
|
||||
"""Добавление нового пользователя с защитой от дублирования."""
|
||||
if not user.date_added:
|
||||
user.date_added = int(datetime.now().timestamp())
|
||||
if not user.date_changed:
|
||||
user.date_changed = int(datetime.now().timestamp())
|
||||
|
||||
|
||||
query = """
|
||||
INSERT OR IGNORE INTO our_users (user_id, first_name, full_name, username, is_bot,
|
||||
language_code, emoji, has_stickers, date_added, date_changed, voice_bot_welcome_received)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
"""
|
||||
params = (user.user_id, user.first_name, user.full_name, user.username,
|
||||
user.is_bot, user.language_code, user.emoji, user.has_stickers,
|
||||
user.date_added, user.date_changed, user.voice_bot_welcome_received)
|
||||
|
||||
params = (
|
||||
user.user_id,
|
||||
user.first_name,
|
||||
user.full_name,
|
||||
user.username,
|
||||
user.is_bot,
|
||||
user.language_code,
|
||||
user.emoji,
|
||||
user.has_stickers,
|
||||
user.date_added,
|
||||
user.date_changed,
|
||||
user.voice_bot_welcome_received,
|
||||
)
|
||||
|
||||
await self._execute_query(query, params)
|
||||
self.logger.info(f"Пользователь обработан (создан или уже существует): {user.user_id}")
|
||||
|
||||
self.logger.info(
|
||||
f"Пользователь обработан (создан или уже существует): {user.user_id}"
|
||||
)
|
||||
|
||||
async def get_user_info(self, user_id: int) -> Optional[User]:
|
||||
"""Получение информации о пользователе."""
|
||||
query = "SELECT username, full_name, has_stickers, emoji FROM our_users WHERE user_id = ?"
|
||||
rows = await self._execute_query_with_result(query, (user_id,))
|
||||
row = rows[0] if rows else None
|
||||
|
||||
|
||||
if row:
|
||||
return User(
|
||||
user_id=user_id,
|
||||
@@ -67,16 +81,16 @@ class UserRepository(DatabaseConnection):
|
||||
full_name=row[1],
|
||||
username=row[0],
|
||||
has_stickers=bool(row[2]) if row[2] is not None else False,
|
||||
emoji=row[3]
|
||||
emoji=row[3],
|
||||
)
|
||||
return None
|
||||
|
||||
|
||||
async def get_user_by_id(self, user_id: int) -> Optional[User]:
|
||||
"""Получение пользователя по ID."""
|
||||
query = "SELECT * FROM our_users WHERE user_id = ?"
|
||||
rows = await self._execute_query_with_result(query, (user_id,))
|
||||
row = rows[0] if rows else None
|
||||
|
||||
|
||||
if row:
|
||||
return User(
|
||||
user_id=row[0],
|
||||
@@ -89,58 +103,66 @@ class UserRepository(DatabaseConnection):
|
||||
emoji=row[7],
|
||||
date_added=row[8],
|
||||
date_changed=row[9],
|
||||
voice_bot_welcome_received=bool(row[10]) if len(row) > 10 else False
|
||||
voice_bot_welcome_received=bool(row[10]) if len(row) > 10 else False,
|
||||
)
|
||||
return None
|
||||
|
||||
|
||||
async def get_username(self, user_id: int) -> Optional[str]:
|
||||
"""Возвращает username пользователя."""
|
||||
query = "SELECT username FROM our_users WHERE user_id = ?"
|
||||
rows = await self._execute_query_with_result(query, (user_id,))
|
||||
row = rows[0] if rows else None
|
||||
|
||||
|
||||
if row:
|
||||
username = row[0]
|
||||
self.logger.info(f"Username пользователя найден: user_id={user_id}, username={username}")
|
||||
self.logger.info(
|
||||
f"Username пользователя найден: user_id={user_id}, username={username}"
|
||||
)
|
||||
return username
|
||||
return None
|
||||
|
||||
|
||||
async def get_user_id_by_username(self, username: str) -> Optional[int]:
|
||||
"""Возвращает user_id пользователя по username."""
|
||||
query = "SELECT user_id FROM our_users WHERE username = ?"
|
||||
rows = await self._execute_query_with_result(query, (username,))
|
||||
row = rows[0] if rows else None
|
||||
|
||||
|
||||
if row:
|
||||
user_id = row[0]
|
||||
self.logger.info(f"User_id пользователя найден: username={username}, user_id={user_id}")
|
||||
self.logger.info(
|
||||
f"User_id пользователя найден: username={username}, user_id={user_id}"
|
||||
)
|
||||
return user_id
|
||||
return None
|
||||
|
||||
|
||||
async def get_full_name_by_id(self, user_id: int) -> Optional[str]:
|
||||
"""Возвращает full_name пользователя."""
|
||||
query = "SELECT full_name FROM our_users WHERE user_id = ?"
|
||||
rows = await self._execute_query_with_result(query, (user_id,))
|
||||
row = rows[0] if rows else None
|
||||
|
||||
|
||||
if row:
|
||||
full_name = row[0]
|
||||
self.logger.info(f"Full_name пользователя найден: user_id={user_id}, full_name={full_name}")
|
||||
self.logger.info(
|
||||
f"Full_name пользователя найден: user_id={user_id}, full_name={full_name}"
|
||||
)
|
||||
return full_name
|
||||
return None
|
||||
|
||||
|
||||
async def get_user_first_name(self, user_id: int) -> Optional[str]:
|
||||
"""Возвращает first_name пользователя."""
|
||||
query = "SELECT first_name FROM our_users WHERE user_id = ?"
|
||||
rows = await self._execute_query_with_result(query, (user_id,))
|
||||
row = rows[0] if rows else None
|
||||
|
||||
|
||||
if row:
|
||||
first_name = row[0]
|
||||
self.logger.info(f"First_name пользователя найден: user_id={user_id}, first_name={first_name}")
|
||||
self.logger.info(
|
||||
f"First_name пользователя найден: user_id={user_id}, first_name={first_name}"
|
||||
)
|
||||
return first_name
|
||||
return None
|
||||
|
||||
|
||||
async def get_all_user_ids(self) -> List[int]:
|
||||
"""Возвращает список всех user_id."""
|
||||
query = "SELECT user_id FROM our_users"
|
||||
@@ -148,20 +170,22 @@ class UserRepository(DatabaseConnection):
|
||||
user_ids = [row[0] for row in rows]
|
||||
self.logger.info(f"Получен список всех user_id: {user_ids}")
|
||||
return user_ids
|
||||
|
||||
|
||||
async def get_last_users(self, limit: int = 30) -> List[tuple]:
|
||||
"""Получение последних пользователей."""
|
||||
query = "SELECT full_name, user_id FROM our_users ORDER BY date_changed DESC LIMIT ?"
|
||||
rows = await self._execute_query_with_result(query, (limit,))
|
||||
return rows
|
||||
|
||||
|
||||
async def update_user_date(self, user_id: int) -> None:
|
||||
"""Обновление даты последнего изменения пользователя."""
|
||||
date_changed = int(datetime.now().timestamp())
|
||||
query = "UPDATE our_users SET date_changed = ? WHERE user_id = ?"
|
||||
await self._execute_query(query, (date_changed, user_id))
|
||||
|
||||
async def update_user_info(self, user_id: int, username: str = None, full_name: str = None) -> None:
|
||||
|
||||
async def update_user_info(
|
||||
self, user_id: int, username: str = None, full_name: str = None
|
||||
) -> None:
|
||||
"""Обновление информации о пользователе."""
|
||||
if username and full_name:
|
||||
query = "UPDATE our_users SET username = ?, full_name = ? WHERE user_id = ?"
|
||||
@@ -174,85 +198,93 @@ class UserRepository(DatabaseConnection):
|
||||
params = (full_name, user_id)
|
||||
else:
|
||||
return
|
||||
|
||||
|
||||
await self._execute_query(query, params)
|
||||
|
||||
|
||||
async def update_user_emoji(self, user_id: int, emoji: str) -> None:
|
||||
"""Обновление эмодзи пользователя."""
|
||||
query = "UPDATE our_users SET emoji = ? WHERE user_id = ?"
|
||||
await self._execute_query(query, (emoji, user_id))
|
||||
|
||||
|
||||
async def update_stickers_info(self, user_id: int) -> None:
|
||||
"""Обновление информации о стикерах."""
|
||||
query = "UPDATE our_users SET has_stickers = 1 WHERE user_id = ?"
|
||||
await self._execute_query(query, (user_id,))
|
||||
|
||||
|
||||
async def get_stickers_info(self, user_id: int) -> bool:
|
||||
"""Получение информации о стикерах."""
|
||||
query = "SELECT has_stickers FROM our_users WHERE user_id = ?"
|
||||
rows = await self._execute_query_with_result(query, (user_id,))
|
||||
row = rows[0] if rows else None
|
||||
return bool(row[0]) if row and row[0] is not None else False
|
||||
|
||||
|
||||
async def check_emoji_exists(self, emoji: str) -> bool:
|
||||
"""Проверка существования эмодзи."""
|
||||
query = "SELECT 1 FROM our_users WHERE emoji = ?"
|
||||
rows = await self._execute_query_with_result(query, (emoji,))
|
||||
row = rows[0] if rows else None
|
||||
return bool(row)
|
||||
|
||||
|
||||
async def get_user_emoji(self, user_id: int) -> str:
|
||||
"""
|
||||
Получает эмодзи пользователя.
|
||||
|
||||
|
||||
Args:
|
||||
user_id: ID пользователя.
|
||||
|
||||
|
||||
Returns:
|
||||
str: Эмодзи пользователя или "Смайл еще не определен" если не установлен.
|
||||
"""
|
||||
query = "SELECT emoji FROM our_users WHERE user_id = ?"
|
||||
rows = await self._execute_query_with_result(query, (user_id,))
|
||||
row = rows[0] if rows else None
|
||||
|
||||
|
||||
if row and row[0]:
|
||||
emoji = row[0]
|
||||
self.logger.info(f"Эмодзи пользователя найден: user_id={user_id}, emoji={emoji}")
|
||||
self.logger.info(
|
||||
f"Эмодзи пользователя найден: user_id={user_id}, emoji={emoji}"
|
||||
)
|
||||
return str(emoji)
|
||||
else:
|
||||
self.logger.info(f"Эмодзи пользователя не найден: user_id={user_id}")
|
||||
return "Смайл еще не определен"
|
||||
|
||||
|
||||
async def check_emoji_for_user(self, user_id: int) -> str:
|
||||
"""
|
||||
Проверяет, есть ли уже у пользователя назначенный emoji.
|
||||
|
||||
|
||||
Args:
|
||||
user_id: ID пользователя.
|
||||
|
||||
|
||||
Returns:
|
||||
str: Эмодзи пользователя или "Смайл еще не определен" если не установлен.
|
||||
"""
|
||||
return await self.get_user_emoji(user_id)
|
||||
|
||||
|
||||
async def check_voice_bot_welcome_received(self, user_id: int) -> bool:
|
||||
"""Проверяет, получал ли пользователь приветственное сообщение от voice_bot."""
|
||||
query = "SELECT voice_bot_welcome_received FROM our_users WHERE user_id = ?"
|
||||
rows = await self._execute_query_with_result(query, (user_id,))
|
||||
row = rows[0] if rows else None
|
||||
|
||||
|
||||
if row:
|
||||
welcome_received = bool(row[0])
|
||||
self.logger.info(f"Пользователь {user_id} получал приветствие: {welcome_received}")
|
||||
self.logger.info(
|
||||
f"Пользователь {user_id} получал приветствие: {welcome_received}"
|
||||
)
|
||||
return welcome_received
|
||||
return False
|
||||
|
||||
|
||||
async def mark_voice_bot_welcome_received(self, user_id: int) -> bool:
|
||||
"""Отмечает, что пользователь получил приветственное сообщение от voice_bot."""
|
||||
try:
|
||||
query = "UPDATE our_users SET voice_bot_welcome_received = 1 WHERE user_id = ?"
|
||||
query = (
|
||||
"UPDATE our_users SET voice_bot_welcome_received = 1 WHERE user_id = ?"
|
||||
)
|
||||
await self._execute_query(query, (user_id,))
|
||||
self.logger.info(f"Пользователь {user_id} отмечен как получивший приветствие")
|
||||
self.logger.info(
|
||||
f"Пользователь {user_id} отмечен как получивший приветствие"
|
||||
)
|
||||
return True
|
||||
except Exception as e:
|
||||
self.logger.error(f"Ошибка при отметке получения приветствия: {e}")
|
||||
|
||||
Reference in New Issue
Block a user