This commit is contained in:
iTKeyS
2025-05-29 19:10:01 +08:00
parent fcd20689d3
commit a674cdd0ed
2 changed files with 343 additions and 0 deletions

189
.gitignore vendored Normal file
View File

@@ -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

154
main.py Normal file
View File

@@ -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()