import os
import csv
import re
# =====================================================================
# НАСТРОЙКИ
# =====================================================================
folder_path = "Downloads_Bank_Docs" # Твоя главная папка с доками (и Batch-папками)
csv_file = "docs.csv" # Файл из Excel
report_file = "full_audit_report.txt" # Куда сохраним результаты
col_status = "Статус"
col_filename = "Имя файла" # ВАЖНО: проверь, как точно называется эта колонка
# =====================================================================
def run_audit():
if not os.path.exists(folder_path):
print(f"[!] Ошибка: Папка {folder_path} не найдена.")
return
if not os.path.exists(csv_file):
print(f"[!] Ошибка: Файл {csv_file} не найден.")
return
print("--- Начинаю глубокую сверку... ---")
# 1. Собираем все файлы со всех подпапок (Batch_1, Batch_2 и т.д.)
actual_files = set()
duplicate_suspects = []
for root, dirs, files in os.walk(folder_path):
for file in files:
actual_files.add(file)
# Регулярка ищет файлы, заканчивающиеся на (1).pdf, (2).docx и т.д.
if re.search(r'\(\d+\)\.\w+$', file):
# Сохраняем вместе с путем, чтобы знать, где он лежит
duplicate_suspects.append(os.path.join(root, file))
print(f"Реально файлов на диске: {len(actual_files)}")
# 2. Читаем CSV, чтобы понять, что ДОЛЖНО быть
expected_files = set()
with open(csv_file, mode="r", encoding="utf-8-sig") as f:
reader = csv.DictReader(f, delimiter=";") # Если не сработает, поменяй ";" на ","
for row in reader:
status = row.get(col_status, "")
if status and "Действителен" in status:
fname = row.get(col_filename, "").strip()
if fname:
expected_files.add(fname)
print(f"Должно быть по списку (Действительных): {len(expected_files)}")
# 3. Вычисляем разницу
# Лишние: есть на диске, но нет в CSV
extra_files = actual_files - expected_files
# Не хватает: есть в CSV, но нет на диске
missing_files = expected_files - actual_files
# 4. Сохраняем красивый отчет
with open(report_file, "w", encoding="utf-8") as out:
out.write(f"=== ОТЧЕТ ПО ФАЙЛАМ ===\n")
out.write(f"На диске: {len(actual_files)}\n")
out.write(f"По списку: {len(expected_files)}\n\n")
if duplicate_suspects:
out.write(f"--- ПОДОЗРИТЕЛЬНЫЕ ДУБЛИКАТЫ В ПАПКАХ ({len(duplicate_suspects)} шт.) ---\n")
out.write("Скорее всего, это копии. Проверь их:\n")
for d in duplicate_suspects:
out.write(f" [?] {d}\n")
out.write("\n")
if extra_files:
out.write(f"--- ЛИШНИЕ ФАЙЛЫ НА ДИСКЕ ({len(extra_files)} шт.) ---\n")
out.write("Они есть в папках, но их нет в Excel среди 'Действительных':\n")
for ext in extra_files:
out.write(f" [-] {ext}\n")
out.write("\n")
if missing_files:
out.write(f"--- НЕ ХВАТАЕТ ФАЙЛОВ ({len(missing_files)} шт.) ---\n")
out.write("Они есть в Excel, но не скачались:\n")
for mis in missing_files:
out.write(f" [+] {mis}\n")
print(f"\n--- ГОТОВО! ---")
print(f"Все списки сохранены в файл: {report_file}")
print("Открой его, там всё подробно расписано.")
if __name__ == "__main__":
run_audit()