Добавил новые функции #1
@@ -1,17 +1,11 @@
|
|||||||
import logging
|
|
||||||
import os
|
|
||||||
import datetime
|
import datetime
|
||||||
from logging.handlers import RotatingFileHandler
|
import os
|
||||||
|
from loguru import logger
|
||||||
|
|
||||||
|
|
||||||
class Logger:
|
class Logger:
|
||||||
def __init__(self, name):
|
def __init__(self, name):
|
||||||
# Инициализация логгера
|
self.logger = logger.bind(name=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')
|
|
||||||
|
|
||||||
# Получение сегодняшней даты для имени файла
|
# Получение сегодняшней даты для имени файла
|
||||||
today = datetime.date.today().strftime('%Y-%m-%d')
|
today = datetime.date.today().strftime('%Y-%m-%d')
|
||||||
@@ -22,25 +16,16 @@ class Logger:
|
|||||||
if not os.path.exists(logs_dir):
|
if not os.path.exists(logs_dir):
|
||||||
# Если не существует, создаем ее
|
# Если не существует, создаем ее
|
||||||
os.makedirs(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,
|
filename,
|
||||||
mode='a',
|
rotation="00:00",
|
||||||
maxBytes=10 * 1024 * 1024, # Максимальный размер файла (10 МБ)
|
retention="5 days",
|
||||||
backupCount=3 # Количество резервных файлов
|
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):
|
def info(self, message):
|
||||||
self.logger.info(message)
|
self.logger.info(message)
|
||||||
@@ -55,4 +40,4 @@ class Logger:
|
|||||||
self.logger.error(message)
|
self.logger.error(message)
|
||||||
|
|
||||||
def critical(self, message):
|
def critical(self, message):
|
||||||
self.logger.critical(message)
|
self.logger.critical(message)
|
||||||
|
|||||||
66
db.py
66
db.py
@@ -1,23 +1,64 @@
|
|||||||
import sqlite3
|
import sqlite3
|
||||||
import configparser
|
import configparser
|
||||||
import os
|
import os
|
||||||
import sys
|
from datetime import datetime
|
||||||
import custom_logger
|
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 = configparser.ConfigParser()
|
||||||
config.read(config_path)
|
config.read(config_path)
|
||||||
LOGS = config.getboolean('Settings', 'logs')
|
LOGS = config.getboolean('Settings', 'logs')
|
||||||
IMPORTANT_LOGS = config.get('Telegram', 'important_logs')
|
IMPORTANT_LOGS = config.get('Telegram', 'important_logs')
|
||||||
|
|
||||||
db_logger = custom_logger.Logger('database')
|
|
||||||
|
|
||||||
|
|
||||||
class BotDB:
|
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.conn = sqlite3.connect(db_file, check_same_thread=False)
|
||||||
self.cursor = self.conn.cursor()
|
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, удалить
|
# TODO: Deprecated, удалить
|
||||||
def get_message_from_db(self, type: str, username):
|
def get_message_from_db(self, type: str, username):
|
||||||
@@ -264,10 +305,10 @@ class BotDB:
|
|||||||
#TODO: Функция всегда возвращает true, даже если такого id нет в таблице
|
#TODO: Функция всегда возвращает true, даже если такого id нет в таблице
|
||||||
self.cursor.execute("DELETE FROM blacklist WHERE user_id = ?", (user_id,))
|
self.cursor.execute("DELETE FROM blacklist WHERE user_id = ?", (user_id,))
|
||||||
self.conn.commit()
|
self.conn.commit()
|
||||||
db_logger.info(f"User with ID {user_id} successfull delete.")
|
logger.info(f"Пользователь с идентификатором {user_id} успешно удален.")
|
||||||
return True
|
return True
|
||||||
except sqlite3.Error as error:
|
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
|
return False
|
||||||
|
|
||||||
def add_new_message_in_db(self, message_text, user_id, message_id, date, has_answer):
|
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()
|
result = self.cursor.fetchone()
|
||||||
return bool(result)
|
return bool(result)
|
||||||
|
|
||||||
def add_admin(self, user_id, username=None):
|
def add_admin(self, user_id, role):
|
||||||
"""
|
"""
|
||||||
Добавляет пользователя в список администраторов.
|
Добавляет пользователя в список администраторов.
|
||||||
Args:
|
Args:
|
||||||
user_id: ID пользователя Telegram.
|
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()
|
return self.conn.commit()
|
||||||
|
|
||||||
def remove_admin(self, user_id):
|
def remove_admin(self, user_id):
|
||||||
|
|||||||
7
main.py
7
main.py
@@ -34,13 +34,9 @@ LOGS = config.getboolean('Settings', 'logs')
|
|||||||
TEST = config.getboolean('Settings', 'test')
|
TEST = config.getboolean('Settings', 'test')
|
||||||
|
|
||||||
# Инициализируем бота и базку
|
# Инициализируем бота и базку
|
||||||
BotDB = BotDB('tg-bot-database')
|
BotDB = BotDB()
|
||||||
|
|
||||||
|
|
||||||
#TODO: Дописать функцию разбана и подключить ее к обработке коллбеков
|
|
||||||
#TODO: Подумать что сделать с процессом наступления даты разбана
|
|
||||||
#TODO: Сделать функционал игнора забаненных
|
|
||||||
|
|
||||||
class State(Enum):
|
class State(Enum):
|
||||||
START = "START"
|
START = "START"
|
||||||
SUGGEST = "SUGGEST"
|
SUGGEST = "SUGGEST"
|
||||||
@@ -214,7 +210,6 @@ class TelegramHelperBot:
|
|||||||
# Получение сегодняшней даты в формате DD-MM-YYYY
|
# Получение сегодняшней даты в формате DD-MM-YYYY
|
||||||
current_date = datetime.now()
|
current_date = datetime.now()
|
||||||
today = current_date.strftime("%d-%m-%Y")
|
today = current_date.strftime("%d-%m-%Y")
|
||||||
print(today)
|
|
||||||
# Получение списка разблокированных пользователей
|
# Получение списка разблокированных пользователей
|
||||||
unblocked_users = BotDB.get_users_for_unblock_today(today)
|
unblocked_users = BotDB.get_users_for_unblock_today(today)
|
||||||
message = "Разблокированные пользователи:\n"
|
message = "Разблокированные пользователи:\n"
|
||||||
|
|||||||
27
migrations/000_migrations_init.py
Normal file
27
migrations/000_migrations_init.py
Normal 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()
|
||||||
56
migrations/001_create_new_tables.py
Normal file
56
migrations/001_create_new_tables.py
Normal 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()
|
||||||
@@ -1,2 +1,3 @@
|
|||||||
pyTelegramBotAPI
|
pyTelegramBotAPI
|
||||||
APScheduler~=3.10.4
|
APScheduler~=3.10.4
|
||||||
|
loguru~=0.7.2
|
||||||
Reference in New Issue
Block a user