cuando termines y verifica que esté todo subido
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
#!/usr/bin/env bash
|
||||
# save_onlyoffice_file — fuerza el guardado (Ctrl+S) de un documento abierto en una
|
||||
# instancia de ONLYOFFICE Desktop Editors en Linux/X11 y confirma que el archivo se
|
||||
# escribio a disco observando el cambio de mtime.
|
||||
#
|
||||
# Para que existe: OnlyOffice mantiene los cambios en memoria hasta que el usuario
|
||||
# guarda. Cualquier proceso que regenere el .xlsx leyendo del disco (por ejemplo un
|
||||
# build que refresca hojas) perderia el trabajo manual no guardado. Esta funcion
|
||||
# vuelca ese trabajo a disco ANTES de tocar el archivo, de modo que el paso de
|
||||
# actualizacion pueda preservarlo. Es el primer paso del flujo seguro:
|
||||
# save_onlyoffice_file -> (actualizar el archivo) -> reload_onlyoffice_file
|
||||
#
|
||||
# La ventana se localiza por el basename del archivo (OnlyOffice titula la ventana
|
||||
# "<basename> — ONLYOFFICE"), igual que open_onlyoffice_file. Si no hay ventana
|
||||
# abierta para ese basename no hay nada que guardar: se devuelve status "no_window"
|
||||
# con exit 0 (el disco ya es la unica fuente de verdad).
|
||||
#
|
||||
# Funcion impura: envia eventos de teclado a X11 (xdotool) y lee el estado del
|
||||
# sistema de archivos. Imprime una linea JSON con el resultado a stdout.
|
||||
#
|
||||
# No usamos `set -e`: los pipelines de busqueda de ventanas (xdotool|head) pueden no
|
||||
# matchear y no deben abortar el script. Mantenemos -u y pipefail con guardas.
|
||||
set -uo pipefail
|
||||
|
||||
save_onlyoffice_file() {
|
||||
local file_path="${1:-}"
|
||||
local instance="${2:-demo}"
|
||||
|
||||
# --- 1. Validacion de dependencias del sistema ---
|
||||
local dep
|
||||
for dep in xdotool stat; do
|
||||
if ! command -v "$dep" >/dev/null 2>&1; then
|
||||
echo "error: dependencia ausente: '$dep' (instala xdotool, coreutils)" >&2
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
|
||||
# --- 2. Validacion de argumentos ---
|
||||
if [ -z "$file_path" ]; then
|
||||
echo "error: uso: save_onlyoffice_file <file_path> [instance]" >&2
|
||||
return 1
|
||||
fi
|
||||
if [ ! -f "$file_path" ]; then
|
||||
echo "error: el archivo no existe: '$file_path'" >&2
|
||||
return 1
|
||||
fi
|
||||
local abs_path
|
||||
abs_path="$(cd "$(dirname "$file_path")" && pwd)/$(basename "$file_path")"
|
||||
local base
|
||||
base="$(basename "$abs_path")"
|
||||
|
||||
# --- 3. Localizar la ventana de OnlyOffice por basename ---
|
||||
local wid=""
|
||||
wid="$(xdotool search --name "$base" 2>/dev/null | head -1 || true)"
|
||||
if [ -z "$wid" ]; then
|
||||
printf '{"instance":"%s","file":"%s","wid":null,"status":"no_window"}\n' \
|
||||
"$instance" "$abs_path"
|
||||
return 0
|
||||
fi
|
||||
local hex
|
||||
hex="$(printf '0x%08x' "$wid" 2>/dev/null || echo "$wid")"
|
||||
|
||||
# --- 4. mtime antes de guardar ---
|
||||
local mtime_before
|
||||
mtime_before="$(stat -c %Y "$abs_path" 2>/dev/null || echo 0)"
|
||||
|
||||
# --- 5. Enfocar la ventana y enviar Ctrl+S ---
|
||||
xdotool windowactivate --sync "$wid" >/dev/null 2>&1 || true
|
||||
xdotool key --clearmodifiers --window "$wid" ctrl+s >/dev/null 2>&1 || true
|
||||
|
||||
# --- 6. Esperar el guardado; auto-confirmar el dialogo de formato si aparece ---
|
||||
# OnlyOffice puede mostrar un dialogo modal ("mantener formato") al guardar. Si el
|
||||
# mtime no cambia en ~1.2s asumimos que hay un modal esperando y le enviamos Return:
|
||||
# acepta la opcion por defecto, que es mantener el formato actual del archivo. Si no
|
||||
# habia dialogo, el Return va al editor y solo mueve de celda (inofensivo: no altera
|
||||
# datos). El intento se repite mientras el guardado no se confirme.
|
||||
local mtime_after="$mtime_before" i=0 confirmed=0
|
||||
local max=27 # ~8s a 0.3s por iteracion
|
||||
until [ "$mtime_after" -gt "$mtime_before" ] || [ "$i" -ge "$max" ]; do
|
||||
read -r -t 0.3 _ </dev/null 2>/dev/null || true
|
||||
mtime_after="$(stat -c %Y "$abs_path" 2>/dev/null || echo "$mtime_before")"
|
||||
i=$((i + 1))
|
||||
# A partir de ~1.2s sin guardar, confirmar el dialogo modal con Return.
|
||||
if [ "$i" -ge 4 ] && [ "$mtime_after" -le "$mtime_before" ]; then
|
||||
local dlg
|
||||
dlg="$(xdotool getactivewindow 2>/dev/null || true)"
|
||||
if [ -n "$dlg" ]; then
|
||||
xdotool key --clearmodifiers --window "$dlg" Return >/dev/null 2>&1 || true
|
||||
confirmed=1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
local status="saved"
|
||||
if [ "$mtime_after" -le "$mtime_before" ]; then
|
||||
# Sin cambio de mtime: no habia nada pendiente que guardar.
|
||||
status="no_change"
|
||||
fi
|
||||
printf '{"instance":"%s","file":"%s","wid":"%s","status":"%s","dialog_confirmed":%s,"mtime_before":%s,"mtime_after":%s}\n' \
|
||||
"$instance" "$abs_path" "$hex" "$status" "$confirmed" "$mtime_before" "$mtime_after"
|
||||
return 0
|
||||
}
|
||||
|
||||
# Ejecutable directo: `bash save_onlyoffice_file.sh <file> [instance]`.
|
||||
if [ "${BASH_SOURCE[0]}" = "${0}" ]; then
|
||||
save_onlyoffice_file "$@"
|
||||
fi
|
||||
Reference in New Issue
Block a user