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.
Go to file
Miguel b5ec940868 Refactor project management and backup functionalities; add API tests and update configuration handling 2025-09-02 09:20:29 +02:00
.github Refactor project management and backup functionalities; add API tests and update configuration handling 2025-09-02 09:20:29 +02:00
Everything-SDK Definicion terminada 2025-09-01 14:39:44 +02:00
src Refactor project management and backup functionalities; add API tests and update configuration handling 2025-09-02 09:20:29 +02:00
static Primera version 2025-09-01 17:50:14 +02:00
templates Primera version 2025-09-01 17:50:14 +02:00
.gitignore Base 2025-09-01 12:23:16 +02:00
README.md Primera version 2025-09-01 17:50:14 +02:00
config.json Refactor project management and backup functionalities; add API tests and update configuration handling 2025-09-02 09:20:29 +02:00
projects.json Refactor project management and backup functionalities; add API tests and update configuration handling 2025-09-02 09:20:29 +02:00
requirements.txt Modificada directorio base del proyecto 2025-09-01 17:20:34 +02:00
test_api.py Refactor project management and backup functionalities; add API tests and update configuration handling 2025-09-02 09:20:29 +02:00
test_functions.py Refactor project management and backup functionalities; add API tests and update configuration handling 2025-09-02 09:20:29 +02:00
test_json.py Primera version 2025-09-01 17:50:14 +02:00
test_project_manager.py Primera version 2025-09-01 17:50:14 +02:00

README.md

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 <repository-url>
    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)

{
  "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)

{
  "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

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'