it's version 0.8 Добавлена возможность выключения хранения логов и баз данных
This commit is contained in:
@@ -0,0 +1,10 @@
|
|||||||
|
TELEGRAM_BOT_TOKEN=your_token_here
|
||||||
|
|
||||||
|
# Полное отключение логов и любого хранения (БД, файлы логов, сохранение message_id)
|
||||||
|
# DISABLE_PERSISTENCE=1
|
||||||
|
|
||||||
|
# Или по отдельности:
|
||||||
|
# DISABLE_LOGGING=1 — нет логов в консоль и в файл
|
||||||
|
# DISABLE_STORAGE=1 — нет SQLite, /del не работает, группы /set не сохраняются
|
||||||
|
|
||||||
|
SCHEDULE_DRIVE_FOLDER_ID=1WhUFHGkS4qC_e84KRArF4ooXHJr8mL5T
|
||||||
@@ -12,6 +12,8 @@ logger = getLogger(__name__)
|
|||||||
|
|
||||||
def register_handlers(dp: Dispatcher, state: BotState, bot: Bot) -> int:
|
def register_handlers(dp: Dispatcher, state: BotState, bot: Bot) -> int:
|
||||||
async def init_db():
|
async def init_db():
|
||||||
|
if Config.DISABLE_STORAGE:
|
||||||
|
return
|
||||||
async with aiosqlite.connect(Config.DAYS_TO_DB_PATH) as db:
|
async with aiosqlite.connect(Config.DAYS_TO_DB_PATH) as db:
|
||||||
await db.execute("""
|
await db.execute("""
|
||||||
CREATE TABLE IF NOT EXISTS days_to_new_year (
|
CREATE TABLE IF NOT EXISTS days_to_new_year (
|
||||||
@@ -24,6 +26,8 @@ def register_handlers(dp: Dispatcher, state: BotState, bot: Bot) -> int:
|
|||||||
logger.info("База данных инициализирована")
|
logger.info("База данных инициализирована")
|
||||||
|
|
||||||
async def save_days_to_db(user_id: int, days: int):
|
async def save_days_to_db(user_id: int, days: int):
|
||||||
|
if Config.DISABLE_STORAGE:
|
||||||
|
return
|
||||||
logger.debug(f"Сохраняем user_id={user_id}, days={days}")
|
logger.debug(f"Сохраняем user_id={user_id}, days={days}")
|
||||||
async with aiosqlite.connect(Config.DAYS_TO_DB_PATH) as db:
|
async with aiosqlite.connect(Config.DAYS_TO_DB_PATH) as db:
|
||||||
await db.execute("""
|
await db.execute("""
|
||||||
@@ -34,6 +38,8 @@ def register_handlers(dp: Dispatcher, state: BotState, bot: Bot) -> int:
|
|||||||
logger.info(f"Запись сохранена: user_id={user_id}, days={days}")
|
logger.info(f"Запись сохранена: user_id={user_id}, days={days}")
|
||||||
|
|
||||||
async def get_last_days(user_id: int) -> int | None:
|
async def get_last_days(user_id: int) -> int | None:
|
||||||
|
if Config.DISABLE_STORAGE:
|
||||||
|
return None
|
||||||
async with aiosqlite.connect(Config.DAYS_TO_DB_PATH) as db:
|
async with aiosqlite.connect(Config.DAYS_TO_DB_PATH) as db:
|
||||||
async with db.execute(
|
async with db.execute(
|
||||||
"SELECT days FROM days_to_new_year WHERE user_id = ?", (int(user_id),)
|
"SELECT days FROM days_to_new_year WHERE user_id = ?", (int(user_id),)
|
||||||
|
|||||||
@@ -1,11 +1,20 @@
|
|||||||
import os
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
|
|
||||||
|
load_dotenv()
|
||||||
|
|
||||||
|
|
||||||
|
def _env_bool(name: str, default: bool = False) -> bool:
|
||||||
|
raw = os.getenv(name)
|
||||||
|
if raw is None:
|
||||||
|
return default
|
||||||
|
return raw.strip().lower() in ("1", "true", "yes", "on")
|
||||||
|
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
# Загружаем .env
|
|
||||||
load_dotenv()
|
|
||||||
|
|
||||||
# API
|
# API
|
||||||
API_TOKEN = os.getenv("TELEGRAM_BOT_TOKEN")
|
API_TOKEN = os.getenv("TELEGRAM_BOT_TOKEN")
|
||||||
@@ -40,9 +49,23 @@ class Config:
|
|||||||
"SCHEDULE_DRIVE_FOLDER_ID", "1WhUFHGkS4qC_e84KRArF4ooXHJr8mL5T"
|
"SCHEDULE_DRIVE_FOLDER_ID", "1WhUFHGkS4qC_e84KRArF4ooXHJr8mL5T"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Отключение логов и хранения (см. .env.example)
|
||||||
|
# DISABLE_PERSISTENCE=1 — выключает и логи, и все БД/файлы сразу
|
||||||
|
_NO_PERSISTENCE = _env_bool("DISABLE_PERSISTENCE")
|
||||||
|
DISABLE_LOGGING = (
|
||||||
|
_env_bool("DISABLE_LOGGING")
|
||||||
|
if os.getenv("DISABLE_LOGGING") is not None
|
||||||
|
else _NO_PERSISTENCE
|
||||||
|
)
|
||||||
|
DISABLE_STORAGE = (
|
||||||
|
_env_bool("DISABLE_STORAGE")
|
||||||
|
if os.getenv("DISABLE_STORAGE") is not None
|
||||||
|
else _NO_PERSISTENCE
|
||||||
|
)
|
||||||
|
|
||||||
# Пути
|
# Пути
|
||||||
LOG_FILE = "storage/log/bot.log"
|
LOG_FILE = Path("storage/log/bot.log")
|
||||||
DAYS_TO_DB_PATH = "addons/x_days_to/days_to_new_year.db"
|
DAYS_TO_DB_PATH = Path("addons/x_days_to/days_to_new_year.db")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
+25
-3
@@ -17,8 +17,14 @@ def register_handlers(dp: Dispatcher, state: BotState, bot: Bot):
|
|||||||
@saving
|
@saving
|
||||||
@admin_required(3)
|
@admin_required(3)
|
||||||
async def send_log(message: Message):
|
async def send_log(message: Message):
|
||||||
|
if Config.DISABLE_LOGGING:
|
||||||
|
await message.answer("📝 Логирование отключено (DISABLE_LOGGING=1).")
|
||||||
|
return
|
||||||
|
if Config.DISABLE_STORAGE:
|
||||||
|
await message.answer("📝 Файл логов не ведётся (DISABLE_STORAGE=1).")
|
||||||
|
return
|
||||||
try:
|
try:
|
||||||
log_file = types.FSInputFile(Config.LOG_FILE)
|
log_file = types.FSInputFile(str(Config.LOG_FILE))
|
||||||
await message.answer_document(log_file, caption="📑 Логи бота")
|
await message.answer_document(log_file, caption="📑 Логи бота")
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
await message.answer("Файл логов пока не создан.")
|
await message.answer("Файл логов пока не создан.")
|
||||||
@@ -31,7 +37,12 @@ def register_handlers(dp: Dispatcher, state: BotState, bot: Bot):
|
|||||||
from utils.mac_metrics import get_macbook_battery_level, get_process_usage
|
from utils.mac_metrics import get_macbook_battery_level, get_process_usage
|
||||||
|
|
||||||
try:
|
try:
|
||||||
stats = analyze_bot_logs(Config.LOG_FILE)
|
if Config.DISABLE_LOGGING or Config.DISABLE_STORAGE:
|
||||||
|
await message.answer(
|
||||||
|
"📊 Аналитика по логам недоступна: логирование или хранение отключено в .env"
|
||||||
|
)
|
||||||
|
return
|
||||||
|
stats = analyze_bot_logs(str(Config.LOG_FILE))
|
||||||
batt = await get_macbook_battery_level()
|
batt = await get_macbook_battery_level()
|
||||||
usage = await get_process_usage()
|
usage = await get_process_usage()
|
||||||
status_text = (
|
status_text = (
|
||||||
@@ -53,7 +64,12 @@ def register_handlers(dp: Dispatcher, state: BotState, bot: Bot):
|
|||||||
async def stat(message: Message):
|
async def stat(message: Message):
|
||||||
from utils.analytics import analyze_bot_logs
|
from utils.analytics import analyze_bot_logs
|
||||||
|
|
||||||
stats = analyze_bot_logs(Config.LOG_FILE)
|
if Config.DISABLE_LOGGING or Config.DISABLE_STORAGE:
|
||||||
|
await message.answer(
|
||||||
|
"📊 Аналитика по логам недоступна: логирование или хранение отключено в .env"
|
||||||
|
)
|
||||||
|
return
|
||||||
|
stats = analyze_bot_logs(str(Config.LOG_FILE))
|
||||||
await message.answer(
|
await message.answer(
|
||||||
create_statistics_text(stats), reply_to_message_id=message.message_id
|
create_statistics_text(stats), reply_to_message_id=message.message_id
|
||||||
)
|
)
|
||||||
@@ -61,6 +77,12 @@ def register_handlers(dp: Dispatcher, state: BotState, bot: Bot):
|
|||||||
@dp.message(Command("del"))
|
@dp.message(Command("del"))
|
||||||
@admin_required(1)
|
@admin_required(1)
|
||||||
async def delete_all_messages(message: Message):
|
async def delete_all_messages(message: Message):
|
||||||
|
if Config.DISABLE_STORAGE:
|
||||||
|
await message.answer(
|
||||||
|
"📭 Хранение сообщений отключено (DISABLE_STORAGE=1).",
|
||||||
|
reply_to_message_id=message.message_id,
|
||||||
|
)
|
||||||
|
return
|
||||||
messages = load_messages()
|
messages = load_messages()
|
||||||
if not messages:
|
if not messages:
|
||||||
sent = await message.answer(
|
sent = await message.answer(
|
||||||
|
|||||||
@@ -1,17 +1,11 @@
|
|||||||
from asyncio import run
|
from asyncio import run
|
||||||
from logging import basicConfig, FileHandler, StreamHandler, INFO, getLogger
|
from logging import getLogger
|
||||||
|
|
||||||
from bot.core import TelegramBot
|
from bot.core import TelegramBot
|
||||||
from config import Config
|
from config import Config
|
||||||
|
from utils.logging_config import setup_logging
|
||||||
|
|
||||||
# Настройка логирования
|
setup_logging()
|
||||||
basicConfig(
|
|
||||||
level=INFO,
|
|
||||||
format="%(asctime)s [%(levelname)s] %(message)s",
|
|
||||||
datefmt="%Y-%m-%d %H:%M:%S",
|
|
||||||
handlers=[FileHandler(Config.LOG_FILE, encoding="utf-8"), StreamHandler()],
|
|
||||||
force=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
logger = getLogger(__name__)
|
logger = getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+6
-1
@@ -1,6 +1,9 @@
|
|||||||
import sqlite3
|
import sqlite3
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
DIR = "/Users/mac/myfirstprogramm/storage/message.db"
|
from config import Config
|
||||||
|
|
||||||
|
DIR = Path(__file__).resolve().parent / "message.db"
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
db = sqlite3.connect(DIR)
|
db = sqlite3.connect(DIR)
|
||||||
@@ -33,4 +36,6 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
|
|
||||||
def get_db():
|
def get_db():
|
||||||
|
if Config.DISABLE_STORAGE:
|
||||||
|
raise RuntimeError("Хранение отключено (DISABLE_STORAGE=1)")
|
||||||
return sqlite3.connect(DIR)
|
return sqlite3.connect(DIR)
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
from .DB import get_db
|
from config import Config
|
||||||
|
|
||||||
|
|
||||||
def save_message(chat_id: int, message_id: int):
|
def save_message(chat_id: int, message_id: int):
|
||||||
|
if Config.DISABLE_STORAGE:
|
||||||
|
return
|
||||||
|
from .DB import get_db
|
||||||
|
|
||||||
db = get_db()
|
db = get_db()
|
||||||
cur = db.cursor()
|
cur = db.cursor()
|
||||||
cur.execute("INSERT INTO message VALUES (?, ?)", (int(chat_id), int(message_id)))
|
cur.execute("INSERT INTO message VALUES (?, ?)", (int(chat_id), int(message_id)))
|
||||||
@@ -11,6 +15,10 @@ def save_message(chat_id: int, message_id: int):
|
|||||||
|
|
||||||
|
|
||||||
def load_messages():
|
def load_messages():
|
||||||
|
if Config.DISABLE_STORAGE:
|
||||||
|
return []
|
||||||
|
from .DB import get_db
|
||||||
|
|
||||||
db = get_db()
|
db = get_db()
|
||||||
cur = db.cursor()
|
cur = db.cursor()
|
||||||
cur.execute("SELECT * FROM message")
|
cur.execute("SELECT * FROM message")
|
||||||
@@ -21,6 +29,10 @@ def load_messages():
|
|||||||
|
|
||||||
|
|
||||||
def clear_messages():
|
def clear_messages():
|
||||||
|
if Config.DISABLE_STORAGE:
|
||||||
|
return
|
||||||
|
from .DB import get_db
|
||||||
|
|
||||||
db = get_db()
|
db = get_db()
|
||||||
cur = db.cursor()
|
cur = db.cursor()
|
||||||
cur.execute("DELETE FROM message")
|
cur.execute("DELETE FROM message")
|
||||||
|
|||||||
@@ -1,6 +1,13 @@
|
|||||||
from .DB import get_db
|
from config import Config
|
||||||
|
|
||||||
|
_DEFAULT_GROUP = "30тс"
|
||||||
|
|
||||||
|
|
||||||
|
def save_user(user_id: int, group: str = _DEFAULT_GROUP):
|
||||||
|
if Config.DISABLE_STORAGE:
|
||||||
|
return
|
||||||
|
from .DB import get_db
|
||||||
|
|
||||||
def save_user(user_id: int, group: str = "30тс"):
|
|
||||||
db = get_db()
|
db = get_db()
|
||||||
cur = db.cursor()
|
cur = db.cursor()
|
||||||
cur.execute("INSERT INTO users (user_id, user_group) VALUES (?, ?)", (user_id, group))
|
cur.execute("INSERT INTO users (user_id, user_group) VALUES (?, ?)", (user_id, group))
|
||||||
@@ -8,19 +15,20 @@ def save_user(user_id: int, group: str = "30тс"):
|
|||||||
cur.close()
|
cur.close()
|
||||||
db.close()
|
db.close()
|
||||||
|
|
||||||
def set_group(user_id: int, group: str = "30тс"):
|
|
||||||
|
def set_group(user_id: int, group: str = _DEFAULT_GROUP):
|
||||||
|
if Config.DISABLE_STORAGE:
|
||||||
|
return
|
||||||
|
from .DB import get_db
|
||||||
|
|
||||||
db = get_db()
|
db = get_db()
|
||||||
cur = db.cursor()
|
cur = db.cursor()
|
||||||
|
|
||||||
# проверяем, есть ли пользователь
|
|
||||||
cur.execute("SELECT 1 FROM users WHERE user_id = ?", (user_id,))
|
cur.execute("SELECT 1 FROM users WHERE user_id = ?", (user_id,))
|
||||||
exists = cur.fetchone()
|
exists = cur.fetchone()
|
||||||
|
|
||||||
if exists:
|
if exists:
|
||||||
# если есть — обновляем группу
|
|
||||||
cur.execute("UPDATE users SET user_group = ? WHERE user_id = ?", (group, user_id))
|
cur.execute("UPDATE users SET user_group = ? WHERE user_id = ?", (group, user_id))
|
||||||
else:
|
else:
|
||||||
# если нет — регистрируем нового пользователя
|
|
||||||
cur.execute("INSERT INTO users (user_id, user_group) VALUES (?, ?)", (user_id, group))
|
cur.execute("INSERT INTO users (user_id, user_group) VALUES (?, ?)", (user_id, group))
|
||||||
|
|
||||||
db.commit()
|
db.commit()
|
||||||
@@ -28,7 +36,11 @@ def set_group(user_id: int, group: str = "30тс"):
|
|||||||
db.close()
|
db.close()
|
||||||
|
|
||||||
|
|
||||||
def get_group(user_id: int, default: str = "30тс") -> str:
|
def get_group(user_id: int, default: str = _DEFAULT_GROUP) -> str:
|
||||||
|
if Config.DISABLE_STORAGE:
|
||||||
|
return default
|
||||||
|
from .DB import get_db
|
||||||
|
|
||||||
db = get_db()
|
db = get_db()
|
||||||
cur = db.cursor()
|
cur = db.cursor()
|
||||||
cur.execute("SELECT user_group FROM users WHERE user_id = ?", (user_id,))
|
cur.execute("SELECT user_group FROM users WHERE user_id = ?", (user_id,))
|
||||||
@@ -36,7 +48,6 @@ def get_group(user_id: int, default: str = "30тс") -> str:
|
|||||||
if row:
|
if row:
|
||||||
group = row[0]
|
group = row[0]
|
||||||
else:
|
else:
|
||||||
# если пользователя нет — регистрируем с дефолтной группой
|
|
||||||
cur.execute("INSERT INTO users (user_id, user_group) VALUES (?, ?)", (user_id, default))
|
cur.execute("INSERT INTO users (user_id, user_group) VALUES (?, ?)", (user_id, default))
|
||||||
db.commit()
|
db.commit()
|
||||||
group = default
|
group = default
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
import logging
|
||||||
|
from logging import CRITICAL, NullHandler, getLogger
|
||||||
|
|
||||||
|
from config import Config
|
||||||
|
|
||||||
|
|
||||||
|
def setup_logging() -> None:
|
||||||
|
"""Настройка логирования. При DISABLE_LOGGING — полное отключение."""
|
||||||
|
root = getLogger()
|
||||||
|
|
||||||
|
if Config.DISABLE_LOGGING:
|
||||||
|
root.handlers.clear()
|
||||||
|
root.addHandler(NullHandler())
|
||||||
|
root.setLevel(CRITICAL)
|
||||||
|
logging.disable(CRITICAL)
|
||||||
|
return
|
||||||
|
|
||||||
|
from logging import INFO, StreamHandler, basicConfig
|
||||||
|
from logging.handlers import FileHandler
|
||||||
|
|
||||||
|
handlers: list[logging.Handler] = [StreamHandler()]
|
||||||
|
|
||||||
|
if not Config.DISABLE_STORAGE:
|
||||||
|
log_path = Config.LOG_FILE
|
||||||
|
log_path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
handlers.append(FileHandler(log_path, encoding="utf-8"))
|
||||||
|
|
||||||
|
basicConfig(
|
||||||
|
level=INFO,
|
||||||
|
format="%(asctime)s [%(levelname)s] %(message)s",
|
||||||
|
datefmt="%Y-%m-%d %H:%M:%S",
|
||||||
|
handlers=handlers,
|
||||||
|
force=True,
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user