From d735cc193267037ed8ae99e4c983112c507e19ad Mon Sep 17 00:00:00 2001 From: VolandSZ <{E-MAIL}> Date: Sun, 15 Mar 2026 19:34:44 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D1=80=D0=BA=D0=B0?= =?UTF-8?q?=20=D0=BF=D0=B5=D1=80=D0=B5=D0=B4=20=D1=81=D0=BA=D0=B0=D1=87?= =?UTF-8?q?=D0=B8=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=D0=BC,=20=D1=87=D1=82?= =?UTF-8?q?=D0=BE=20=D1=84=D0=B0=D0=B9=D0=BB=20=D0=B1=D1=8D=D0=BA=D0=B0?= =?UTF-8?q?=D0=BF=D0=B0=20=D1=83=D0=B6=D0=B5=20=D0=BF=D0=BE=D0=BB=D0=BD?= =?UTF-8?q?=D0=BE=D1=81=D1=82=D1=8C=D1=8E=20=D1=81=D0=BE=D0=B7=D0=B4=D0=B0?= =?UTF-8?q?=D0=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.py | 108 ++++++++++++++++++++++++++++------------------- requirements.txt | Bin 0 -> 1962 bytes 2 files changed, 64 insertions(+), 44 deletions(-) create mode 100644 requirements.txt diff --git a/main.py b/main.py index 3581deb..74a32fc 100644 --- a/main.py +++ b/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") diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..5c87a2a6b0e0d831c6ce5ce73c028f898529f57b GIT binary patch literal 1962 zcmZvd-Ez}V41~`$GdxO|IzI(2cn4;9fJ~aWiA$5Xshb}j9@tN7)eU7lzKA8QR;xWH ze||5@bLsT#%g<7moqm1OGbx|Sjozw!EFa1uG7f!gTxN<)BZKHtbq8fMf`zn?ABp5AbW@jKpHEUt4{96ymSIPge9zyuIRNE+Urju4L?>kS-Ua5J{L+Xq_-Fxo?%Hbc6_1Zp`z%d%V$-OeOr{z1-ivh?TStYA z=UHe~1CBYjLR;$0EVOkx=k5nIGEmN);KamsCKE8py`nfB9aCle%f!>zwKFf}qo?SjnSFch9`CPJj1A279>vr-sjJTr`(3JE zo?M?0_hDDWalYARfA8eGVsE`hj?dNLA##3b3RL#3#I|s`F~CoMkE9@a)>kuu2p+uu z-QIOAZo-|%S8b_HEiSr)w&f{e0PJ-->0WwM8`xV16@-$-!bTff4yJd zdfY!Np~9IM=h0JjLZ=Vskeki36R)CIqTt)%3{3j}790Wsv60-(eas}V%6k$%Rp{tV zblP|uldZ#d-!S&|03a&@> qJBTm$5X!9MckYuqGkrhLNL{Y)K-_G1qQyz