From a674cdd0ed65c2409d759da3f67e16fb5429f701 Mon Sep 17 00:00:00 2001 From: iTKeyS Date: Thu, 29 May 2025 19:10:01 +0800 Subject: [PATCH] start --- .gitignore | 189 +++++++++++++++++++++++++++++++++++++++++++++++++++++ main.py | 154 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 343 insertions(+) create mode 100644 .gitignore create mode 100644 main.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d1a7fc7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,189 @@ +# ---> Python + +# Скомпилированные и оптимизированные файлы Python +__pycache__/ +*.py[cod] +*$py.class + +# C-расширения +*.so + +# Артефакты сборки и управления пакетами +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller: файлы для сборки исполняемых файлов +*.manifest +*.spec + +# Логи установщика пакетов +pip-log.txt +pip-delete-this-directory.txt + +# Кэш тестирования и покрытия кода +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Файлы локализации +*.mo +*.pot + +# Django и Flask +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal +instance/ +.webassets-cache + +# Scrapy +.scrapy + +# Документация Sphinx +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# Управление версиями Python (pyenv) +.python-version + +# pipenv, poetry, pdm +.pdm.toml +.pdm-python +.pdm-build/ +__pypackages__/ +poetry.lock +pdm.lock + +# Очереди и кеши (Celery) +celerybeat-schedule +celerybeat.pid + +# Символы отладки Cython +cython_debug/ + +# Анализаторы типов (mypy, pyre, pytype) +.mypy_cache/ +.dmypy.json +dmypy.json +.pyre/ +.pytype/ + +# PyCharm и другие JetBrains IDE +.idea/ + +# Spyder и Rope +.spyderproject +.spyproject +.ropeproject + +# MkDocs +/site + +# Конфигурация Obsidian +.obsidian/ + +# Виртуальные окружения Python +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Зависимости NPM/Yarn и артефакты сборки +node_modules +dist/ + +# Конфигурации IDE и редакторов +.idea +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace +.fleet/ + +# Visual Studio Code (исключая файлы настроек проекта) +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json + +# Системные файлы ОС +.DS_Store +Thumbs.db + +# Лог-файлы NPM/Yarn +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Логи и SQLite-базы +*.log +*.log.* +logs/* +logs/debug.* +logs/requests.* + +# Исключение отдельных файлов +TODOS.md +*_00 + +# Исключение миграций, кроме структуры директорий +migrations/ +migrations/**/**/* +!migrations/**/.keep + +# Статические файлы Django +/staticfiles/* +/static/* + +/backend_old/ +/backend_old/* +*/backend_old/* + +_old/ +/_old/* + +.DS_Store +*.DS_Store \ No newline at end of file diff --git a/main.py b/main.py new file mode 100644 index 0000000..6283743 --- /dev/null +++ b/main.py @@ -0,0 +1,154 @@ +import os +import csv +import time +import pathlib +from datetime import datetime + +# Пути для поиска файлов +SEARCH_DIRS = ["Desktop", "Downloads", "Documents"] +EXTENSIONS = (".mov", ".avi", ".mp3", ".mp4", ".mkv", ".wav", ".flac") + +# Файлы с хостами и результатами +HOSTS_FILE = "hosts.txt" +OUTPUT_CSV = "found_files.csv" +FAILED_CSV = "failed_hosts.csv" + +# Системные папки, которые не нужно сканировать +EXCLUDE_FOLDERS = {"Administrator", "DefaultAccount", "Public", "All Users", "Default", "WDAGUtilityAccount"} + +# Список недоступных ПК +failed_hosts = [] + +def format_size(size_bytes): + """ Форматирование размера файла в MB/GB """ + if size_bytes >= 1_073_741_824: + return f"{size_bytes / 1_073_741_824:.2f} GB" + elif size_bytes >= 1_048_576: + return f"{size_bytes / 1_048_576:.2f} MB" + return f"{size_bytes} bytes" + +def get_users_from_folders(host): + """ Получает список пользователей, проверяя папки в \\host\c$\Users """ + users_path = f"\\\\{host}\\c$\\Users" + + try: + if not os.path.exists(users_path): + print(f"[Ошибка] ПК {host} недоступен!") + failed_hosts.append(host) + return [] + + users = [u for u in os.listdir(users_path) if u not in EXCLUDE_FOLDERS] + print(f"[{host}] Найдено {len(users)} пользователей: {users}") + return users + except Exception as e: + print(f"[Ошибка] Не удалось получить пользователей с {host}: {e}") + failed_hosts.append(host) + return [] + +def get_file_info(file_path): + """ Получает информацию о файле """ + try: + file_stat = os.stat(file_path) + return { + "size_bytes": file_stat.st_size, + "size_formatted": format_size(file_stat.st_size), + "created": datetime.fromtimestamp(file_stat.st_ctime).strftime("%Y-%m-%d %H:%M:%S"), + "last_accessed": datetime.fromtimestamp(file_stat.st_atime).strftime("%Y-%m-%d %H:%M:%S"), + } + except Exception as e: + print(f"[Ошибка] Не удалось получить данные о файле {file_path}: {e}") + return None + +def wait_for_folder_access(path, timeout=10): + """ Открывает проводник для доступа к скрытым файлам и ждет индексации """ + try: + print(f"[Открытие проводника] {path}") + os.startfile(path) + time.sleep(3) + + start_time = time.time() + while time.time() - start_time < timeout: + if os.path.exists(path) and os.listdir(path): + print(f"[Готово] Папка доступна: {path}") + return True + print(f"[Ожидание] Файлы еще не загружены... ({int(time.time() - start_time)}/{timeout} сек)") + time.sleep(2) + + print(f"[Ошибка] Не удалось получить доступ к {path}") + return False + except Exception as e: + print(f"[Ошибка] Не удалось открыть {path}: {e}") + return False + +def scan_host(host): + """ Сканирует ПК и находит файлы с нужными расширениями """ + results = [] + users = get_users_from_folders(host) + + if not users: + return results + + for user in users: + base_path = f"\\\\{host}\\c$\\Users\\{user}" + if not os.path.exists(base_path): + print(f"[Пропуск] Папка {base_path} не найдена") + continue + + if not wait_for_folder_access(base_path): + continue + + for folder in SEARCH_DIRS: + search_path = os.path.join(base_path, folder) + if not os.path.exists(search_path): + print(f"[Пропуск] Нет папки {search_path}") + continue + + print(f"[Поиск] {search_path}") + for root, _, files in os.walk(search_path): + for file in files: + if file.lower().endswith(EXTENSIONS): + file_path = os.path.join(root, file) + file_info = get_file_info(file_path) + if file_info: + results.append([ + host, user, pathlib.Path(file).suffix, + file_info["size_bytes"], file_info["size_formatted"], + file_info["created"], file_info["last_accessed"], file_path + ]) + print(f"[Найден файл] {file_path} ({file_info['size_formatted']})") + + return results + +def main(): + with open(HOSTS_FILE, "r") as f: + hosts = [line.strip() for line in f.readlines() if line.strip()] + + all_results = [] + for host in hosts: + print(f"\n🔍 [Сканирование] ПК: {host}") + results = scan_host(host) + all_results.extend(results) + + # Сохранение найденных файлов в CSV + with open(OUTPUT_CSV, "w", newline="", encoding="utf-8") as csv_file: + writer = csv.writer(csv_file) + writer.writerow(["PC Name", "User", "File Type", "Size (bytes)", "Size (Formatted)", "Created Date", "Last Accessed", "File Path"]) + writer.writerows(all_results) + + print(f"\n✅ Поиск завершен! Результаты сохранены в {OUTPUT_CSV}") + + # Сохранение списка недоступных ПК + if failed_hosts: + with open(FAILED_CSV, "w", newline="", encoding="utf-8") as csv_file: + writer = csv.writer(csv_file) + writer.writerow(["PC Name"]) + writer.writerows([[host] for host in failed_hosts]) + + print("\n❌ [Ошибка] Не удалось подключиться к следующим ПК:") + for host in failed_hosts: + print(f" - {host}") + + print(f"📄 Список недоступных ПК сохранен в {FAILED_CSV}") + +if __name__ == "__main__": + main()