# AutoBackups Project ## Overview AutoBackups is a Python application designed to automate the backup of Simatic S7 projects and other user-defined directories. The application leverages the Everything API to efficiently locate files and manage backups based on user-defined configurations. ## Features - Monitors specified directories for Simatic S7 files (*.s7p) and other user-defined directories. - Automatically compresses and backs up projects on a configurable schedule (daily, hourly, 3-hour, 7-hour intervals, startup, or manual). - Supports manual backup triggers. - Skips projects with files in use and retries after one hour. - Maintains a two-stage hash system: first checking *.s7p files, then all files to avoid unnecessary backups. - User-friendly web interface built with Flask for configuration and status monitoring. - Comprehensive logging system with timestamped log files. ## Project Structure ``` ├── .logs/ # Application logs with startup timestamps ├── src │ ├── app.py # Main entry point of the Flask application │ ├── models │ │ └── __init__.py # Data models for configuration and directories │ ├── routes │ │ └── __init__.py # API routes for backup operations │ ├── services │ │ └── __init__.py # Business logic for backups │ └── utils │ └── __init__.py # Utility functions for hashing and file access ├── static │ ├── css # CSS files for styling │ └── js # JavaScript files for client-side functionality ├── templates │ └── index.html # Main HTML template for the web interface ├── config.json # Global configuration settings for the application ├── projects.json # Per-project configuration, schedules, and hash storage ├── requirements.txt # Python dependencies └── README.md # Project documentation ``` ## Installation 1. Clone the repository: ``` git clone cd autobackups ``` 2. Create a Miniconda environment: ``` conda create --name autobackups python=3.12 conda activate autobackups ``` 3. Install the required packages: ``` pip install -r requirements.txt ``` 4. Configure the application by editing `config.json` to specify directories to monitor and backup settings. ## Usage - Start the Flask application: ``` python src/app.py ``` - Access the web interface at `http://localhost:5120` to configure settings and monitor backup statuses. ## Contributing Contributions are welcome! Please submit a pull request or open an issue for any enhancements or bug fixes. ## License This project is licensed under the MIT License. See the LICENSE file for details. # AutoBackups - Especificación Técnica Detallada ## Resumen Ejecutivo AutoBackups es una aplicación Python que automatiza el backup de proyectos Simatic S7 y directorios definidos por el usuario, utilizando la API de Everything para búsqueda eficiente de archivos y un sistema de hash inteligente para evitar backups innecesarios. ## Arquitectura del Sistema ### 1. Componentes Principales #### 1.1 Motor de Búsqueda (Everything API) - **Librería**: PyEverything wrapper - **DLL Local**: `Everything-SDK\dll\Everything64.dll` - **Función**: Localizar archivos *.s7p en directorios de observación - **Optimización**: Evitar último nivel del árbol para archivos .s7p - **Ventaja**: Aprovecha el índice existente de Everything para búsquedas instantáneas #### 1.2 Sistema de Hash en Dos Etapas **Etapa 1**: Hash rápido de archivos *.s7p - Solo verifica MD5 de (timestamp + tamaño) de archivos .s7p - Si no hay cambios → no se procede con backup - Si hay cambios → procede a Etapa 2 **Etapa 2**: Hash completo del proyecto - Calcula MD5 de (timestamp + tamaño) de todos los archivos del directorio - Compara con último hash almacenado - Solo hace backup si hay diferencias #### 1.3 Scheduler de Background - **daily**: Una vez al día a hora configurada - **hourly**: Cada hora - **3-hour**: Cada 3 horas - **7-hour**: Cada 7 horas - **startup**: Al iniciar la aplicación - **manual**: Solo bajo demanda del usuario - **Escaneos**: Automáticos cada 1 hora - **Backups**: Mínimo cada 10 minutos - **Prioridad**: Baja prioridad de sistema ### 2. Estructura de Datos #### 2.1 config.json (Configuración Global) ```json { "observation_directories": [ { "path": "C:\\Projects\\Siemens", "type": "siemens_s7", "enabled": true, "description": "Directorio principal de proyectos Siemens" }, { "path": "D:\\Engineering\\Projects", "type": "siemens_s7", "enabled": true, "description": "Proyectos de ingeniería adicionales" }, { "path": "C:\\Important\\Documentation", "type": "manual", "enabled": true, "description": "Documentación importante para backup manual" } ], "backup_destination": "D:\\Backups\\AutoBackups", "global_settings": { "default_schedule": "daily", "default_schedule_time": "02:00", "retry_delay_hours": 1, "backup_timeout_minutes": 0, "min_free_space_mb": 100, "scan_interval_minutes": 60, "min_backup_interval_minutes": 10 }, "everything_api": { "dll_path": "Everything-SDK\\dll\\Everything64.dll", "enabled": true, "search_depth": -1, "skip_last_level_for_s7p": true }, "web_interface": { "host": "127.0.0.1", "port": 5000, "debug": false }, "logging": { "level": "INFO", "max_log_files": 30, "log_rotation_days": 30 }, "backup_options": { "compression_level": 6, "include_subdirectories": true, "preserve_directory_structure": true, "hash_algorithm": "md5", "hash_includes": ["timestamp", "size"], "backup_type": "complete", "process_priority": "low", "sequential_execution": true, "filename_format": "HH-MM-SS_projects.zip", "date_format": "YYYY-MM-DD" } } ``` #### 2.2 projects.json (Estado de Proyectos) ```json { "metadata": { "version": "1.0", "last_updated": "2025-09-01T08:30:15Z", "total_projects": 0 }, "projects": [ { "id": "example_project_001", "name": "PLC_MainLine_Example", "path": "C:\\Projects\\Siemens\\LineA\\Project1", "type": "siemens_s7", "s7p_file": "C:\\Projects\\Siemens\\LineA\\Project1\\project.s7p", "observation_directory": "C:\\Projects\\Siemens", "relative_path": "LineA\\Project1", "backup_path": "LineA\\Project1", "schedule_config": { "schedule": "daily", "schedule_time": "02:00", "enabled": true, "next_scheduled_backup": "2025-09-02T02:00:00Z" }, "backup_history": { "last_backup_date": "2025-09-01T02:15:30Z", "last_backup_file": "D:\\Backups\\AutoBackups\\LineA\\Project1\\2025-09-01\\02-15-30_projects.zip", "backup_count": 5, "last_successful_backup": "2025-09-01T02:15:30Z" }, "hash_info": { "last_s7p_hash": "abc123def456789", "last_full_hash": "def789ghi012345", "last_s7p_timestamp": "2025-08-31T14:30:00Z", "last_s7p_size": 2048576, "last_scan_timestamp": "2025-09-01T02:10:00Z", "file_count": 1247, "total_size_bytes": 125847296 }, "status": { "current_status": "ready", "last_error": null, "retry_count": 0, "next_retry": null, "files_in_use": false, "exclusivity_check_passed": true, "last_status_update": "2025-09-01T02:15:35Z" }, "discovery_info": { "discovered_date": "2025-09-01T08:30:15Z", "discovery_method": "everything_api", "auto_discovered": true } } ], "statistics": { "total_backups_created": 15, "total_backup_size_mb": 2450.5, "average_backup_time_seconds": 45.2, "last_global_scan": "2025-09-01T08:30:15Z", "projects_with_errors": 0, "projects_pending_retry": 0 } } ``` ### 3. Flujo de Operación #### 3.1 Inicio de Aplicación 1. Cargar configuración desde `config.json` 2. Cargar estado de proyectos desde `projects.json` 3. Inicializar logger con timestamp de inicio 4. Escanear directorios de observación usando Everything API 5. Actualizar lista de proyectos detectados 6. Iniciar scheduler 7. Iniciar interfaz web Flask #### 4.2 Proceso de Backup 1. **Verificación de Espacio**: Verificar mínimo 100MB libres 2. **Verificación de Acceso .s7p**: Intentar comprimir solo archivo .s7p 3. **Hash Etapa 1**: Verificar MD5 de (timestamp + tamaño) del archivo .s7p 4. **Hash Etapa 2**: Si Etapa 1 detecta cambios, verificar hash completo 5. **Compresión**: Crear archivo ZIP con estructura específica preservada 6. **Almacenamiento**: Guardar en `backup_destination/ProjectPath/YYYY-MM-DD/HH-MM-SS_projects.zip` 7. **Actualización**: Actualizar hashes y timestamps en `projects.json` #### 3.3 Gestión de Errores - **Archivos en uso**: Marcar proyecto para reintento en 1 hora - **Errores de permisos**: Log de error y notificación en interfaz - **Errores de espacio**: Verificar espacio disponible antes de backup ### 4. Interfaz Web #### 4.1 Dashboard Principal - **Lista de Proyectos**: Tabla con estado, último backup, próximo backup - **Controles Globales**: Backup manual global, pausar/reanudar scheduler - **Estadísticas**: Total de proyectos, backups exitosos, errores #### 4.2 Configuración de Proyectos - **Habilitación/Deshabilitación**: Toggle por proyecto - **Configuración de Schedule**: Dropdown con opciones de frecuencia - **Backup Manual**: Botón de backup inmediato por proyecto #### 4.3 Logs y Monitoreo - **Log Viewer**: Mostrar logs recientes con filtros por nivel - **Estado del Sistema**: Información de Everything API, espacio en disco ### 5. Estructura de Backup #### 5.1 Nomenclatura de Archivos (Estructura Específica) ``` backup_destination/ ├── LineA/ │ └── Project1/ │ ├── 2025-09-01/ │ │ ├── 02-15-30_projects.zip │ │ └── 14-30-15_projects.zip │ └── 2025-09-02/ │ └── 02-15-45_projects.zip └── LineB/ └── Project2/ └── 2025-09-01/ └── 08-20-10_projects.zip ``` #### 5.2 Contenido del ZIP ``` 02-15-30_projects.zip └── LineA/ └── Project1/ ├── project.s7p ├── subfolder1/ └── subfolder2/ ``` ### 6. Tecnologías y Librerías #### 6.1 Python Core - **Python**: 3.12 - **Framework Web**: Flask - **Scheduler**: APScheduler - **Compresión**: zipfile (biblioteca estándar) #### 6.2 Librerías Específicas - **Everything API**: PyEverything wrapper con DLL local - **Hashing**: hashlib MD5 para (timestamp + tamaño) - **Config**: json (biblioteca estándar) - **Logging**: logging (biblioteca estándar) - **File Access Check**: Intento de compresión + verificación .s7p - **Process Priority**: pywin32 para baja prioridad - **Disk Space**: psutil para monitoreo de espacio libre #### 6.3 Frontend - **HTML/CSS/JavaScript**: Vanilla (sin React por simplicidad) - **AJAX**: Para comunicación con Flask API - **Bootstrap**: Para estilizado responsivo ### 7. Consideraciones de Seguridad #### 7.1 Acceso a Archivos - Verificación de permisos antes de backup - Manejo seguro de rutas para evitar path traversal - Logs de todos los accesos a archivos #### 7.2 Interfaz Web - Solo acceso local (127.0.0.1) - No autenticación requerida (uso local únicamente) - Validación de inputs en formularios ### 8. Logging y Monitoreo #### 8.1 Estructura de Logs ``` .logs/ ├── autobackups_2025-09-01_08-30-15.log ├── autobackups_2025-09-02_08-30-22.log └── ... ``` #### 8.2 Niveles de Log - **INFO**: Inicio/fin de backups, descubrimiento de proyectos - **WARNING**: Archivos en uso, reintentos - **ERROR**: Fallos de backup, errores de configuración - **DEBUG**: Detalles de hashes, operaciones de archivos ### 9. Instalación y Despliegue #### 9.1 Entorno Miniconda ```bash conda create --name autobackups python=3.12 conda activate autobackups pip install -r requirements.txt ``` #### 9.2 Ejecución - **Desarrollo**: `python src/app.py` - **Producción**: `pythonw.exe src/app.py` (sin consola) - **Como servicio**: Futuro enhancement con `python-windows-service` ### 10. Roadmap de Desarrollo #### Fase 1: Core Backend - [ ] Integración con Everything API - [ ] Sistema de hash en dos etapas - [ ] Motor de backup básico - [ ] Scheduler con APScheduler #### Fase 2: Interfaz Web - [ ] Dashboard básico con Flask - [ ] API REST para operaciones CRUD - [ ] Frontend con HTML/JS/Bootstrap #### Fase 3: Características Avanzadas - [ ] Logs web viewer - [ ] Configuración avanzada de directorios - [ ] Estadísticas y reportes #### Fase 4: Optimizaciones - [ ] Ejecución como servicio Windows - [ ] Notificaciones por email - [ ] Backup incremental Este documento será la base para el desarrollo del proyecto AutoBackups. # AutoBackups - Preguntas Técnicas Pendientes ## Preguntas Críticas para el Desarrollo ### 1. Everything API - Integración **Pregunta**: ¿Everything está instalado y funcionando en el sistema objetivo? **Impacto**: Si no está disponible, necesitaremos un método alternativo de búsqueda de archivos. **Opciones**: - Usar `python-everything` si Everything está disponible - Implementar búsqueda recursiva con `os.walk()` como fallback - Usar `pathlib` con `glob` patterns **Decisión necesaria**: ¿Podemos asumir que Everything estará disponible o necesitamos fallback? ### 2. Estructura de Backup - Clarificación de Rutas **Pregunta**: Si tenemos un archivo en `C:\Projects\Siemens\LineA\Project1\project.s7p`, ¿el backup debe ser? **Opción A**: ``` backup_destination/2025-09-01_14-30-15/Projects_Siemens_LineA_Project1.zip └── Projects/Siemens/LineA/Project1/... ``` **Opción B**: ``` backup_destination/2025-09-01_14-30-15/LineA_Project1.zip └── LineA/Project1/... ``` **Decisión necesaria**: ¿Qué estructura prefieres? ### 3. Configuración de Schedules - Granularidad **Pregunta**: ¿Los schedules deben ser configurables a nivel de: - Por directorio de observación (todos los proyectos de un directorio) - Por proyecto individual - Ambos (global con override por proyecto) **Decisión necesaria**: ¿Qué nivel de granularidad necesitas? ### 4. Hash de Archivos - Algoritmo y Almacenamiento **Pregunta**: Para el sistema de hash en dos etapas: - ¿Usamos MD5 (rápido) o SHA256 (más seguro) para los hashes? - ¿El hash incluye solo timestamp o también tamaño de archivo? - ¿Cómo manejamos archivos que se mueven dentro del proyecto? **Decisión necesaria**: ¿Qué balance entre velocidad y precisión prefieres? ### 5. Detección de Archivos en Uso - Método **Pregunta**: Para detectar archivos bloqueados, ¿prefieres: **Opción A**: Intentar abrir cada archivo en modo escritura exclusiva **Opción B**: Usar `lsof` (Linux) / `handle.exe` (Windows) para listar archivos abiertos **Opción C**: Solo verificar el archivo .s7p principal **Decisión necesaria**: ¿Qué método consideras más apropiado? ### 6. Manejo de Proyectos Grandes - Performance **Pregunta**: ¿Hay límites que debamos considerar? - Tamaño máximo de proyecto para backup - Tiempo máximo de backup - Número máximo de archivos por proyecto **Decisión necesaria**: ¿Necesitamos algún tipo de throttling o límites? ### 7. Configuración de Directorios - Recursividad **Pregunta**: Cuando especificamos un directorio de observación como `C:\Projects`, ¿debemos: - Buscar solo en subdirectorios inmediatos - Buscar recursivamente en toda la jerarquía - Permitir configurar la profundidad de búsqueda **Decisión necesaria**: ¿Qué comportamiento prefieres por defecto? ### 8. Backup Incremental vs Completo **Pregunta**: ¿Todos los backups deben ser completos o consideras backup incremental? - Backup completo: Todo el proyecto cada vez - Backup incremental: Solo archivos modificados **Decisión necesaria**: ¿Preferencia por simplicidad o eficiencia de espacio? ### 9. Web Interface - Características Específicas **Pregunta**: ¿Qué funcionalidades son prioritarias en la interfaz web? **Must-have**: - Lista de proyectos con estado - Trigger manual de backup - Ver logs básicos **Nice-to-have**: - Configurar schedules por proyecto - Ver progreso de backup en tiempo real - Estadísticas históricas - Configurar nuevos directorios **Decisión necesaria**: ¿Cuáles son must-have vs nice-to-have? ### 10. Error Handling - Estrategias de Recuperación **Pregunta**: ¿Cómo manejar errores específicos? - Espacio insuficiente en destino de backup - Pérdida de conexión con Everything - Corrupción de archivos de configuración - Falla durante compresión **Decisión necesaria**: ¿Qué nivel de robustez necesitas? ### 11. Startup Behavior - Inicialización **Pregunta**: Al iniciar la aplicación: - ¿Debe hacer un escaneo completo inmediatamente? - ¿Debe esperar al primer schedule programado? - ¿Debe permitir configurar el comportamiento de startup? **Decisión necesaria**: ¿Qué comportamiento prefieres al iniciar? ### 12. Multi-threading - Concurrencia **Pregunta**: ¿Los backups deben ejecutarse: - Secuencialmente (uno por vez) - En paralelo (múltiples simultáneos) - Con límite configurable de concurrencia **Decisión necesaria**: ¿Qué balance entre velocidad y recursos del sistema? ## Próximos Pasos Una vez que tengas respuestas a estas preguntas, podremos: 1. Finalizar el diseño técnico 2. Crear el `requirements.txt` definitivo 3. Comenzar con la implementación por fases 4. Definir el plan de testing ¿Podrías revisar estas preguntas y darme tus preferencias para cada una? Para ejecutar el programa se puede usar: 'conda activate autobackups ; python src/app.py'