115 lines
5.1 KiB
Python
115 lines
5.1 KiB
Python
"""
|
||
Скрипт для объединения всех файлов в дереве каталогов в один .docx файл.
|
||
Выходной файл будет содержать пути к файлам, за которыми следует их содержимое.
|
||
"""
|
||
|
||
import os
|
||
from pathlib import Path
|
||
from docx import Document
|
||
from docx.shared import Inches
|
||
import mimetypes
|
||
|
||
|
||
def is_binary_file(file_path):
|
||
"""
|
||
Проверяет, является ли файл двоичным, пытаясь прочитать его как текст.
|
||
"""
|
||
try:
|
||
with open(file_path, 'tr', encoding='utf-8') as check_file:
|
||
check_file.read(1024) # Читаем первые 1KB для проверки
|
||
return False
|
||
except UnicodeDecodeError:
|
||
return True
|
||
|
||
|
||
def should_skip_directory(directory):
|
||
"""
|
||
Определяет, нужно ли пропустить каталог на основе общих шаблонов игнорирования.
|
||
"""
|
||
skip_dirs = {'.git', '.venv', '__pycache__', 'node_modules', '.pytest_cache',
|
||
'data', '.idea', '.vscode', 'logs', 'media', 'staticfiles'}
|
||
return any(skip_dir in directory.parts for skip_dir in skip_dirs)
|
||
|
||
|
||
def should_skip_file(file_path):
|
||
"""
|
||
Определяет, нужно ли пропустить файл на основе расширений или шаблонов.
|
||
"""
|
||
skip_extensions = {'.jpg', '.jpeg', '.png', '.gif', '.bmp', '.ico', '.svg',
|
||
'.mp3', '.mp4', '.avi', '.mov', '.pdf', '.zip', '.tar',
|
||
'.gz', '.exe', '.so', '.dll', '.doc', '.docx', '.xls',
|
||
'.xlsx', '.ppt', '.pptx', '.db', '.sqlite', '.log'}
|
||
|
||
file_ext = Path(file_path).suffix.lower()
|
||
return file_ext in skip_extensions
|
||
|
||
|
||
def concatenate_files_to_docx():
|
||
"""
|
||
Основная функция для объединения всех текстовых файлов в один документ .docx.
|
||
Обрабатываем только файлы из директорий src/apps и src/config.
|
||
"""
|
||
print("Начинаем объединение файлов...")
|
||
|
||
# Создаем новый документ Word
|
||
doc = Document()
|
||
|
||
# Добавляем заголовок
|
||
doc.add_heading('Объединенные файлы', 0)
|
||
|
||
# Определяем целевые директории
|
||
target_dirs = [
|
||
Path('./src/apps'),
|
||
Path('./src/config')
|
||
]
|
||
|
||
# Проходим по файлам в целевых директориях
|
||
for target_dir in target_dirs:
|
||
if target_dir.exists():
|
||
for file_path in target_dir.rglob('*'):
|
||
if file_path.is_file():
|
||
# Пропускаем определенные типы файлов
|
||
if should_skip_file(file_path):
|
||
continue
|
||
|
||
# Пропускаем, если это двоичный файл
|
||
if is_binary_file(str(file_path)):
|
||
print(f"Пропускаем двоичный файл: {file_path}")
|
||
continue
|
||
|
||
try:
|
||
# Добавляем путь к файлу как заголовок
|
||
doc.add_heading(str(file_path), level=1)
|
||
|
||
# Читаем содержимое файла
|
||
with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
|
||
content = f.read()
|
||
|
||
# Удаляем пустые строки из содержимого
|
||
lines = [line for line in content.splitlines() if line.strip()]
|
||
clean_content = '\n'.join(lines)
|
||
|
||
# Добавляем содержимое в документ
|
||
if clean_content.strip(): # Добавляем только если есть содержимое
|
||
doc.add_paragraph(clean_content)
|
||
else:
|
||
doc.add_paragraph("[Пустой файл]")
|
||
|
||
print(f"Добавлен файл: {file_path}")
|
||
|
||
except Exception as e:
|
||
error_msg = f"Ошибка чтения файла {file_path}: {str(e)}"
|
||
print(error_msg)
|
||
doc.add_heading(f"ОШИБКА: {file_path}", level=1)
|
||
doc.add_paragraph(error_msg)
|
||
else:
|
||
print(f"Целевая директория не найдена: {target_dir}")
|
||
|
||
# Сохраняем документ
|
||
output_filename = "один_файл_state_corp.docx"
|
||
doc.save(output_filename)
|
||
print(f"\nУспешно создан {output_filename} с объединенным содержимым!")
|
||
|
||
|
||
if __name__ == "__main__":
|
||
concatenate_files_to_docx() |