# 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 a system tray integration for easy access and background operation.

## 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.
- **System tray integration** with options to open browser and close application.
- **Custom favicon** for both frontend and system tray.
- 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
│       └── system_tray.py    # System tray functionality
├── static
│   ├── css                   # CSS files for styling
│   ├── icons
│   │   └── favicon.png       # Application icon (used in web and system tray)
│   └── 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
├── launch_tray.py            # System tray launcher
├── launch_with_tray.bat      # Windows batch file for easy launching
├── 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

### Regular Mode
- Start the Flask application:
  ```
  python src/app.py
  ```
- Access the web interface at `http://localhost:5120` to configure settings and monitor backup statuses.

### System Tray Mode (Recommended)
- Start the application with system tray integration:
  ```
  python launch_tray.py
  ```
- Or use the Windows batch file:
  ```
  launch_with_tray.bat
  ```

#### System Tray Features:
- **Auto-start**: Application starts in the background with system tray icon
- **Quick Access**: Double-click the tray icon to open the web interface
- **Right-click Menu**:
  - "Open AutoBackups" - Opens the web interface in your default browser
  - "Status" - Shows application status (future feature)
  - "Exit" - Safely closes the application
- **Custom Icon**: Uses `static/icons/favicon.png` for both web interface and system tray
- **Silent Operation**: Application runs silently in the background

#### System Tray Requirements:
- Windows 10/11 (tested)
- Python packages: `pystray`, `pillow` (automatically installed)
- Valid favicon.png file in `static/icons/`

## 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'

