feat(shell): auto-commit con 31 cambios
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
#!/usr/bin/env bash
|
||||
# open_onlyoffice_file — abre un archivo en una INSTANCIA AISLADA de ONLYOFFICE
|
||||
# Desktop Editors (Linux/X11), sin perturbar la instancia personal del usuario.
|
||||
#
|
||||
# Funcion impura: lanza un proceso GUI, lee estado de ventanas (xdotool) y
|
||||
# escribe directorios en /tmp. Imprime una linea JSON con el resultado.
|
||||
#
|
||||
# Por que "instancia aislada": ONLYOFFICE Desktop es single-instance por
|
||||
# usuario — un segundo `onlyoffice-desktopeditors <file>` se reenvia a la
|
||||
# instancia viva y abre el archivo como PESTAÑA en su ventana. El lock
|
||||
# single-instance NO se rompe con XDG_CONFIG_HOME, pero SI se rompe lanzando
|
||||
# con HOME y XDG_RUNTIME_DIR propios. Por eso cada "slot" nombrado (instance)
|
||||
# usa su propio HOME/XDG_RUNTIME_DIR/XDG_CONFIG_HOME bajo /tmp.
|
||||
|
||||
# Sin -e: las busquedas de ventana (xdotool search) pueden no matchear y
|
||||
# devolver exit !=0; no deben abortar la funcion. -u y pipefail se mantienen.
|
||||
set -uo pipefail
|
||||
|
||||
open_onlyoffice_file() {
|
||||
local file_path="${1:-}"
|
||||
local instance="${2:-demo}"
|
||||
|
||||
if [[ -z "$file_path" ]]; then
|
||||
echo "open_onlyoffice_file: falta <file_path>" >&2
|
||||
echo "uso: open_onlyoffice_file <file_path> [instance]" >&2
|
||||
return 2
|
||||
fi
|
||||
|
||||
# 1. Dependencias del sistema.
|
||||
local dep
|
||||
for dep in onlyoffice-desktopeditors wmctrl xdotool; do
|
||||
if ! command -v "$dep" >/dev/null 2>&1; then
|
||||
echo "open_onlyoffice_file: falta dependencia '$dep' (instala el paquete correspondiente)" >&2
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
|
||||
# 2. El archivo DEBE existir — esta funcion no crea archivos.
|
||||
if [[ ! -f "$file_path" ]]; then
|
||||
echo "open_onlyoffice_file: el archivo no existe: $file_path (esta funcion no crea archivos)" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Ruta absoluta y basename para titular/buscar la ventana.
|
||||
local abs_path base
|
||||
abs_path=$(readlink -f -- "$file_path")
|
||||
base=$(basename -- "$abs_path")
|
||||
|
||||
# 3. Slot aislado: HOME/XDG_RUNTIME_DIR/XDG_CONFIG_HOME propios bajo /tmp.
|
||||
local oo_home="/tmp/oo_${instance}"
|
||||
local oo_run="/tmp/oo_${instance}_run"
|
||||
local oo_cfg="${oo_home}/.config"
|
||||
mkdir -p "$oo_home" "$oo_cfg" "$oo_run"
|
||||
chmod 700 "$oo_run" 2>/dev/null || true
|
||||
|
||||
# 4. Idempotencia: si ya hay ventana para ese basename, no relanzar.
|
||||
local existing_wid
|
||||
existing_wid=$(xdotool search --name -- "$base" 2>/dev/null | head -1 || true)
|
||||
if [[ -n "$existing_wid" ]]; then
|
||||
local wid_hex
|
||||
wid_hex=$(printf '0x%x' "$existing_wid" 2>/dev/null || echo "$existing_wid")
|
||||
printf '{"instance":"%s","file":"%s","wid":"%s","pid":null,"status":"open"}\n' \
|
||||
"$instance" "$abs_path" "$wid_hex"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# 5. Lanzar la instancia aislada con su env propio. setsid lo desacopla de
|
||||
# la terminal; redirige todo a un log del slot.
|
||||
env HOME="$oo_home" XDG_RUNTIME_DIR="$oo_run" XDG_CONFIG_HOME="$oo_cfg" \
|
||||
setsid onlyoffice-desktopeditors "$abs_path" \
|
||||
>"/tmp/oo_${instance}.log" 2>&1 </dev/null &
|
||||
local launch_pid=$!
|
||||
|
||||
# 6. Esperar la ventana por evento (NUNCA sleep en foreground).
|
||||
# ~25s con read -t 0.3 => ~83 iteraciones.
|
||||
local wid="" i=0 max=83
|
||||
while [[ $i -lt $max ]]; do
|
||||
wid=$(xdotool search --name -- "$base" 2>/dev/null | head -1 || true)
|
||||
[[ -n "$wid" ]] && break
|
||||
read -t 0.3 _ </dev/null 2>/dev/null || true
|
||||
i=$((i + 1))
|
||||
done
|
||||
|
||||
if [[ -z "$wid" ]]; then
|
||||
printf '{"instance":"%s","file":"%s","wid":null,"pid":%s,"status":"timeout"}\n' \
|
||||
"$instance" "$abs_path" "$launch_pid"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local wid_hex
|
||||
wid_hex=$(printf '0x%x' "$wid" 2>/dev/null || echo "$wid")
|
||||
# El pid del proceso real (DesktopEditors) puede diferir del launcher; el
|
||||
# launcher reexec/fork. Reportamos el pid del launcher (best-effort).
|
||||
printf '{"instance":"%s","file":"%s","wid":"%s","pid":%s,"status":"open"}\n' \
|
||||
"$instance" "$abs_path" "$wid_hex" "$launch_pid"
|
||||
return 0
|
||||
}
|
||||
|
||||
# Ejecutable directo: `bash open_onlyoffice_file.sh <file> [instance]`.
|
||||
# Sourceado: define la funcion sin ejecutarla.
|
||||
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||
open_onlyoffice_file "$@"
|
||||
fi
|
||||
Reference in New Issue
Block a user