2026-06-16 20:30:47 +03:00
2026-06-16 20:30:47 +03:00
2026-06-16 08:01:42 +03:00
2026-06-16 08:12:14 +03:00
2026-06-15 09:04:11 +03:00
2026-06-16 08:12:14 +03:00
2026-06-16 08:12:14 +03:00
2026-03-08 19:50:47 +03:00
2026-06-16 08:12:14 +03:00

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.

Project notes:

Features

  • Native desktop GUI built with Fyne.
  • Job storage in one clean YAML file.
  • App settings in a separate YAML file.
  • @every schedules and standard 5-field cron expressions.
  • Manual and scheduled command runs.
  • Per-run .log files with stdout/stderr.
  • Log cleanup by maximum file count and maximum age.
  • Global pause/resume for all job execution.
  • Windows tray support.
  • Version shown in the window title, Settings, and build artifact names.

Requirements

Common:

  • Go 1.22 or newer.

Windows:

  • MSYS2 with UCRT64 GCC in C:\msys64\ucrt64\bin.

Install these dependencies on Windows:

# 1. Install Go 1.22 or newer from https://go.dev/dl/.
#    The default installer path is C:\Program Files\Go.
go version

# 2. Install MSYS2 from https://www.msys2.org/.
#    Use the default installation path so UCRT64 tools are placed under
#    C:\msys64\ucrt64\bin.

# 3. Open "MSYS2 UCRT64" from the Start menu and install GCC plus windres.
pacman -Syu
pacman -S --needed mingw-w64-ucrt-x86_64-gcc mingw-w64-ucrt-x86_64-binutils

# 4. In PowerShell, check that the compiler is available where the build script
#    expects it. build-windows.bat prepends this directory automatically.
Test-Path C:\msys64\ucrt64\bin\gcc.exe
Test-Path C:\msys64\ucrt64\bin\windres.exe

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-<version>-windows-amd64.exe. The script changes
# to the repository root first, so double-clicking it from Explorer works. It
# also 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-0.2.4-windows-amd64.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-0.2.4-linux-amd64

Linux using Docker:

# Builds the Linux binary inside Docker using the versioned image tag
# gitea.mixdep.ru/mix/pysentry-builder:<version>. Useful from hosts or CI jobs
# 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-0.2.4-linux-amd64

Release build from Linux:

# Interactively choose Linux amd64, Linux arm64, Windows amd64, or all artifacts
# from one Linux/Docker workflow. The Dockerfile contains the builder
# environment; the build commands live in this script. Docker runs the build
# with the current user's UID/GID so dist/ files are not owned by root.
chmod +x ./scripts/build-release-linux.sh
./scripts/build-release-linux.sh

Non-interactive release builds can pass target names:

# Build only Linux arm64 and Windows amd64 artifacts.
./scripts/build-release-linux.sh linux-arm64 windows-amd64

The binaries are copied to:

# Linux artifact.
dist/linux/pysentry-0.2.4-linux-amd64

# Linux arm64 artifact.
dist/linux/pysentry-0.2.4-linux-arm64

# Windows artifact cross-compiled from Linux.
dist/windows/pysentry-0.2.4-windows-amd64.exe

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 the PySentry
# executable 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

# Start PySentry automatically when the current desktop user signs in.
start_on_login: false

# 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 1m'

    # 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

  1. Start PySentry.
  2. Use New job to create a command.
  3. Set Schedule, Command, optional Folder, and Enabled.
  4. Use Run now for a manual test run.
  5. Use Pause to disable one job.
  6. Use Pause all as a global stop switch.
  7. Open History to see whether a run was Manual, Schedule, or UI.
  8. Open Settings to change jobs_dir, logs_dir, and log cleanup limits. Use Browse to choose directories.

Changing jobs_dir saves the current job list to the new directory.

The Start on login setting shows an OK or Problem status next to the checkbox. Saving settings with the checkbox enabled rewrites the autostart entry using the current executable path.

Autostart

PySentry is a user desktop application, not a system daemon, so autostart should be configured per user.

Linux:

# PySentry writes an XDG Autostart desktop entry when Start on login is enabled.
# This is better for a GUI/tray application than a systemd user service because
# the desktop environment starts it inside the graphical user session.
# Saving the setting also removes the old ~/.config/systemd/user/pysentry.service
# unit if it was created by an earlier PySentry build.
~/.config/autostart/pysentry.desktop

[Desktop Entry]
Type=Application
Name=PySentry
Exec=/opt/pysentry/pysentry-0.2.4-linux-amd64
Terminal=false

Windows:

# PySentry writes an HKCU Run entry when Start on login is enabled. It needs no
# administrator rights and starts PySentry when the current user signs in. Task
# Scheduler remains a later option if delayed start or elevated tasks become
# necessary. Saving settings with the checkbox enabled rewrites this entry, so it
# repairs an old path after the executable was moved or renamed.
HKCU\Software\Microsoft\Windows\CurrentVersion\Run\PySentry

Project Layout

  • cmd/pysentry starts the desktop app.
  • src/gui contains the GUI.
  • src/core contains YAML storage, command execution, scheduling, and log cleanup.
  • assets contains app icons that are embedded into the application binary.
  • scripts contains build helpers.
  • docs contains architecture notes, the changelog, and the roadmap.

Build outputs are written to dist/. The old local bin/ directory is not used.

Dependencies

PySentry keeps the direct dependency list intentionally small:

The remaining entries in go.mod are indirect dependencies pulled by Fyne and the Go module resolver.

Source repositories for mirroring:

To list every direct and indirect Go module used by the current checkout:

go list -m all
S
Description
GoSentry is a cross-platform desktop scheduler inspired by cron
Readme MIT 3.7 MiB
Languages
Go 90.1%
Shell 6.2%
Batchfile 2.4%
Dockerfile 1.3%