6.4 KiB
PySentry
PySentry is a cross-platform desktop scheduler inspired by cron. It provides a native GUI for creating, grouping, pausing, running, and monitoring scheduled shell commands.
PySentry is being designed and implemented with assistance from OpenAI Codex.
Features
- Native desktop GUI built with Fyne.
- Job storage in one clean YAML file.
- App settings in a separate YAML file.
@everyschedules and standard 5-field cron expressions.- Manual and scheduled command runs.
- Per-run
.logfiles with stdout/stderr. - Log cleanup by maximum file count and maximum age.
- Global pause/resume for all job execution.
- Windows tray support.
Requirements
Common:
- Go 1.22 or newer.
Windows:
- MSYS2 with UCRT64 GCC in
C:\msys64\ucrt64\bin.
Linux:
- A C compiler.
- Fyne native build dependencies, including OpenGL/X11 development packages.
On Debian/Ubuntu, the Linux dependencies are typically:
# Go builds the application, gcc is required by CGO/Fyne, and the OpenGL/X11
# development packages provide the native desktop headers used by Fyne.
sudo apt install golang gcc libgl1-mesa-dev xorg-dev
Build
Windows:
# Builds dist\windows\pysentry.exe. The script adds MSYS2 UCRT64 to PATH for
# this process only, embeds the Windows icon when windres is available, and uses
# the Windows GUI subsystem so no console window opens at startup.
.\scripts\build-windows.bat
The Windows build is created as a GUI application, so it does not open a terminal window.
The binary is written to:
# GUI executable produced by scripts\build-windows.bat.
dist\windows\pysentry.exe
Linux:
# Make the helper executable once, then build a linux/amd64 Fyne binary.
chmod +x ./scripts/build-linux.sh
./scripts/build-linux.sh
The binary is written to:
# Linux executable produced by scripts/build-linux.sh.
dist/linux/pysentry
Linux using Docker:
# Builds the same Linux binary inside Docker, useful from Windows hosts or CI
# where the native Linux/Fyne packages are not installed locally.
chmod +x ./scripts/build-linux-docker.sh
./scripts/build-linux-docker.sh
The binary is copied to:
# Linux executable copied out of the Docker build image.
dist\linux\pysentry
Run From Source
Windows:
# Fyne requires CGO on Windows. MSYS2 UCRT64 provides the C compiler and native
# libraries used by the desktop backend.
$env:Path = 'C:\msys64\ucrt64\bin;' + $env:Path
$env:CGO_ENABLED = '1'
# go run starts the app from source. Use scripts\build-windows.bat when you need
# a standalone .exe without a console window.
& 'C:\Program Files\Go\bin\go.exe' run ./cmd/pysentry
Linux:
# CGO must stay enabled because the Fyne GUI links against native Linux desktop
# libraries.
CGO_ENABLED=1 go run ./cmd/pysentry
Storage
PySentry creates its runtime files next to the executable by default.
pysentry.yaml stores application settings:
# Directory containing jobs.yaml. "." means "the folder where pysentry.exe lives";
# an absolute path can be used when jobs should live elsewhere.
jobs_dir: .
# Directory for per-run command output logs. Relative paths are resolved against
# the program folder, just like jobs_dir.
logs_dir: logs
# Keep at most this many .log files after cleanup. Newest logs are preserved.
max_log_files: 100
# Delete .log files older than this many days during cleanup.
max_log_age_days: 30
# Closing the window hides it to the tray instead of stopping the scheduler.
keep_running_in_tray: true
# Reserved for desktop failure notifications; the setting is stored now so the
# UI and config format do not need to change when notifications are wired fully.
notify_on_failure: true
jobs.yaml stores only job definitions:
jobs:
# A harmless sample job created on first run so the scheduler can be tested
# immediately. Runtime fields such as last run time, next run time, and command
# output are intentionally not stored here; they are displayed in the GUI and
# written to separate log files.
- id: 1
# Human-readable name shown in the jobs list and used in log file names.
name: Hello scheduler
# Optional grouping label. Omit it or leave it empty to put the job under
# the "No folder" filter.
folder: Examples
# Either @every with a Go duration, or a standard five-field cron expression.
schedule: '@every 10s'
# Command passed to the platform shell: cmd.exe /C on Windows, sh -c on Linux.
command: echo PySentry test job: scheduler is alive
# Disabled jobs remain in jobs.yaml but are skipped by the scheduler.
enabled: true
Command output is written to separate files under logs_dir. File names include the run timestamp and job name, for example:
# Format: YYYYMMDD-HHMMSS_<sanitized job name>.log
20260614-224306_Hello_scheduler.log
Schedules
Fast interval schedules:
# Go duration syntax after @every; useful for tests and simple intervals.
@every 10s
@every 5m
@every 1h30m
Standard 5-field cron schedules:
# Standard five-field cron: minute hour day-of-month month day-of-week.
*/5 * * * * every five minutes
0 2 * * * every day at 02:00
30 9 * * 1-5 weekdays at 09:30
Using The App
- Start PySentry.
- Use
New jobto create a command. - Set
Schedule,Command, optionalFolder, andEnabled. - Use
Run nowfor a manual test run. - Use
Pauseto disable one job. - Use
Pause allas a global stop switch. - Open
Historyto see whether a run wasManual,Schedule, orUI. - Open
Settingsto changejobs_dir,logs_dir, and log cleanup limits. UseBrowseto choose directories.
Changing jobs_dir saves the current job list to the new directory.
Project Layout
cmd/pysentrystarts the desktop app.src/guicontains the GUI.src/corecontains YAML storage, command execution, scheduling, and log cleanup.assetscontains app icons that are embedded into the application binary.scriptscontains build helpers.
Build outputs are written to dist/. The old local bin/ directory is not used.
Dependencies
PySentry keeps the direct dependency list intentionally small:
fyne.io/fyne/v2for the native GUI.github.com/robfig/cron/v3for cron schedule parsing.gopkg.in/yaml.v3for YAML settings and jobs.
The remaining entries in go.mod are indirect dependencies pulled by Fyne and the Go module resolver.