add auto trig for api and send via telegram

This commit is contained in:
Your Name
2026-08-05 11:49:27 -04:00
parent bd92c7f899
commit d722842d20
19 changed files with 739 additions and 61 deletions
+25 -10
View File
@@ -30,7 +30,8 @@ Linux_post_install/
├── lib/
│ ├── common.sh # Shared library (colors, logging, spinner, timer, run)
── flags.sh # Feature flag store (flag_set/clear/is_set/value/list/status)
── flags.sh # Feature flag store (flag_set/clear/is_set/value/list/status)
│ └── entertainment-lib.sh # Entertainment module lib (ENABLED list, scheduler sync)
├── bin/ # CLI tools — installed to /usr/local/bin/
│ ├── pos # Main dispatcher — smart arg matching to pos-* scripts
@@ -40,7 +41,11 @@ Linux_post_install/
│ ├── pos-docker-health # One-glance container health dashboard (exits 1 if unhealthy)
│ ├── pos-docker-ps # Enhanced container overview (health, IPs, ports, uptime)
│ ├── pos-docker-vbox # Disposable Docker-based VMs (create/enter/start/stop/rm/ls)
│ ├── pos-entertainment-config # Show or edit the entertainment config (ENABLED auto-trigger list, weather location)
│ ├── pos-entertainment-disable # Disable a plugin's auto-trigger (remove it from ENABLED)
│ ├── pos-entertainment-enable # Enable an auto-trigger for a plugin (systemd user timer)
│ ├── pos-entertainment-send # Run a public-API plugin and send its output via Telegram (default sender)
│ ├── pos-entertainment-status # Show enabled plugins and their timer state
│ ├── pos-media-mp3 # Download audio as MP3 (yt-dlp)
│ ├── pos-media-mp4 # Download video as MP4 (interactive format select)
│ ├── pos-network-checkport # Check TCP port connectivity
@@ -62,9 +67,10 @@ Linux_post_install/
├── features/ # User-customizable scripts (installed via --feature)
│ └── autostart.sh # Boot-time script (via systemd, flag-gated)
├── entertainment/ # Public-API plugins for pos entertainment send (→ /usr/local/share/linux_post_install/entertainment)
├── entertainment/ # Public-API plugins for pos entertainment send (→ /usr/local/bin)
│ ├── weather.sh # Current weather via Open-Meteo (no API key)
── joke.sh # Random dad joke via icanhazdadjoke (no API key)
── joke.sh # Random dad joke via icanhazdadjoke (no API key)
│ └── gold.sh # Gold spot (XAU/USD) via goldprice.dev (no API key)
├── templates/ # Dev-only scaffolds — NOT installed by install.sh
│ ├── pos-tool.sh # New `pos` CLI tool (→ bin/pos-<cat>-<cmd>)
@@ -108,7 +114,7 @@ Linux_post_install/
├── config/
│ ├── authorized_keys # SSH public keys (gitignored)
│ └── entertainment.env # Default weather location (auto-installed by postinstall)
│ └── entertainment.env # Weather location template (auto-installed by postinstall)
├── compose/
│ └── scale-tail/ # Git submodule → ScaleTail templates (119+ services)
@@ -145,7 +151,7 @@ User runs: ./install.sh [--apps|--full|--feature|--dry-run|--skip <phase>|--step
├─ Phase 2: install.sh (requires root)
│ └─ Copies bin/* → /usr/local/bin/ (chmod 755)
│ └─ Copies lib/common.sh + lib/flags.sh → /usr/local/bin/ (chmod 644)
│ └─ Copies lib/common.sh + lib/flags.sh + lib/entertainment-lib.sh → /usr/local/bin/ (chmod 644)
│ └─ Copies x64_bin/* → /usr/local/bin/ on x86_64 (arm64_bin/ on aarch64)
│ └─ [if --feature] Copies features/* → /usr/local/bin/ (asks before overwriting),
│ then sets the matching feature flag
@@ -211,7 +217,11 @@ All non-interactive `pos` commands log output to `~/.local/share/linux_post_inst
| docker | health | `pos-docker-health` | One-glance container health dashboard (exits 1 if unhealthy) |
| docker | ps | `pos-docker-ps` | Enhanced container overview (health, IPs, ports, uptime) |
| docker | vbox | `pos-docker-vbox` | Disposable Docker-based VMs (create/enter/start/stop/rm/ls) |
| entertainment | config | `pos-entertainment-config` | Show or edit the entertainment config (ENABLED auto-trigger list, weather location) |
| entertainment | disable | `pos-entertainment-disable` | Disable a plugin's auto-trigger (remove it from ENABLED) |
| entertainment | enable | `pos-entertainment-enable` | Enable an auto-trigger for a plugin (systemd user timer) |
| entertainment | send | `pos-entertainment-send` | Run a public-API plugin and send its output via Telegram (default sender) |
| entertainment | status | `pos-entertainment-status` | Show enabled plugins and their timer state |
| media | mp3 | `pos-media-mp3` | Download audio as MP3 (yt-dlp) |
| media | mp4 | `pos-media-mp4` | Download video as MP4 (interactive format select) |
| network | checkport | `pos-network-checkport` | Check TCP port connectivity |
@@ -365,7 +375,7 @@ All `.service` files in `systemd/` are automatically copied to `/etc/systemd/sys
### Runtime Config
- `~/.config/linux_post_install/compose.env` — Docker Compose global defaults
- `~/.config/linux_post_install/entertainment.env` — entertainment plugin defaults (e.g. weather location); auto-installed from `config/entertainment.env` by `postinstall.sh` (no clobber)
- `~/.config/linux_post_install/entertainment.env` — entertainment plugin defaults: weather location + `ENABLED` auto-trigger list (`plugin, interval` pairs → systemd user timers via `pos entertainment enable/disable`); auto-installed from `config/entertainment.env` by `postinstall.sh` (no clobber, template printed)
- `~/.bashrc` — Modified by postinstall (PATH, bash completion)
### Feature Flags
@@ -470,21 +480,26 @@ Use conventional prefixes: `feat:`, `fix:`, `docs:`, `refactor:`, `chore:`
|------|-------|---------|
| `install.sh` | 192 | Main orchestrator — 4 phases with CLI flags, `--feature`, prebuilt arch bins |
| `preinstall.sh` | 54 | System packages + hotspot deps + yt-dlp + fail2ban |
| `postinstall.sh` | 114 | fail2ban config, PATH, bash completion, systemd (flag-gated) |
| `postinstall.sh` | 115 | fail2ban config, PATH, bash completion, systemd (flag-gated) |
| `lib/common.sh` | 121 | Shared library |
| `lib/flags.sh` | 60 | Feature flag store (set/clear/is_set/value/list/status) |
| `lib/entertainment-lib.sh` | 380 | Entertainment module lib (ENABLED parsing, scheduler sync) |
| `bin/flag-reader` | 58 | Inspect flags (list/status/`--raw`) |
| `bin/flag-set` | 21 | Set a flag (optionally with a value) |
| `bin/flag-clear` | 21 | Unset a flag |
| `features/autostart.sh` | 14 | Boot-time feature (moved from `bin/`, flag-gated service) |
<!-- GEN:START filetable -->
| `bin/pos` | 211 | CLI dispatcher with smart arg matching + logging + category help |
| `bin/pos` | 213 | CLI dispatcher with smart arg matching + logging + category help |
| `bin/pos-communication-telegram` | 150 | Send Telegram messages via Bot API (--send, test, config set) |
| `bin/pos-docker-compose` | 364 | Docker Compose service manager (ls/up/down/restart/logs/update/config) |
| `bin/pos-docker-health` | 110 | One-glance container health dashboard (exits 1 if unhealthy) |
| `bin/pos-docker-ps` | 128 | Enhanced container overview (health, IPs, ports, uptime) |
| `bin/pos-docker-vbox` | 157 | Disposable Docker-based VMs (create/enter/start/stop/rm/ls) |
| `bin/pos-entertainment-send` | 124 | Run a public-API plugin and send its output via Telegram (default sender) |
| `bin/pos-entertainment-config` | 64 | Show or edit the entertainment config (ENABLED auto-trigger list, weather location) |
| `bin/pos-entertainment-disable` | 32 | Disable a plugin's auto-trigger (remove it from ENABLED) |
| `bin/pos-entertainment-enable` | 49 | Enable an auto-trigger for a plugin (systemd user timer) |
| `bin/pos-entertainment-send` | 93 | Run a public-API plugin and send its output via Telegram (default sender) |
| `bin/pos-entertainment-status` | 55 | Show enabled plugins and their timer state |
| `bin/pos-media-mp3` | 35 | Download audio as MP3 (yt-dlp) |
| `bin/pos-media-mp4` | 38 | Download video as MP4 (interactive format select) |
| `bin/pos-network-checkport` | 45 | Check TCP port connectivity |
@@ -495,7 +510,7 @@ Use conventional prefixes: `feat:`, `fix:`, `docs:`, `refactor:`, `chore:`
| `bin/pos-system-backup` | 117 | Encrypted (AES-256) folder snapshots (tar + gpg) |
| `bin/pos-system-firewall` | 285 | Interactive UFW management |
| `bin/pos-usb-server` | 218 | USB Redirector server control (--ls, --share; prompts when args omitted) |
| `completions/pos.bash` | 150 | Dynamic bash completion |
| `completions/pos.bash` | 169 | Dynamic bash completion |
<!-- GEN:END filetable -->
| `apps/install.sh` | 171 | App install/uninstall picker/orchestrator |
+6 -5
View File
@@ -20,7 +20,7 @@ How this repo works, how to add features, and what to keep in mind when editing.
| Phase | Script | Responsibility |
|-------|--------|----------------|
| Pre | `preinstall.sh` | System packages, apt repos, global binaries (yt-dlp) |
| Install | `install.sh` | Copies `bin/*``/usr/local/bin/` (chmod 755), `lib/common.sh``/usr/local/bin/common.sh` |
| Install | `install.sh` | Copies `bin/*``/usr/local/bin/` (chmod 755), `lib/common.sh` + `lib/flags.sh` + `lib/entertainment-lib.sh``/usr/local/bin/` (chmod 644) |
| Post | `postinstall.sh` | User config (SSH keys, PATH, bash completion), systemd services |
Each phase is independent and runs only if the corresponding script exists.
@@ -31,9 +31,9 @@ Each phase is independent and runs only if the corresponding script exists.
|-----------|---------|-------------|
| `bin/` | Daily-use CLI tools and wrappers | `/usr/local/bin/` |
| `apps/<category>/` | Optional desktop app installers | run on demand |
| `lib/` | Shared library (`common.sh`) | sourced at build time |
| `lib/` | Shared libraries: `common.sh` (helpers), `flags.sh` (feature flags), `entertainment-lib.sh` (entertainment scheduling) | sourced at build time |
| `config/` | Gitignored user config files | `~/.config/<app>/` (via postinstall) |
| `entertainment/` | Public-API plugins for the entertainment module | `/usr/local/share/linux_post_install/entertainment` (via install.sh Phase 2) |
| `entertainment/` | Public-API plugins for the entertainment module | `/usr/local/bin` (via install.sh Phase 2) |
| `compose/` | ScaleTail templates (git submodule) | `/usr/local/share/linux_post_install/scale-tail` |
| `systemd/` | Systemd unit files | `/etc/systemd/system/` (via postinstall) |
@@ -179,15 +179,16 @@ make check # full self-consistency gate (syntax, exec bits, d
## Adding an Entertainment Plugin
The `entertainment` module routes public-API data to Telegram via the single runner `pos entertainment send <plugin>` (`bin/pos-entertainment-send`).
The `entertainment` module routes public-API data to Telegram via the single runner `pos entertainment send <plugin>` (`bin/pos-entertainment-send`). Auto-triggering is config-driven: `ENABLED` in `entertainment.env` holds `plugin, interval` pairs; the tools `pos entertainment config|enable|disable|status` (`bin/pos-entertainment-*`) reconcile the schedule. All shared logic (ENABLED parsing, interval→schedule mapping, scheduler sync) lives in `lib/entertainment-lib.sh` — sourced by the `pos-entertainment-*` tools (never by plugins). The scheduler is auto-detected: systemd user timers when a user systemd manager exists, otherwise a managed user crontab block.
### 1. Create the plugin
Drop an executable script in `entertainment/<name>.sh`:
Drop an executable script in `entertainment/<name>.sh` with a `# POS_PLUGIN: <name>` marker on line 3 (this is what makes it a plugin — the installed runner lists plugins by this marker, not by `.sh` files, since `/usr/local/bin` is shared with other tooling):
```bash
#!/usr/bin/env bash
set -euo pipefail
# POS_PLUGIN: myplugin
err() { echo "ERROR: $*" >&2; exit 1; }
command -v curl &>/dev/null || err "curl not found"
+29 -4
View File
@@ -215,8 +215,13 @@ The bot token is a secret — it is stored only in `~/.config/linux_post_install
| `pos entertainment send <plugin> [--print] [--markdown] [args…]` | Run the plugin, send its output to Telegram (silent) |
| `pos entertainment send <plugin> --print` | Print the output locally; do not send |
| `pos entertainment send <plugin> --markdown` | Send with `--parse-mode markdown` (via `pos communication telegram`) |
| `pos entertainment config` | Show the config file (`~/.config/linux_post_install/entertainment.env`) |
| `pos entertainment config set KEY=VALUE…` | Set keys (e.g. `ENABLED`, `WEATHER_LAT`) and re-sync timers |
| `pos entertainment enable <plugin> [interval]` | Add plugin to `ENABLED` + create/enable its systemd **user** timer |
| `pos entertainment disable <plugin>` | Remove plugin from `ENABLED` + disable/remove its timer |
| `pos entertainment status` | Enabled plugins + timer state + next fire time |
**Plugin lookup order:** `$ENTERTAINMENT_DIR` → repo `entertainment/``/usr/local/share/linux_post_install/entertainment/` (installed by `install.sh` Phase 2). A plugin name matches the file name with or without the `.sh` suffix.
**Plugin lookup order:** `$ENTERTAINMENT_DIR` → repo `entertainment/``/usr/local/bin/` (installed by `install.sh` Phase 2, beside the runner). A plugin name matches the file name with or without the `.sh` suffix.
Plugins:
@@ -224,12 +229,32 @@ Plugins:
|--------|-----------|--------|
| `weather` | Open-Meteo (no API key) | `~/.config/linux_post_install/entertainment.env`: `WEATHER_LAT`, `WEATHER_LON` (required), `WEATHER_CITY` (optional label) |
| `joke` | icanhazdadjoke.com (no API key) | None |
| `gold` | goldprice.dev (no API key, anonymous free tier) | None |
**Config auto-install:** `postinstall.sh` copies the repo's `config/entertainment.env` (default: Al-Hasakah, Syria) to `~/.config/linux_post_install/entertainment.env` on install — but only if you haven't already created your own (no clobber). Override the default by creating/editing that file.
**Config auto-install:** `postinstall.sh` copies the repo's `config/entertainment.env` (a commented template showing each key's syntax) to `~/.config/linux_post_install/entertainment.env` on install — but only if you haven't already created your own (no clobber), and prints the template so you can fill in your location. Fill in `WEATHER_LAT`/`WEATHER_LON` (and optionally `WEATHER_CITY`) to enable the weather plugin.
**Adding a plugin:** drop an executable script in `entertainment/` (e.g. `myfeed.sh`). It must be non-interactive and print the message to stdout; errors go to stderr (exit nonzero). If it needs coordinates/tokens, read them from `~/.config/linux_post_install/entertainment.env` (chmod 600, env precedence). No registration needed. Dependencies beyond `curl`/`jq` (both in `preinstall.sh` PACKAGES) should be guarded with `command -v … || exit 1`.
**Adding a plugin:** drop an executable script in `entertainment/` (e.g. `myfeed.sh`) with a `# POS_PLUGIN: <name>` marker on line 3 — the runner lists and validates plugins by this marker, so non-plugin `.sh` files in the shared `/usr/local/bin` are ignored. The plugin must be non-interactive and print the message to stdout; errors go to stderr (exit nonzero). If it needs coordinates/tokens, read them from `~/.config/linux_post_install/entertainment.env` (chmod 600, env precedence). No registration needed. Dependencies beyond `curl`/`jq` (both in `preinstall.sh` PACKAGES) should be guarded with `command -v … || exit 1`.
**Automation:** the runner is headless/timer-friendly — no TTY prompts, exit 0 on success / 1 on failure. A systemd timer (e.g. hourly) can call `pos entertainment send weather` directly. Note the config files live under the user's `$HOME`, so the timer must run as that user (a systemd **user** unit, or a system unit with `Environment=HOME=/home/<user>`).
**Automation (auto-trigger):** enable plugins on a schedule via the `ENABLED` key in the config — a comma-separated list of `plugin, interval` pairs:
```
ENABLED="weather, 5m gold, 1h joke, daily"
```
`pos entertainment enable <plugin> [interval]` appends/updates one entry and re-syncs; `pos entertainment disable <plugin>` removes it; `pos entertainment config set ENABLED="…"` replaces the whole list. The scheduler backend is auto-detected on each sync:
- **systemd** (when a user systemd manager is reachable): one **user timer** per enabled plugin (`~/.config/systemd/user/pos-entertainment-<plugin>.{service,timer}`), running `pos entertainment send <plugin>` as your user on that schedule (`OnCalendar` + `Persistent=true`). `pos entertainment enable` also tries `sudo loginctl enable-linger $USER` once so timers fire without login.
- **cron** (fallback when no systemd user manager, e.g. this dev box): a managed block in your user crontab (`# POS-ENTERTAINMENT-BEGIN``END`), one line per plugin. Cron runs as your user and fires without login.
Either way the job runs as you, so it reads your `$HOME` configs (weather location, Telegram token) natively — no `Environment=HOME=` hacks.
Intervals: `5m 10m 15m 30m 45m hourly 2h 6h 12h daily weekly`, or a raw `OnCalendar=…` spec (systemd mode only; cron mode uses the named intervals). Default when omitted: `daily`.
`pos entertainment status` shows the enabled plugins, the detected scheduler, and each plugin's interval + next/next-ish fire time (`systemctl --user list-timers` or the crontab block).
Notes:
- The runner is headless/timer-friendly — no TTY prompts, exit 0 on success / 1 on failure.
- Scheduling is per-user for the user who runs `enable`; if you manage a different machine's user (e.g. via `runuser`/`sudo -u`), run the `enable`/`disable` commands as that user.
### flags
+1 -1
View File
@@ -4,7 +4,7 @@ Everything in this folder is reference material for the `Linux_post_install` pro
| Document | What it covers |
|----------|----------------|
| [SCRIPTS.md](SCRIPTS.md) | Core installer scripts: `install.sh`, `preinstall.sh`, `postinstall.sh`, `lib/common.sh`, `lib/flags.sh`, `features/autostart.sh` — purpose, how each works, configuration |
| [SCRIPTS.md](SCRIPTS.md) | Core installer scripts: `install.sh`, `preinstall.sh`, `postinstall.sh`, `lib/common.sh`, `lib/flags.sh`, `lib/entertainment-lib.sh`, `features/autostart.sh` — purpose, how each works, configuration |
| [POS.md](POS.md) | The `pos` CLI: dispatcher, every `pos-*` command, Docker Compose / ScaleTail config, legacy wrappers, flag CLIs |
| [APPS.md](APPS.md) | Optional apps: `apps/install.sh` picker, installer conventions, full app catalog |
| [SYSTEMD.md](SYSTEMD.md) | Systemd units (`autostart.service`, `ssh-agent.service`), feature-flag gating, bash completion |
+10 -1
View File
@@ -36,7 +36,7 @@ The phases:
| # | Phase | Script/action |
|---|-------|----------------|
| 1 | preinstall | `preinstall.sh` — apt packages + yt-dlp |
| 2 | scripts | Copies `bin/*``/usr/local/bin/` (755), `lib/common.sh` + `lib/flags.sh``/usr/local/bin/` (644). Copies precompiled arch binaries from `x64_bin/` (or `arm64_bin/`) → `/usr/local/bin/`. With `--feature`: also installs `features/*` (see below) |
| 2 | scripts | Copies `bin/*``/usr/local/bin/` (755), `lib/common.sh` + `lib/flags.sh` + `lib/entertainment-lib.sh``/usr/local/bin/` (644). Copies precompiled arch binaries from `x64_bin/` (or `arm64_bin/`) → `/usr/local/bin/`. With `--feature`: also installs `features/*` (see below) |
| 3 | postinstall | `postinstall.sh` — PATH, completion, SSH keys, systemd |
| 4 | scalepoint | Shallow-clones ScaleTail templates to `/usr/local/share/linux_post_install/scale-tail` |
| 5 (opt) | apps | `apps/install.sh` when `--apps` (interactive) or `--full` (all, non-interactive) |
@@ -172,6 +172,15 @@ flag_clear autostart
---
## lib/entertainment-lib.sh — entertainment module
**File:** `lib/entertainment-lib.sh` (installed to `/usr/local/bin/entertainment-lib.sh`)
**Purpose:** shared logic for the `pos entertainment` tools — config (`entertainment.env`), `ENABLED` auto-trigger list parsing (`plugin, interval` pairs), plugin lookup by `# POS_PLUGIN:` marker, interval→schedule mapping, and scheduler reconciliation (systemd **user** timers when a user manager is reachable, otherwise a managed user **crontab** block).
Sourced by `bin/pos-entertainment-send|config|enable|disable|status` (after `lib/common.sh`). **Plugins must not source it** — their stdout is the sent message.
---
## features/autostart.sh — boot-time feature
**File:** `features/autostart.sh` (installed to `/usr/local/bin/autostart.sh` by `./install.sh --feature`)