Добавлена проверка перед скачиванием, что файл бэкапа уже полностью
создан
This commit is contained in:
108
main.py
108
main.py
@ -3,7 +3,7 @@ import re
|
||||
import time
|
||||
|
||||
# from datetime import datetime
|
||||
from dataclasses import dataclass, field
|
||||
from dataclasses import dataclass
|
||||
|
||||
# from pathlib import Path
|
||||
from playwright.sync_api import (
|
||||
@ -234,7 +234,7 @@ class BackupManager:
|
||||
backup_data: bool = False,
|
||||
backup_mysql: bool = True,
|
||||
wait_for_completion: bool = True,
|
||||
poll_interval: int = 30,
|
||||
poll_interval: int = 60,
|
||||
max_wait: int = 600,
|
||||
):
|
||||
"""
|
||||
@ -323,7 +323,7 @@ class BackupManager:
|
||||
) -> bool:
|
||||
"""Ожидание завершения создания бэкапа"""
|
||||
print(f"\n[*] Ожидание завершения (макс. {max_wait} сек)...")
|
||||
print(f" Ожидаем {expected_new} новых файлов")
|
||||
print(f" Ожидаем {expected_new} новых готовых файлов")
|
||||
|
||||
start_time = time.time()
|
||||
attempt = 0
|
||||
@ -340,52 +340,73 @@ class BackupManager:
|
||||
# Обновляем список через ссылку на странице
|
||||
self._refresh_backup_list()
|
||||
files_now = self.parse_backup_table()
|
||||
count_now = len(files_now)
|
||||
new_count = count_now - count_before
|
||||
|
||||
print(f"файлов: {count_now} (новых: {new_count})")
|
||||
# Считаем только ГОТОВЫЕ файлы (размер вида "12345 KB" без "формируется")
|
||||
ready_files = [f for f in files_now if self._is_file_ready(f)]
|
||||
ready_count = len(ready_files)
|
||||
new_ready = ready_count - count_before
|
||||
|
||||
if new_count >= expected_new:
|
||||
print(f"\n[OK] Бэкап создан! Новых файлов: {new_count}")
|
||||
# Считаем файлы в процессе создания
|
||||
in_progress = [f for f in files_now if not self._is_file_ready(f)]
|
||||
|
||||
print(
|
||||
f"готовых: {ready_count} (новых: {new_ready}), в процессе: {len(in_progress)}"
|
||||
)
|
||||
|
||||
if in_progress:
|
||||
for f in in_progress:
|
||||
print(f" ⏳ {f.name} — {f.size}")
|
||||
|
||||
if new_ready >= expected_new:
|
||||
print(f"\n[OK] Бэкап создан! Новых готовых файлов: {new_ready}")
|
||||
return True
|
||||
|
||||
# Проверяем статус задания
|
||||
status = self._check_task_status()
|
||||
if status:
|
||||
for s in status:
|
||||
print(f" Задание: {s}")
|
||||
# status = self._check_task_status()
|
||||
# if status:
|
||||
# for s in status:
|
||||
# print(f" Задание: {s}")
|
||||
|
||||
print(f" Следующая проверка через {poll_interval} сек...")
|
||||
time.sleep(poll_interval)
|
||||
|
||||
def _check_task_status(self) -> list[str]:
|
||||
"""Проверяет статус заданий в таблице Schedule/Operation"""
|
||||
statuses = self.page.evaluate("""() => {
|
||||
const tables = document.querySelectorAll('table');
|
||||
const results = [];
|
||||
def _is_file_ready(self, backup_file: BackupFile) -> bool:
|
||||
"""Проверяет что файл готов (не в процессе создания)"""
|
||||
size = backup_file.size.lower()
|
||||
# Готовый файл: "1033513 KB"
|
||||
# В процессе: "файл формируется, 50048 KB"
|
||||
if "формируется" in size or "создаётся" in size or "progress" in size:
|
||||
return False
|
||||
return True
|
||||
|
||||
for (const table of tables) {
|
||||
const headers = table.querySelectorAll('th');
|
||||
const headerTexts = Array.from(headers).map(h => h.innerText.trim());
|
||||
# def _check_task_status(self) -> list[str]:
|
||||
# """Проверяет статус заданий в таблице Schedule/Operation"""
|
||||
# statuses = self.page.evaluate("""() => {
|
||||
# const tables = document.querySelectorAll('table');
|
||||
# const results = [];
|
||||
|
||||
if (headerTexts.some(h => h.includes('Schedule') || h.includes('Operation'))) {
|
||||
const rows = table.querySelectorAll('tr');
|
||||
for (const row of rows) {
|
||||
const cells = row.querySelectorAll('td');
|
||||
if (cells.length >= 3) {
|
||||
const schedule = cells[0]?.innerText?.trim() || '';
|
||||
const server = cells[1]?.innerText?.trim() || '';
|
||||
const operation = cells[2]?.innerText?.trim() || '';
|
||||
if (schedule || operation) {
|
||||
results.push(`${schedule} | ${server} | ${operation}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}""")
|
||||
return statuses
|
||||
# for (const table of tables) {
|
||||
# const headers = table.querySelectorAll('th');
|
||||
# const headerTexts = Array.from(headers).map(h => h.innerText.trim());
|
||||
|
||||
# if (headerTexts.some(h => h.includes('Schedule') || h.includes('Operation'))) {
|
||||
# const rows = table.querySelectorAll('tr');
|
||||
# for (const row of rows) {
|
||||
# const cells = row.querySelectorAll('td');
|
||||
# if (cells.length >= 3) {
|
||||
# const schedule = cells[0]?.innerText?.trim() || '';
|
||||
# const server = cells[1]?.innerText?.trim() || '';
|
||||
# const operation = cells[2]?.innerText?.trim() || '';
|
||||
# if (schedule || operation) {
|
||||
# results.push(`${schedule} | ${server} | ${operation}`);
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
# return results;
|
||||
# }""")
|
||||
# return statuses
|
||||
|
||||
def create_backup_mysql_only(self, wait: bool = True):
|
||||
"""Создать только бэкап базы данных"""
|
||||
@ -647,16 +668,15 @@ class BackupManager:
|
||||
|
||||
# print("ПРОПУЩЕНО (удаление закомментировано)")
|
||||
|
||||
print(f"\n[OK] Готово")
|
||||
print("\n[OK] Готово")
|
||||
|
||||
|
||||
# === ИСПОЛЬЗОВАНИЕ ===
|
||||
|
||||
if __name__ == "__main__":
|
||||
mgr = BackupManager(
|
||||
username="minzdravmo",
|
||||
password="KB3ZS7*sv6j4zYr@bPdeFWQN38rbtQv",
|
||||
# backup_folder=Path("F:/test_folder/MyReports"),
|
||||
username="rav",
|
||||
password="KB3e8rbtQv",
|
||||
account_id="564622",
|
||||
)
|
||||
|
||||
@ -678,9 +698,9 @@ if __name__ == "__main__":
|
||||
)
|
||||
|
||||
# 3. Показать, что удаляем и удалить
|
||||
mgr.print_deletion_plan(delete_count=1, year=2026)
|
||||
# mgr.print_deletion_plan(delete_count=1, year=2026)
|
||||
|
||||
mgr.delete_old_backups(delete_count=1, year=2026)
|
||||
# mgr.delete_old_backups(delete_count=1, year=2026)
|
||||
|
||||
# Скачать только последний бэкап (без создания нового)
|
||||
# mgr.download_latest(save_dir="./backups")
|
||||
|
||||
BIN
requirements.txt
Normal file
BIN
requirements.txt
Normal file
Binary file not shown.
Reference in New Issue
Block a user