# 📜 Scripts y Servicios — napi

Copia de referencia de todos los scripts y unidades systemd desplegados en **zzz** (`qu3v3d0.tech`) y **aldebaran/anka4** para el sistema de retroalimentación a estudiantes.

---

## 🗂️ Inventario

| Fichero | Dónde vive | Descripción |
|:--------|:-----------|:------------|
| **`python-upload-watcher.sh`** | `zzz:/usr/local/bin/` | Watcher ASIR1 — detecta entregas SFTP en `/home/USER/python/`, agrupa por carpeta, notifica XMPP |
| **`nginx-user-config-watcher.sh`** | `zzz:/usr/local/bin/` | Watcher DDAW2 — valida y despliega `*.conf` de alumnos, analiza CSP, notifica XMPP |
| **`xmpp-notify.py`** | `zzz:/usr/local/bin/` | Bot XMPP one-shot (slixmpp) — envía mensaje a `jla@librebits.info` |
| **`python-upload-watcher.service`** | `zzz:/etc/systemd/system/` | Unit systemd para el watcher ASIR1 |
| **`nginx-user-config-watcher.service`** | `zzz:/etc/systemd/system/` | Unit systemd para el watcher DDAW2 |
| **`home-fenix-napi-data.mount`** | `aldebaran:~/.config/systemd/user/` | Mount sshfs `~/napi-data/` → `zzz:/var/www/napi/data/` (DDAW2) |
| **`home-fenix-napi-data2.mount`** | `aldebaran:~/.config/systemd/user/` | Mount sshfs `~/napi-data2/` → `zzz:/var/www/napi2/data/` (ASIR1) |

---

## 🐍 python-upload-watcher.sh (v7)

**Propósito:** Monitorizar las entregas de prácticas de Programación (ASIR1) subidas por SFTP.

### Características

- ✅ **Batching por carpeta** — Cuando un alumno sube `PRACTICA3.1/` con N ficheros, envía **un solo mensaje XMPP** con el listado completo (espera 10s de silencio)
- ♻️ **Re-entregas** — Si el alumno borra y re-sube la misma carpeta (<120s), etiqueta como "Re-entrega"
- 👤 **Nombre completo** — Notifica `[María Jara]` en vez de `[jara]` (mapa usuario → nombre en el script)
- 🪟 **Windows-safe** — Ignora `Thumbs.db`, `desktop.ini`, `.DS_Store`, `*.tmp`, `~$*`
- 🐍 **Python-safe** — Ignora `__pycache__/`, `*.pyc`, `*.pyo`
- 🛠️ **Dev-safe** — Ignora `.git/`, `.venv/`, `node_modules/`, `.idea/`, `.vscode/`
- 📁 **Iconos por tipo** — 🐍 `.py` · 📦 `.zip/.rar` · 📝 `.md` · 📄 `.txt` · 📕 `.pdf` · 📘 `.docx`

### Ejemplo de notificación XMPP

```
📁 [Andrés Barrios] Entrega ASIR1: PRACTICA3.1/ (4 ficheros)
  🐍 main.py (2048 bytes)
  🐍 utils.py (1024 bytes)
  📝 README.md (512 bytes)
  📄 requisitos.txt (128 bytes)
```

```
📁 [Andrés Barrios] ♻️ Re-entrega ASIR1: PRACTICA3.1/ (3 ficheros)
  🐍 main.py (2100 bytes)
  📝 README.md (600 bytes)
  📄 requisitos.txt (128 bytes)
```

### Eventos inotifywait monitorizados

| Evento | Acción |
|:-------|:-------|
| `CREATE` (directorio) | Abre batch, detecta re-entrega si fue borrado recientemente |
| `CREATE` (fichero) | Ignorado (esperamos `close_write`) |
| `CLOSE_WRITE` | Fichero completado → añade al batch o notifica individual |
| `MOVED_TO` | Fichero movido al directorio → igual que `close_write` |
| `DELETE` / `MOVED_FROM` | Registra borrado de carpeta (para detectar re-entregas) |

### Log

```bash
sudo tail -f /var/log/python-upload-watcher.log  # en zzz
```

---

## 🌐 nginx-user-config-watcher.sh (v3)

**Propósito:** Despliegue automático de configuraciones Nginx subidas por alumnos de DDAW2 via SFTP.

### Características

- ✅ **Validación de seguridad** — Verifica `server_name`, `root`, bloquea directivas peligrosas (`proxy_pass`, `include /`, etc.)
- 🔒 **Análisis CSP** — Revisa cabeceras `Content-Security-Policy`, detecta `unsafe-inline`, multiline, HTTPS
- 📛 **Nomenclatura** — Verifica patrón `mi-nginx[-SUFIJO].conf`
- 🌐 **Multi-sitio v3** — `mi-nginx-hextris.conf` → `USER-hextris.qu3v3d0.tech`
- 🗑️ **Undeploy** — Borrar el `.conf` via SFTP elimina el site de Nginx
- 💡 **Pistas humanizadas** — Traduce errores `nginx -t` a español comprensible

### Límites

- Máximo **4 sitios** por alumno
- Solo `.conf` dentro de `/home/USER/html/`

---

## 📨 xmpp-notify.py

Bot XMPP one-shot usando `slixmpp`. Envía un mensaje y desconecta.

```bash
/usr/local/bin/xmpp-notify.py "Mensaje de prueba"
```

- **JID:** `zzz@librebits.info`
- **Destinatario:** `jla@librebits.info`
- **Config:** `/etc/xmpp-notify.conf` (credenciales)

---

## ⚙️ Units systemd

### En zzz (system-level)

```bash
# Estado de los watchers
sudo systemctl status python-upload-watcher.service   # ASIR1
sudo systemctl status nginx-user-config-watcher.service  # DDAW2

# Reiniciar
sudo systemctl restart python-upload-watcher.service
sudo systemctl restart nginx-user-config-watcher.service
```

### En aldebaran/anka4 (user-level)

```bash
# Estado de los mounts sshfs
systemctl --user status home-fenix-napi\\x2ddata.mount   # DDAW2
systemctl --user status home-fenix-napi\\x2ddata2.mount  # ASIR1

# Montar/desmontar
systemctl --user start home-fenix-napi\\x2ddata2.mount
systemctl --user stop home-fenix-napi\\x2ddata2.mount
```

---

## 🏗️ Estructura de directorios en zzz

```
/var/www/napi/                  ← DDAW2
├── viewer.html
├── marked.min.js
├── twemoji.min.js
└── data/
    ├── anas/notas.md
    ├── pablo/notas.md
    └── ... (19 alumnos)

/var/www/napi2/                 ← ASIR1 (Programación)
├── viewer.html
├── marked.min.js
├── twemoji.min.js
└── data/
    ├── barja/notas.md
    ├── barrios/notas.md
    └── ... (21 alumnos)

/home/USER/python/              ← Entregas SFTP (ASIR1)
    ├── PRACTICA3.1/
    │   ├── main.py
    │   └── README.md
    └── fichero_suelto.py
```

---

## 📅 Historial de versiones

| Script | Versión | Fecha | Cambios |
|:-------|:--------|:------|:--------|
| `python-upload-watcher.sh` | **v7** | 2026-02-25 | Batching + re-entregas + Windows-safe + `__pycache__` filter + nombres completos |
| `nginx-user-config-watcher.sh` | **v3** | 2026-02-19 | Multi-sitio + undeploy + CSP analysis |
| `xmpp-notify.py` | **v1** | 2026-01-27 | Bot one-shot slixmpp |
