Files
autoficher/deploy/autoficher.service
omar 5ba5710db2 feat: daemon con bot de Telegram, killswitch y servicio systemd
Pasa de un cron ciego a un servicio en segundo plano. El killswitch lo exige:
para poder cancelar un fichaje pendiente desde el movil tiene que haber un
proceso escuchando durante la espera.

- daemon: bucle propio que duerme exactamente hasta el siguiente evento, con
  precision de decimas. No usa JobQueue de PTB porque APScheduler 3.6 importa
  pkg_resources, que ya no existe en Python 3.13; ademas asi no se añade una
  dependencia. Recupera fichajes perdidos si el equipo estuvo apagado.
- bot: /hoy /saldo /plan /fichar /desfichar /off /on /pausa /reanudar /log.
  Los comandos se registran con setMyCommands para que salgan en el menu del
  chat. Solo atiende al chat_id configurado.
- killswitch: aviso 12 min antes con teclado inline (cancelar / +15 min /
  fichar ya).
- Google Calendar queda solo para ausencias personales; festivos y vacaciones
  salen del calendario de Timenet.
- deploy/autoficher.service: unidad de usuario endurecida (ProtectSystem
  strict, escritura solo en el propio directorio), Restart=always.
- requirements: python-telegram-bot >= 22. La 20.5 tiene un bug de __slots__
  en Updater que rompe el polling en Python 3.13.
- .gitignore: data/, *.db, .env, __pycache__ en cualquier nivel.

tools/test_daemon.py cubre con reloj simulado y sin red: plan, aviso previo,
fichaje a su hora, killswitch, retraso de 15 min, pausa, recuperacion tras
apagon, fallo de red y dia no laborable. 19 comprobaciones.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-24 18:51:46 +02:00

35 lines
857 B
Desktop File

[Unit]
Description=Autoficher - fichaje automatico en Timenet
After=network-online.target
Wants=network-online.target
# si entra en bucle de fallos, deja de reintentar en vez de martillear la API
StartLimitIntervalSec=600
StartLimitBurst=6
[Service]
Type=simple
WorkingDirectory=%h/autoficher
ExecStart=%h/autoficher/venv/bin/python3 %h/autoficher/autoficherd.py
EnvironmentFile=%h/autoficher/.env
Environment=PYTHONUNBUFFERED=1
Restart=always
RestartSec=30
# margen para cerrar sesion de Telegram y avisar antes de morir
TimeoutStopSec=30
KillSignal=SIGTERM
# endurecimiento: solo puede escribir en su propio directorio
NoNewPrivileges=yes
PrivateTmp=yes
ProtectSystem=strict
ReadWritePaths=%h/autoficher
ProtectKernelTunables=yes
ProtectControlGroups=yes
RestrictSUIDSGID=yes
RestrictRealtime=yes
LockPersonality=yes
[Install]
WantedBy=default.target