from datetime import datetime from typing import Optional, List, Dict, Any from database.base import DatabaseConnection from database.models import User class UserRepository(DatabaseConnection): """Репозиторий для работы с пользователями.""" async def create_tables(self): """Создание таблицы пользователей.""" query = ''' CREATE TABLE IF NOT EXISTS our_users ( user_id INTEGER NOT NULL PRIMARY KEY, first_name TEXT, full_name TEXT, username TEXT, is_bot BOOLEAN DEFAULT 0, language_code TEXT, has_stickers BOOLEAN DEFAULT 0 NOT NULL, emoji TEXT, date_added INTEGER NOT NULL, 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}") 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) await self._execute_query(query, params) 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, first_name="", # Не получаем из этого запроса full_name=row[1], username=row[0], has_stickers=bool(row[2]) if row[2] is not None else False, 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], first_name=row[1], full_name=row[2], username=row[3], is_bot=bool(row[4]), language_code=row[5], has_stickers=bool(row[6]), emoji=row[7], date_added=row[8], date_changed=row[9], 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}") 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}") 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}") 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}") return first_name return None async def get_all_user_ids(self) -> List[int]: """Возвращает список всех user_id.""" query = "SELECT user_id FROM our_users" rows = await self._execute_query_with_result(query) 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: """Обновление информации о пользователе.""" if username and full_name: query = "UPDATE our_users SET username = ?, full_name = ? WHERE user_id = ?" params = (username, full_name, user_id) elif username: query = "UPDATE our_users SET username = ? WHERE user_id = ?" params = (username, user_id) elif full_name: query = "UPDATE our_users SET full_name = ? WHERE user_id = ?" 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}") 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}") 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 = ?" await self._execute_query(query, (user_id,)) self.logger.info(f"Пользователь {user_id} отмечен как получивший приветствие") return True except Exception as e: self.logger.error(f"Ошибка при отметке получения приветствия: {e}") return False