Cargando tu progreso...
+ +diff --git a/PLAN.md b/PLAN.md new file mode 100644 index 0000000..4d9af12 --- /dev/null +++ b/PLAN.md @@ -0,0 +1,148 @@ +# Plan: Emacs Integration for napi — Remote File-Notify via TRAMP + +## Context + +Fénix wants **real-time awareness in Emacs** of student deliveries on zzz (qu3v3d0.tech). The GNU Emacs manual confirms that `file-notify-add-watch` works on **remote machines** via TRAMP — it runs `inotifywait` on the remote host through SSH and streams events back in real-time. No polling. + +This means: **no modifications to watcher scripts on zzz**, no reverse SSH tunnels, no Porthole/JSON-RPC. Pure Emacs, using built-in capabilities + a dedicated daemon. + +## Architecture + +``` +emacs --daemon=napi (local) + │ + ├── TRAMP SSH → zzz:/home/*/python/ (ASIR1 — 21 dirs) + │ └── inotifywait running on zzz (auto-started by TRAMP) + │ + ├── TRAMP SSH → zzz:/home/*/html/ (DDAW2 — 19 dirs) + │ └── inotifywait running on zzz (auto-started by TRAMP) + │ + └── On file event → forward notification to `water` daemon + ├── Desktop notification (D-Bus) + ├── Sound alert (paplay) + ├── *napi-log* buffer (persistent log) + └── Minibuffer message + +emacsclient --socket-name=napi --eval '(napi-dashboard)' ← interact +emacsclient --socket-name=water --eval '(napi-log)' ← view in main UI +``` + +## Prerequisites + +- `inotify-tools` installed on zzz (provides `inotifywait`) — **already present** (watchers use it) +- SSH key access from local → zzz — **already working** (`ssh fenix@qu3v3d0.tech`) +- Emacs 30.1 on local — **confirmed** + +## Implementation Steps + +### Step 1: Create `~/napi/emacs/napi.el` + +The core elisp package. ~200 lines. Key components: + +| Component | Purpose | +|:----------|:--------| +| `napi-watch-start` | Sets up TRAMP file-notify watches on all student dirs | +| `napi-watch-stop` | Removes all watches cleanly | +| `napi-notify` | Handles a file event: log + desktop notification + sound | +| `napi-log` | Interactive: open `*napi-log*` buffer | +| `napi-open-student` | Interactive: completing-read → open student dir/notas.md | +| `napi-dashboard` | Interactive: overview of all students + last delivery | +| `C-c n` prefix | Keybindings for all interactive commands | + +**Student name maps** (username → full name) embedded in elisp, mirroring watcher scripts. + +**TRAMP watch setup** — the core innovation: +```elisp +;; For each ASIR1 student: +(file-notify-add-watch + "/ssh:fenix@qu3v3d0.tech:/home/jara/python/" + '(change) + #'napi--handle-event) + +;; 40 watches total (21 ASIR1 + 19 DDAW2) +;; Each spawns a persistent inotifywait on zzz via SSH +``` + +**Event handler** filters noise (Thumbs.db, __pycache__, .tmp, etc.) and forwards clean notifications to `water` daemon via: +```elisp +(shell-command + "emacsclient --socket-name=water --eval '(napi--show-notification ...)' &") +``` + +**Reconnection**: TRAMP sends a `stopped` event when SSH drops. The handler auto-re-establishes the watch after a delay. + +### Step 2: Create systemd user unit for `napi` daemon + +File: `~/.config/systemd/user/emacs-napi.service` + +```ini +[Unit] +Description=Emacs daemon for napi student monitoring +After=network-online.target +Wants=network-online.target + +[Service] +Type=forking +ExecStart=/usr/bin/emacs --daemon=napi -l ~/napi/emacs/napi-init.el +ExecStop=/usr/bin/emacsclient --socket-name=napi --eval "(kill-emacs)" +Restart=on-failure +RestartSec=30 + +[Install] +WantedBy=default.target +``` + +### Step 3: Create `~/napi/emacs/napi-init.el` + +Minimal init file for the `napi` daemon (not the full `~/.emacs.d/init.el`): + +```elisp +;; Loaded ONLY by emacs --daemon=napi +(load "~/napi/emacs/napi.el") +(napi-watch-start) +(message "napi: watching %d student directories on zzz" napi--watch-count) +``` + +### Step 4: Also load `napi.el` in `water` daemon + +Add to `~/.emacs.d/init.el` (near line 1478, following `funciones-art.el` pattern): + +```elisp +(load "~/napi/emacs/napi.el") +``` + +This gives the `water` daemon the `napi-log`, `napi-dashboard`, `napi-open-student` commands and the `C-c n` keybindings — but **no watches** (those run in the `napi` daemon only). + +### Step 5: Verify `inotifywait` on zzz + +```bash +ssh fenix@qu3v3d0.tech "which inotifywait && inotifywait --help | head -1" +``` + +## Files to Create/Modify + +| File | Action | Location | +|:-----|:-------|:---------| +| `emacs/napi.el` | **CREATE** | `~/napi/emacs/napi.el` | +| `emacs/napi-init.el` | **CREATE** | `~/napi/emacs/napi-init.el` | +| `emacs-napi.service` | **CREATE** | `~/.config/systemd/user/emacs-napi.service` | +| `init.el` | **MODIFY** (1 line) | `~/.emacs.d/init.el` | + +**No modifications to zzz** — no watcher changes, no new SSH keys, no reverse tunnels. + +## Testing + +1. **Unit test** — load `napi.el` in `water`, call `(napi-notify ...)` manually +2. **TRAMP watch test** — single watch on one student dir, touch a file on zzz +3. **Full integration** — start `napi` daemon, simulate SFTP upload as student +4. **Stress test** — confirm 40 concurrent TRAMP watches are stable +5. **Reconnection** — kill SSH, verify watch auto-restores +6. **UI test** — `C-c n l` (log), `C-c n s` (student), `C-c n d` (dashboard) + +## Risk: 40 Concurrent SSH/inotifywait Processes + +Each `file-notify-add-watch` via TRAMP spawns a separate `inotifywait` process on zzz. 40 watches = 40 persistent SSH channels + 40 inotifywait processes. + +**Mitigation**: TRAMP reuses SSH connections (ControlMaster). So it's 1 SSH connection + 40 remote processes. The zzz server's `inotify` limit (`fs.inotify.max_user_watches`) is typically 65536 — 40 is nothing. + +**Fallback**: If 40 watches proves unstable, consolidate to 2 watches on parent dirs (`/home/` with recursive) + filter events by path. Or switch to the emacsclient-via-SSH approach (see FINDINGS.md). diff --git a/Screenshots/napi-sketch.jpg b/Screenshots/napi-sketch.jpg new file mode 100644 index 0000000..7f61d4a Binary files /dev/null and b/Screenshots/napi-sketch.jpg differ diff --git a/TASKS.org b/TASKS.org index ee3c26f..1020086 100644 --- a/TASKS.org +++ b/TASKS.org @@ -18,4 +18,37 @@ es decir, mencionar el/la autor/a de la entrega por ambos, nombre y apellido -* esto +* TODO Emacs packages using JSON-RPC o other kinda-API thing i could be using in a complementary way to streamline my interaction with the students via 'zzz' server where 'napi' is hosted / serving + + + --- + Emacs Packages Using JSON-RPC / Structured Protocols + + For napi/ Specifically (file-sync + notification) + + ┌──────────────────────────────────────────────────────────────────────────────────────────────┬──────────────────────────────────────────┬────────────────────────────────────────────────────────────────────┐ + │ Package │ What It Does │ napi Complement │ + ├──────────────────────────────────────────────────────────────────────────────────────────────┼──────────────────────────────────────────┼────────────────────────────────────────────────────────────────────┤ + │ https://github.com/legoscia/emacs-jabber │ XMPP client for Emacs │ Direct integration with your slixmpp notification system │ + ├──────────────────────────────────────────────────────────────────────────────────────────────┼──────────────────────────────────────────┼────────────────────────────────────────────────────────────────────┤ + │ https://www.gnu.org/software/emacs/manual/html_node/elisp/File-Notifications.html (built-in) │ inotify/kqueue file watching │ Watch ~/napi-data/ for student uploads natively in Emacs │ + ├──────────────────────────────────────────────────────────────────────────────────────────────┼──────────────────────────────────────────┼────────────────────────────────────────────────────────────────────┤ + │ https://github.com/jcaw/json-rpc-server.el + https://github.com/jcaw/porthole │ Expose Emacs functions via HTTP JSON-RPC │ Let external scripts (your inotify watchers) trigger Emacs actions │ + └──────────────────────────────────────────────────────────────────────────────────────────────┴──────────────────────────────────────────┴────────────────────────────────────────────────────────────────────┘ + +** Explore the idea (as referred on above's gnu.org manual - link) "Notifications on File Changes", which states : + +"Several operating systems support watching of filesystems for changes to files or their attributes. If configured +properly, Emacs links a respective library like inotify and others. These libraries enable watching of filesystems on the local machine. + +**It is also possible to watch filesystems on remote machines**, see Remote Files in The GNU Emacs Manual. This does not +depend on one of the libraries linked to Emacs. + +Since all these libraries emit different events upon notified file changes, Emacs provides a special library filenotify +which presents a unified interface to applications. Lisp programs that want to receive file notifications should always +use this library in preference to the native ones. [..] + + +the **bold** is mine ! ... + +*** Am i crazy saying that ~/napi could be running remotely, as long as a 'emacs -daemon=napi' which i could hook into an 'emacsclient' ? diff --git a/api.php b/api.php new file mode 100644 index 0000000..033508e --- /dev/null +++ b/api.php @@ -0,0 +1,56 @@ + Sistema KISS de seguimiento académico: Markdown + Basic Auth + PHP + Vanilla JS + +**Servidor:** qu3v3d0.tech | **Filosofía:** Unix + KISS + +--- + +## Qué hace este sistema + +``` +Profesor sube tabla-de-seguimiento.md + ↓ +Alumnos acceden con user/pass SFTP + ↓ +Cada alumno ve SOLO su progreso +``` + +--- + +## Paso 1: Crear htpasswd para Basic Auth + +```bash +# Generar archivo de passwords (password = username por defecto) +sudo touch /etc/nginx/.htpasswd_sftp + +for user in alumno{01..20}; do + echo "$user:$(openssl passwd -apr1 $user)" | \ + sudo tee -a /etc/nginx/.htpasswd_sftp > /dev/null +done + +# Permisos restrictivos +sudo chmod 640 /etc/nginx/.htpasswd_sftp +sudo chown root:www-data /etc/nginx/.htpasswd_sftp + +# Verificar +sudo cat /etc/nginx/.htpasswd_sftp +``` + +**✅ Verificación:** +``` +alumno01:$apr1$xyz$... +alumno02:$apr1$abc$... +... +``` + +--- + +## Paso 2: Crear estructura de directorios + +```bash +# Crear directorios +sudo mkdir -p /home/admin/html/dashboard/data + +# Permisos +sudo chown -R admin:www-data /home/admin/html/dashboard +sudo chmod 755 /home/admin/html/dashboard +sudo chmod 775 /home/admin/html/dashboard/data +``` + +**Estructura final:** +``` +/home/admin/html/dashboard/ +├── index.html # Cliente (vanilla JS + marked.js) +├── api.php # filtro por usuario +├── style.css # estilo minimalista +└── data/ + └── tabla-de-seguimiento.md +``` + +--- + +## Paso 3: Crear api.php + +```bash +sudo tee /home/admin/html/dashboard/api.php > /dev/null << 'EOF' + /dev/null << 'EOF' + + +
+ + +qu3v3d0.tech
+Cargando tu progreso...
+ +