add migrations

This commit is contained in:
KatykhinAA
2024-07-06 13:05:50 +03:00
parent c3a6bcbb8a
commit 2c71b8ba46
6 changed files with 152 additions and 44 deletions

View File

@@ -1,17 +1,11 @@
import logging
import os
import datetime
from logging.handlers import RotatingFileHandler
import os
from loguru import logger
class Logger:
def __init__(self, name):
# Инициализация логгера
self.logger = logging.getLogger(name) # Сохраняем logger как свойство класса
self.logger.setLevel(logging.INFO)
# Формат записи логов
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(filename)s - %(lineno)d - %(message)s')
self.logger = logger.bind(name=name)
# Получение сегодняшней даты для имени файла
today = datetime.date.today().strftime('%Y-%m-%d')
@@ -22,25 +16,16 @@ class Logger:
if not os.path.exists(logs_dir):
# Если не существует, создаем ее
os.makedirs(logs_dir)
filename = f'logs/helper_bot_{today}.log'
filename = f'{logs_dir}/helper_bot_{today}.log'
# Создание обработчика для файла логов
file_handler = RotatingFileHandler(
# Настройка формата логов
self.logger.add(
filename,
mode='a',
maxBytes=10 * 1024 * 1024, # Максимальный размер файла (10 МБ)
backupCount=3 # Количество резервных файлов
rotation="00:00",
retention="5 days",
compression="zip",
format="{time:YYYY-MM-DD at HH:mm:ss} | {level} | {name} | {line} | {message}",
)
file_handler.setFormatter(formatter)
# Добавление обработчика к логгеру
self.logger.addHandler(file_handler)
# Добавление стандартного обработчика
# чтобы сообщения также отображались на консоли
console_handler = logging.StreamHandler()
console_handler.setFormatter(formatter)
self.logger.addHandler(console_handler)
def info(self, message):
self.logger.info(message)

66
db.py
View File

@@ -1,23 +1,64 @@
import sqlite3
import configparser
import os
import sys
import custom_logger
from datetime import datetime
from loguru import logger
from custom_logger import Logger
config_path = os.path.join(sys.path[0], 'settings.ini')
db_logger = Logger(name='db')
script_dir = os.path.dirname(os.path.abspath(__file__))
config_path = os.path.join(script_dir, 'settings.ini')
config = configparser.ConfigParser()
config.read(config_path)
LOGS = config.getboolean('Settings', 'logs')
IMPORTANT_LOGS = config.get('Telegram', 'important_logs')
db_logger = custom_logger.Logger('database')
class BotDB:
def __init__(self, db_file):
def __init__(self):
db_file_path = os.path.dirname(os.path.abspath(__file__))
db_file = os.path.join(db_file_path, 'tg-bot-database')
self.conn = sqlite3.connect(db_file, check_same_thread=False)
self.cursor = self.conn.cursor()
logger.info(f'Подключен к базе данных: {db_file_path}')
def create_table(self, sql_script):
"""Создает таблицу в базе."""
try:
cursor = self.conn.cursor()
cursor.execute(sql_script)
except Exception as e:
print(f"Ошибка при создании таблицы: {e}")
def get_current_version(self):
"""Получает текущую версию миграций из таблицы migrations."""
try:
cursor = self.conn.cursor()
cursor.execute("SELECT version FROM migrations ORDER BY version DESC LIMIT 1")
version = cursor.fetchone()[0]
return version
except Exception as e:
print(f"Ошибка при получении версии: {e}")
return 0
def update_version(self, new_version, script_name):
"""Обновляет версию миграций в таблице migrations."""
logger.info(f'Попытка обновления версии: {new_version}, скрипт: {script_name}')
try:
current_date = datetime.now()
today = current_date.strftime("%d-%m-%Y %H:%M:%S")
cursor = self.conn.cursor()
cursor.execute(
"INSERT INTO migrations (version, script_name, created_at) VALUES(?, ?, ?)",
(new_version, script_name, today),
)
self.conn.commit()
logger.info(f"Версия обновлена: {new_version}, скрипт: {script_name}")
except sqlite3.IntegrityError as e:
logger.error(f"Ошибка при обновлении версии: {e}")
except Exception as e:
logger.error(f"Ошибка при обновлении версии: {e}")
# TODO: Deprecated, удалить
def get_message_from_db(self, type: str, username):
@@ -264,10 +305,10 @@ class BotDB:
#TODO: Функция всегда возвращает true, даже если такого id нет в таблице
self.cursor.execute("DELETE FROM blacklist WHERE user_id = ?", (user_id,))
self.conn.commit()
db_logger.info(f"User with ID {user_id} successfull delete.")
logger.info(f"Пользователь с идентификатором {user_id} успешно удален.")
return True
except sqlite3.Error as error:
db_logger.error(f"Error delete user with ID {user_id} from blacklist table: {str(error)}")
logger.error(f"Ошибка удаления пользователя с идентификатором {user_id} из таблицы blacklist. Ошибка: {str(error)}")
return False
def add_new_message_in_db(self, message_text, user_id, message_id, date, has_answer):
@@ -302,14 +343,17 @@ class BotDB:
result = self.cursor.fetchone()
return bool(result)
def add_admin(self, user_id, username=None):
def add_admin(self, user_id, role):
"""
Добавляет пользователя в список администраторов.
Args:
user_id: ID пользователя Telegram.
username: Username пользователя (необязательно).
role: Роль пользователя.
Доступные варианты:
1. creator - создатель
2. admin - обычная роль
"""
self.cursor.execute("INSERT INTO admins (user_id, username) VALUES (?, ?)", (user_id, username))
self.cursor.execute("INSERT INTO admins (user_id, role) VALUES (?, ?)", (user_id, role))
return self.conn.commit()
def remove_admin(self, user_id):

View File

@@ -34,13 +34,9 @@ LOGS = config.getboolean('Settings', 'logs')
TEST = config.getboolean('Settings', 'test')
# Инициализируем бота и базку
BotDB = BotDB('tg-bot-database')
BotDB = BotDB()
#TODO: Дописать функцию разбана и подключить ее к обработке коллбеков
#TODO: Подумать что сделать с процессом наступления даты разбана
#TODO: Сделать функционал игнора забаненных
class State(Enum):
START = "START"
SUGGEST = "SUGGEST"
@@ -214,7 +210,6 @@ class TelegramHelperBot:
# Получение сегодняшней даты в формате DD-MM-YYYY
current_date = datetime.now()
today = current_date.strftime("%d-%m-%Y")
print(today)
# Получение списка разблокированных пользователей
unblocked_users = BotDB.get_users_for_unblock_today(today)
message = "Разблокированные пользователи:\n"

View File

@@ -0,0 +1,27 @@
import os
from db import BotDB
BotDB = BotDB()
def get_filename():
"""Возвращает имя файла без расширения."""
filename = os.path.basename(__file__)
filename = os.path.splitext(filename)[0]
return filename
def main():
migrations_init = """
CREATE TABLE IF NOT EXISTS migrations (
version INTEGER PRIMARY KEY NOT NULL,
script_name TEXT NOT NULL,
created_at TEXT
);
"""
BotDB.create_table(migrations_init)
BotDB.update_version(0, get_filename())
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,56 @@
import os
from db import BotDB
BotDB = BotDB()
def get_filename():
"""Возвращает имя файла без расширения."""
filename = os.path.basename(__file__)
filename = os.path.splitext(filename)[0]
return filename
def main():
# Проверка версии миграций
current_version = BotDB.get_current_version() # Добавьте функцию для получения версии
# Выполнение миграций и проверка последней версии
if current_version < 1:
# Скрипты миграции
create_table_sql_1 = """
CREATE TABLE IF NOT EXISTS "admins" (
user_id INTEGER NOT NULL,
"role" TEXT
);
"""
create_table_sql_2 = """CREATE TABLE IF NOT EXISTS "blacklist"
(
"user_id" INTEGER NOT NULL UNIQUE,
"user_name" INTEGER,
"message_for_user" INTEGER,
"date_to_unban" INTEGER
);
"""
create_table_sql_3 = """
CREATE TABLE IF NOT EXISTS user_messages (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
message_text TEXT,
user_id INTEGER,
message_id INTEGER NOT NULL,
date TEXT
);
"""
# Применение миграции
BotDB.create_table(create_table_sql_1)
BotDB.create_table(create_table_sql_2)
BotDB.create_table(create_table_sql_3)
BotDB.add_admin(842766148, 'creator')
BotDB.add_admin(920057022, 'admin')
filename = get_filename()
BotDB.update_version(1, filename)
if __name__ == "__main__":
main()

View File

@@ -1,2 +1,3 @@
pyTelegramBotAPI
APScheduler~=3.10.4
loguru~=0.7.2