"""Creación automática de config/ y carpetas de trabajo.""" import shutil import sys from pathlib import Path from ..constants import ( APP_DIR, BUNDLE_DIR, BUNDLED_SOURCE_7ZIP, BUNDLED_SOURCE_ODBC, CONFIG_DIR, DATA_DIR, DIR_ENTRADA, DIR_FALLADOS, DIR_PROCESADOS, DIR_TEMP, ENV_PATH, LOGS_DIR, ODBC_DIR, SEVEN_ZIP_DIR, ) from ..db.database import DatabaseManager from .env_loader import render_env_template def _copy_tree_if_missing(src: Path, dest: Path) -> None: if not src.is_dir() or dest.exists(): return dest.parent.mkdir(parents=True, exist_ok=True) shutil.copytree(src, dest) def _write_env_if_missing() -> None: if ENV_PATH.exists(): return template_path = BUNDLE_DIR / "packaging" / "templates" / "env.default" if not template_path.is_file(): template_path = APP_DIR / "packaging" / "templates" / "env.default" if template_path.is_file(): content = template_path.read_text(encoding="utf-8") content = content.replace("{APP_DIR}", str(APP_DIR)) else: content = render_env_template(APP_DIR) ENV_PATH.write_text(content, encoding="utf-8") try: ENV_PATH.chmod(0o600) except OSError: pass def ensure_runtime_layout() -> None: """ Idempotente: crea config/, carpetas de trabajo y .env si no existen. No sobrescribe .env ni app.db existentes. """ for directory in ( CONFIG_DIR, DATA_DIR, LOGS_DIR, ODBC_DIR, SEVEN_ZIP_DIR, DIR_ENTRADA, DIR_PROCESADOS, DIR_FALLADOS, DIR_TEMP, ): directory.mkdir(parents=True, exist_ok=True) _write_env_if_missing() _copy_tree_if_missing(BUNDLED_SOURCE_7ZIP, SEVEN_ZIP_DIR) _copy_tree_if_missing(BUNDLED_SOURCE_ODBC, ODBC_DIR) from ..constants import DB_PATH if not DB_PATH.exists(): DatabaseManager(DB_PATH) if getattr(sys, "frozen", False): marker = CONFIG_DIR / ".bootstrap_ok" if not marker.exists(): marker.write_text("ok", encoding="utf-8")