feat: add entertainment module — public-API plugins (weather, joke) sent via Telegram by default (pos entertainment send)

This commit is contained in:
Your Name
2026-08-05 14:45:51 +00:00
parent e3762f4074
commit 2aaf5cff62
11 changed files with 330 additions and 7 deletions
+10 -3
View File
@@ -40,6 +40,7 @@ Linux_post_install/
│ ├── pos-docker-health # One-glance container health dashboard (exits 1 if unhealthy) │ ├── pos-docker-health # One-glance container health dashboard (exits 1 if unhealthy)
│ ├── pos-docker-ps # Enhanced container overview (health, IPs, ports, uptime) │ ├── pos-docker-ps # Enhanced container overview (health, IPs, ports, uptime)
│ ├── pos-docker-vbox # Disposable Docker-based VMs (create/enter/start/stop/rm/ls) │ ├── pos-docker-vbox # Disposable Docker-based VMs (create/enter/start/stop/rm/ls)
│ ├── pos-entertainment-send # Run a public-API plugin and send its output via Telegram (default sender)
│ ├── pos-media-mp3 # Download audio as MP3 (yt-dlp) │ ├── pos-media-mp3 # Download audio as MP3 (yt-dlp)
│ ├── pos-media-mp4 # Download video as MP4 (interactive format select) │ ├── pos-media-mp4 # Download video as MP4 (interactive format select)
│ ├── pos-network-checkport # Check TCP port connectivity │ ├── pos-network-checkport # Check TCP port connectivity
@@ -61,6 +62,10 @@ Linux_post_install/
├── features/ # User-customizable scripts (installed via --feature) ├── features/ # User-customizable scripts (installed via --feature)
│ └── autostart.sh # Boot-time script (via systemd, flag-gated) │ └── autostart.sh # Boot-time script (via systemd, flag-gated)
├── entertainment/ # Public-API plugins for pos entertainment send (→ /usr/local/share/linux_post_install/entertainment)
│ ├── weather.sh # Current weather via Open-Meteo (no API key)
│ └── joke.sh # Random dad joke via icanhazdadjoke (no API key)
├── templates/ # Dev-only scaffolds — NOT installed by install.sh ├── templates/ # Dev-only scaffolds — NOT installed by install.sh
│ ├── pos-tool.sh # New `pos` CLI tool (→ bin/pos-<cat>-<cmd>) │ ├── pos-tool.sh # New `pos` CLI tool (→ bin/pos-<cat>-<cmd>)
│ ├── app.sh # New optional app installer (→ apps/<cat>/<name>.sh) │ ├── app.sh # New optional app installer (→ apps/<cat>/<name>.sh)
@@ -205,6 +210,7 @@ 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 | 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 | 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) | | docker | vbox | `pos-docker-vbox` | Disposable Docker-based VMs (create/enter/start/stop/rm/ls) |
| entertainment | send | `pos-entertainment-send` | Run a public-API plugin and send its output via Telegram (default sender) |
| media | mp3 | `pos-media-mp3` | Download audio as MP3 (yt-dlp) | | media | mp3 | `pos-media-mp3` | Download audio as MP3 (yt-dlp) |
| media | mp4 | `pos-media-mp4` | Download video as MP4 (interactive format select) | | media | mp4 | `pos-media-mp4` | Download video as MP4 (interactive format select) |
| network | checkport | `pos-network-checkport` | Check TCP port connectivity | | network | checkport | `pos-network-checkport` | Check TCP port connectivity |
@@ -470,12 +476,13 @@ Use conventional prefixes: `feat:`, `fix:`, `docs:`, `refactor:`, `chore:`
| `bin/flag-clear` | 21 | Unset a flag | | `bin/flag-clear` | 21 | Unset a flag |
| `features/autostart.sh` | 14 | Boot-time feature (moved from `bin/`, flag-gated service) | | `features/autostart.sh` | 14 | Boot-time feature (moved from `bin/`, flag-gated service) |
<!-- GEN:START filetable --> <!-- GEN:START filetable -->
| `bin/pos` | 208 | CLI dispatcher with smart arg matching + logging + category help | | `bin/pos` | 211 | CLI dispatcher with smart arg matching + logging + category help |
| `bin/pos-communication-telegram` | 140 | Send Telegram messages via Bot API (--send, test, config set) | | `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-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-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-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-docker-vbox` | 157 | Disposable Docker-based VMs (create/enter/start/stop/rm/ls) |
| `bin/pos-entertainment-send` | 122 | Run a public-API plugin and send its output via Telegram (default sender) |
| `bin/pos-media-mp3` | 35 | Download audio as MP3 (yt-dlp) | | `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-media-mp4` | 38 | Download video as MP4 (interactive format select) |
| `bin/pos-network-checkport` | 45 | Check TCP port connectivity | | `bin/pos-network-checkport` | 45 | Check TCP port connectivity |
@@ -486,7 +493,7 @@ Use conventional prefixes: `feat:`, `fix:`, `docs:`, `refactor:`, `chore:`
| `bin/pos-system-backup` | 117 | Encrypted (AES-256) folder snapshots (tar + gpg) | | `bin/pos-system-backup` | 117 | Encrypted (AES-256) folder snapshots (tar + gpg) |
| `bin/pos-system-firewall` | 285 | Interactive UFW management | | `bin/pos-system-firewall` | 285 | Interactive UFW management |
| `bin/pos-usb-server` | 218 | USB Redirector server control (--ls, --share; prompts when args omitted) | | `bin/pos-usb-server` | 218 | USB Redirector server control (--ls, --share; prompts when args omitted) |
| `completions/pos.bash` | 146 | Dynamic bash completion | | `completions/pos.bash` | 150 | Dynamic bash completion |
<!-- GEN:END filetable --> <!-- GEN:END filetable -->
| `apps/install.sh` | 171 | App install/uninstall picker/orchestrator | | `apps/install.sh` | 171 | App install/uninstall picker/orchestrator |
+36
View File
@@ -33,6 +33,7 @@ Each phase is independent and runs only if the corresponding script exists.
| `apps/<category>/` | Optional desktop app installers | run on demand | | `apps/<category>/` | Optional desktop app installers | run on demand |
| `lib/` | Shared library (`common.sh`) | sourced at build time | | `lib/` | Shared library (`common.sh`) | sourced at build time |
| `config/` | Gitignored user config files | `~/.config/<app>/` (via postinstall) | | `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) |
| `compose/` | ScaleTail templates (git submodule) | `/usr/local/share/linux_post_install/scale-tail` | | `compose/` | ScaleTail templates (git submodule) | `/usr/local/share/linux_post_install/scale-tail` |
| `systemd/` | Systemd unit files | `/etc/systemd/system/` (via postinstall) | | `systemd/` | Systemd unit files | `/etc/systemd/system/` (via postinstall) |
@@ -176,6 +177,41 @@ 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`).
### 1. Create the plugin
Drop an executable script in `entertainment/<name>.sh`:
```bash
#!/usr/bin/env bash
set -euo pipefail
err() { echo "ERROR: $*" >&2; exit 1; }
command -v curl &>/dev/null || err "curl not found"
data="$(curl -fsS --max-time 20 https://api.example.com/foo)"
printf 'Title: %s\n' "$data"
```
**Contract:** plugins are **self-contained** — do **not** source `lib/common.sh`. Its `log`/`warn`/`ok` helpers print to **stdout**, and the runner captures stdout as the message to send (helper chatter would be sent to Telegram). All stdout is the message; errors go to stderr and exit nonzero. Plugins must be non-interactive (no prompts) — the module is designed for cron/systemd timers.
### 2. Config (if needed)
Read runtime values from `~/.config/linux_post_install/entertainment.env` (chmod 600, env precedence) — same pattern as `telegram.env`. Example: `weather.sh` uses `WEATHER_LAT`/`WEATHER_LON`.
### 3. Deps
`curl` and `jq` are already in `preinstall.sh` PACKAGES. Anything else: guard with `command -v … || err "…"` and, if apt-available, add to PACKAGES.
### 4. Done
Plugins are not `pos-*` tools, so `make gen`/`make check` don't scan them — verify with `bash -n entertainment/<name>.sh` and a live `pos entertainment send <name> --print` run. Document the plugin in `DOC/POS.md`'s entertainment plugin table.
---
## Adding an Optional App ## Adding an Optional App
Start from the template: `cp templates/app.sh apps/<category>/<name>.sh`. Start from the template: `cp templates/app.sh apps/<category>/<name>.sh`.
+26
View File
@@ -12,6 +12,7 @@
- [ssh](#ssh) - [ssh](#ssh)
- [usb](#usb) - [usb](#usb)
- [communication](#communication) - [communication](#communication)
- [entertainment](#entertainment)
- [flags](#flags) - [flags](#flags)
- [Legacy wrappers](#legacy-wrappers) - [Legacy wrappers](#legacy-wrappers)
@@ -203,6 +204,31 @@ Subcommands that need input prompt interactively when args are omitted.
The bot token is a secret — it is stored only in `~/.config/linux_post_install/telegram.env` and never in the repo. Requires network access to `api.telegram.org`. The bot token is a secret — it is stored only in `~/.config/linux_post_install/telegram.env` and never in the repo. Requires network access to `api.telegram.org`.
### entertainment
**File:** `bin/pos-entertainment-send`
**Purpose:** run a public-API plugin and send its output to Telegram by default. Plugins are standalone scripts in `entertainment/` that fetch a public API and **print the message to stdout** — that stdout is what gets sent.
| Command | Behavior |
|---------|----------|
| `pos entertainment send` | List available plugins + usage |
| `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`) |
**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.
Plugins:
| Plugin | Source API | Config |
|--------|-----------|--------|
| `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 |
**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`.
**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>`).
### flags ### flags
Feature-flag management CLIs (see [SCRIPTS.md → lib/flags.sh](SCRIPTS.md#libflagssh--feature-flags)): Feature-flag management CLIs (see [SCRIPTS.md → lib/flags.sh](SCRIPTS.md#libflagssh--feature-flags)):
+1 -1
View File
@@ -11,7 +11,7 @@ It is a **personal toolkit** — a bootstrap script, a unified `pos` CLI for eve
**What you get:** **What you get:**
- 25+ system packages installed automatically - 25+ system packages installed automatically
- The `pos` CLI: network, Docker (compose + vbox VMs), media, system, SSH, USB, and communication (Telegram) tools - The `pos` CLI: network, Docker (compose + vbox VMs), media, system, SSH, USB, communication (Telegram), and entertainment (public-API plugins → Telegram) tools
- Wi-Fi hotspot tools (`create_ap`, `wihotspot-gui`) via `pos network hotspot` - Wi-Fi hotspot tools (`create_ap`, `wihotspot-gui`) via `pos network hotspot`
- 15 optional desktop apps (VS Code, Brave, OBS, Tailscale, …) — pick what you want - 15 optional desktop apps (VS Code, Brave, OBS, Tailscale, …) — pick what you want
- 119+ self-hosted services with Tailscale access (Jellyfin, Home Assistant, …) - 119+ self-hosted services with Tailscale access (Jellyfin, Home Assistant, …)
+5 -2
View File
@@ -81,8 +81,8 @@ usage() {
cat <<EOF cat <<EOF
pos — Personal OS Toolkit pos — Personal OS Toolkit
A unified CLI for network, docker, media, system, A unified CLI for network, docker, media, system, SSH,
and SSH tools on Debian/Ubuntu. USB, communication, and entertainment tools on Debian/Ubuntu.
USAGE USAGE
pos <category> <command> [args] pos <category> <command> [args]
@@ -114,6 +114,9 @@ EXAMPLES
pos communication telegram --send "Backup done" pos communication telegram --send "Backup done"
Send a Telegram message Send a Telegram message
pos entertainment send weather Fetch Open-Meteo weather → Telegram
pos entertainment send joke --print Preview a joke locally (no send)
pos docker vbox create lab1 Create disposable Docker VM pos docker vbox create lab1 Create disposable Docker VM
pos docker vbox create lab1 --dir . Create VM using current directory pos docker vbox create lab1 --dir . Create VM using current directory
pos docker vbox enter lab1 Shell into a Docker VM pos docker vbox enter lab1 Shell into a Docker VM
+122
View File
@@ -0,0 +1,122 @@
#!/usr/bin/env bash
set -euo pipefail
# POS: entertainment send — Run a public-API plugin and send its output via Telegram (default sender)
# POS_FLAGS: --print --markdown
source "$(dirname "$0")/../lib/common.sh" 2>/dev/null || source "$(dirname "$0")/common.sh"
# ── Plugin directory lookup ─────────────────────────────────────
plugin_dir() {
if [ -n "${ENTERTAINMENT_DIR:-}" ]; then
echo "$ENTERTAINMENT_DIR"
elif [ -d "$(dirname "$0")/../entertainment" ]; then
echo "$(cd "$(dirname "$0")/../entertainment" && pwd)"
elif [ -d "/usr/local/share/linux_post_install/entertainment" ]; then
echo "/usr/local/share/linux_post_install/entertainment"
else
err "entertainment plugin dir not found (set ENTERTAINMENT_DIR)"
fi
}
list_plugins() {
local dir="$1" f
for f in "$dir"/*; do
[ -f "$f" ] && [ -x "$f" ] && echo "$(basename "$f")"
done
}
resolve_plugin() {
local dir="$1" name="$2" f
[ -n "$name" ] || err "No plugin given"
for f in "$dir/$name" "$dir/$name.sh"; do
if [ -f "$f" ] && [ -x "$f" ]; then
echo "$f"
return 0
fi
done
err "Plugin '$name' not found in $dir — try one of: $(list_plugins "$dir" | tr '\n' ' ')"
}
usage() {
local dir plugins
dir="$(plugin_dir 2>/dev/null)" || dir=""
if [ -n "$dir" ]; then
plugins="$(list_plugins "$dir" | sed 's/^/ /')"
else
plugins=" (plugin directory not found — set ENTERTAINMENT_DIR)"
fi
cat <<EOF
Usage: pos entertainment send <plugin> [--print] [--markdown] [plugin args...]
Run an entertainment plugin, capture its output, and send it via Telegram.
Plugins are scripts that fetch a public API and print the message to stdout —
that stdout is what gets sent.
Modes:
(default) Send the plugin output to Telegram (silent)
--print Print the output locally instead of sending
--markdown Send with Markdown parse_mode (via pos communication telegram)
Available plugins:
$plugins
Environment:
ENTERTAINMENT_DIR Override the plugin directory
Config (per plugin): ~/.config/linux_post_install/entertainment.env
Examples:
pos entertainment send weather
pos entertainment send weather --print
pos entertainment send joke --markdown
EOF
exit 0
}
case "${1:-}" in
-h|--help|"") usage ;;
esac
# ── Parse runner flags ──────────────────────────────────────────
PRINT=0
MARKDOWN=0
plugin_args=()
while [ $# -gt 0 ]; do
case "$1" in
--print) PRINT=1; shift ;;
--markdown) MARKDOWN=1; shift ;;
-h|--help) usage ;;
*) plugin_args+=("$1"); shift ;;
esac
done
[ ${#plugin_args[@]} -ge 1 ] || usage
plugin="${plugin_args[0]}"
unset 'plugin_args[0]'
# ── Run the plugin ──────────────────────────────────────────────
dir="$(plugin_dir)"
script="$(resolve_plugin "$dir" "$plugin")"
if ! output="$("$script" "$@")"; then
err "Plugin '$plugin' failed (exit $?)"
fi
[ -n "$output" ] || { warn "Plugin '$plugin' produced no output — nothing to send"; exit 0; }
# ── Route the output ────────────────────────────────────────────
if [ "$PRINT" -eq 1 ]; then
printf '%s\n' "$output"
exit 0
fi
telegram="$(dirname "$0")/pos-communication-telegram"
[ -x "$telegram" ] || telegram="$(command -v pos-communication-telegram 2>/dev/null || true)"
[ -n "$telegram" ] && [ -x "$telegram" ] || err "pos-communication-telegram not found next to this script"
if [ "$MARKDOWN" -eq 1 ]; then
exec "$telegram" --send "$output" --parse-mode markdown
else
exec "$telegram" --send "$output"
fi
+4
View File
@@ -4,6 +4,7 @@
# GEN:START posflags # GEN:START posflags
declare -A _pos_flags declare -A _pos_flags
_pos_flags[communication-telegram]="--send" _pos_flags[communication-telegram]="--send"
_pos_flags[entertainment-send]="--print --markdown"
_pos_flags[network-hotspot]="--foreground" _pos_flags[network-hotspot]="--foreground"
_pos_flags[system-backup]="--service" _pos_flags[system-backup]="--service"
_pos_flags[usb-server]="--ls --ls-shared --share --unshare --auto-share --callback --close-callback --auto-connect --disconnect --nickname --timeout --port --info --version" _pos_flags[usb-server]="--ls --ls-shared --share --unshare --auto-share --callback --close-callback --auto-connect --disconnect --nickname --timeout --port --info --version"
@@ -114,6 +115,9 @@ _pos() {
communication-telegram) communication-telegram)
_pos_complete_flags communication-telegram _pos_complete_flags communication-telegram
;; ;;
entertainment-send)
_pos_complete_flags entertainment-send
;;
network-hotspot) network-hotspot)
_pos_complete_flags network-hotspot _pos_complete_flags network-hotspot
;; ;;
+32
View File
@@ -0,0 +1,32 @@
#!/usr/bin/env bash
set -euo pipefail
# Entertainment plugin: random dad joke via icanhazdadjoke.com (no API key).
# Contract: stdout is the message sent by 'pos entertainment send joke'.
err() { echo "ERROR: $*" >&2; exit 1; }
case "${1:-}" in
-h|--help)
cat <<EOF
Usage: pos entertainment send joke
Random dad joke from icanhazdadjoke.com (no API key).
Example:
pos entertainment send joke --print
EOF
exit 0
;;
esac
command -v curl &>/dev/null || err "curl not found"
command -v jq &>/dev/null || err "jq not found"
if ! joke="$(curl -fsS --max-time 20 -H 'Accept: application/json' \
https://icanhazdadjoke.com/ | jq -r '.joke')"; then
err "Failed to fetch a joke from icanhazdadjoke.com"
fi
[ -n "$joke" ] || err "No joke received"
printf '%s\n' "$joke"
+83
View File
@@ -0,0 +1,83 @@
#!/usr/bin/env bash
set -euo pipefail
# Entertainment plugin: current weather via Open-Meteo (no API key).
# Contract: stdout is the message sent by 'pos entertainment send weather'.
err() { echo "ERROR: $*" >&2; exit 1; }
CONFIG_FILE="$HOME/.config/linux_post_install/entertainment.env"
load_config() {
[ -f "$CONFIG_FILE" ] || return 0
local k v
while IFS='=' read -r k v; do
[ -n "$k" ] || continue
case "$k" in
\#*) continue ;;
esac
v="${v%\"}"; v="${v#\"}"; v="${v%\'}"; v="${v#\'}"
if [ -z "${!k:-}" ]; then
export "$k"="$v"
fi
done < <(grep -E '^[A-Z_]+=' "$CONFIG_FILE" || true)
}
wmo_desc() {
case "$1" in
0) echo "clear sky" ;;
1) echo "mainly clear" ;;
2) echo "partly cloudy" ;;
3) echo "overcast" ;;
45|48) echo "fog" ;;
51|53|55) echo "drizzle" ;;
61|63|65) echo "rain" ;;
71|73|75) echo "snow" ;;
80|81|82) echo "rain showers" ;;
95|96|99) echo "thunderstorm" ;;
*) echo "weather code $1" ;;
esac
}
case "${1:-}" in
-h|--help)
cat <<EOF
Usage: pos entertainment send weather
Current weather via Open-Meteo (no API key).
Config: $CONFIG_FILE (chmod 600)
WEATHER_LAT, WEATHER_LON Required — coordinates
WEATHER_CITY Optional label (e.g. "Berlin")
Example:
WEATHER_LAT=52.52 WEATHER_LON=13.41 pos entertainment send weather --print
EOF
exit 0
;;
esac
command -v curl &>/dev/null || err "curl not found"
command -v jq &>/dev/null || err "jq not found"
load_config
[ -n "${WEATHER_LAT:-}" ] || err "WEATHER_LAT not set — add it to $CONFIG_FILE"
[ -n "${WEATHER_LON:-}" ] || err "WEATHER_LON not set — add it to $CONFIG_FILE"
label="${WEATHER_CITY:-$WEATHER_LAT,$WEATHER_LON}"
if ! json="$(curl -fsS --max-time 20 \
"https://api.open-meteo.com/v1/forecast?latitude=${WEATHER_LAT}&longitude=${WEATHER_LON}&current=temperature_2m,relative_humidity_2m,apparent_temperature,weather_code,wind_speed_10m")"; then
err "Failed to fetch weather from Open-Meteo"
fi
temp="$(jq -r '.current.temperature_2m' <<<"$json")"
feels="$(jq -r '.current.apparent_temperature' <<<"$json")"
humidity="$(jq -r '.current.relative_humidity_2m' <<<"$json")"
code="$(jq -r '.current.weather_code' <<<"$json")"
wind="$(jq -r '.current.wind_speed_10m' <<<"$json")"
unit_temp="$(jq -r '.current_units.temperature_2m' <<<"$json")"
unit_wind="$(jq -r '.current_units.wind_speed_10m' <<<"$json")"
printf 'Weather in %s: %s, %s%s (feels like %s%s), humidity %s%%, wind %s%s\n' \
"$label" "$(wmo_desc "$code")" "$temp" "$unit_temp" "$feels" "$unit_temp" "$humidity" "$wind" "$unit_wind"
+10
View File
@@ -114,6 +114,16 @@ if should_run 2 scripts; then
run sudo install -m 644 lib/common.sh /usr/local/bin/common.sh run sudo install -m 644 lib/common.sh /usr/local/bin/common.sh
run sudo install -m 644 lib/flags.sh /usr/local/bin/flags.sh run sudo install -m 644 lib/flags.sh /usr/local/bin/flags.sh
# ── Entertainment plugins ────────────────────────────────
run sudo mkdir -p /usr/local/share/linux_post_install/entertainment
pcount=0
for f in entertainment/*.sh; do
[ -f "$f" ] || continue
run sudo install -m 755 "$f" /usr/local/share/linux_post_install/entertainment/
pcount=$((pcount + 1))
done
ok "$pcount entertainment plugins -> /usr/local/share/linux_post_install/entertainment"
# ── Precompiled architecture binaries ───────────────────── # ── Precompiled architecture binaries ─────────────────────
# Manually-compiled binaries (not available on the internet), # Manually-compiled binaries (not available on the internet),
# copied straight into /usr/local/bin for the matching arch. # copied straight into /usr/local/bin for the matching arch.
+1 -1
View File
@@ -132,7 +132,7 @@ regen_block() {
regen_block "$ctx" tree regen_block "$ctx" tree
regen_block "$ctx" dispatch regen_block "$ctx" dispatch
regen_block "$ctx" selfcontained regen_block "$ctx" selfcontained
regen_block "$ctx" filetable
regen_block "$comp" posflags regen_block "$comp" posflags
regen_block "$ctx" filetable
echo "gen-docs: $mode OK" echo "gen-docs: $mode OK"