diff --git a/backup.py b/backup.py new file mode 100644 index 00000000..1312bd16 --- /dev/null +++ b/backup.py @@ -0,0 +1,45 @@ +import subprocess +import os +import logging +from datetime import datetime +from aiogram.types import BufferedInputFile +from bot import bot +from config import ADMIN_ID, DB_USER, DB_NAME + +async def backup_database(): + # Параметры бэкапа + USER = DB_USER + HOST = "localhost" + BACKUP_DIR = "/home/vlad" + DATE = datetime.now().strftime("%Y-%m-%d-%H%M%S") + BACKUP_FILE = f"{BACKUP_DIR}/{DB_NAME}-backup-{DATE}.sql" + + # Команда для резервного копирования + try: + subprocess.run( + ['pg_dump', '-U', USER, '-h', HOST, '-F', 'c', '-f', BACKUP_FILE, DB_NAME], + check=True + ) + logging.info(f"Бэкап базы данных создан: {BACKUP_FILE}") + except subprocess.CalledProcessError as e: + logging.error(f"Ошибка при создании бэкапа базы данных: {e}") + return + + # Отправка файла бэкапа в чат админа + try: + with open(BACKUP_FILE, 'rb') as backup_file: + backup_input_file = BufferedInputFile(backup_file.read(), filename=os.path.basename(BACKUP_FILE)) + await bot.send_document(ADMIN_ID, backup_input_file) + logging.info(f"Бэкап базы данных отправлен админу: {ADMIN_ID}") + except Exception as e: + logging.error(f"Ошибка при отправке бэкапа в Telegram: {e}") + + # Удаление старых копий (старше 7 дней) + try: + subprocess.run( + ['find', BACKUP_DIR, '-type', 'f', '-name', '*.sql', '-mtime', '+7', '-exec', 'rm', '{}', ';'], + check=True + ) + logging.info("Старые бэкапы удалены.") + except subprocess.CalledProcessError as e: + logging.error(f"Ошибка при удалении старых бэкапов: {e}") diff --git a/backup_pg copy.sh b/backup_pg copy.sh deleted file mode 100644 index d12bc6c7..00000000 --- a/backup_pg copy.sh +++ /dev/null @@ -1,13 +0,0 @@ -# Параметры -DB_NAME="имя_вашей_базы" -USER="имя_пользователя_postgresql" -HOST="localhost" -BACKUP_DIR="/путь/к/папке/резервных_копий" -DATE=$(date +\%Y-\%m-\%d-\%H\%M\%S) -BACKUP_FILE="$BACKUP_DIR/$DB_NAME-backup-$DATE.sql" - -# Команда для резервного копирования -pg_dump -U $USER -h $HOST -F c -f $BACKUP_FILE $DB_NAME - -# Удаление старых копий (например, старше 7 дней) -find $BACKUP_DIR -type f -name "*.sql" -mtime +7 -exec rm {} \; \ No newline at end of file diff --git a/main.py b/main.py index 69676d3a..7e8f2fff 100644 --- a/main.py +++ b/main.py @@ -9,6 +9,7 @@ from config import WEBAPP_HOST, WEBAPP_PORT, WEBHOOK_PATH, WEBHOOK_URL from database import init_db from handlers.notifications import notify_expiring_keys from handlers.pay import payment_webhook +from backup import backup_database # Импорт функции бэкапа logging.basicConfig(level=logging.DEBUG) @@ -17,10 +18,16 @@ async def periodic_notifications(): await notify_expiring_keys(bot) await asyncio.sleep(3600) +async def periodic_database_backup(): + while True: + await backup_database() # Выполнение бэкапа базы данных + await asyncio.sleep(21600) # 6 часов = 21600 секунд + async def on_startup(app): await bot.set_webhook(WEBHOOK_URL) await init_db() - asyncio.create_task(periodic_notifications()) + asyncio.create_task(periodic_notifications()) # Уведомления + asyncio.create_task(periodic_database_backup()) # Бэкапы async def on_shutdown(app): await bot.delete_webhook() @@ -31,10 +38,9 @@ async def on_shutdown(app): except Exception as e: logging.error(f"Error during shutdown: {e}") - async def shutdown_site(site): logging.info("Остановка сайта...") - await site.stop() # Остановка сайта + await site.stop() logging.info("Сервер остановлен.") async def main(): @@ -63,7 +69,6 @@ async def main(): try: await asyncio.Event().wait() # Ожидание сигнала остановки finally: - # Убедимся, что сессии закрыты и задачи завершены pending = asyncio.all_tasks() for task in pending: task.cancel() @@ -74,4 +79,3 @@ if __name__ == '__main__': asyncio.run(main()) except Exception as e: logging.error(f"Ошибка при запуске приложения: {e}") -