start
This commit is contained in:
189
.gitignore
vendored
Normal file
189
.gitignore
vendored
Normal 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
154
main.py
Normal 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()
|
||||
Reference in New Issue
Block a user