diff --git a/CHANGELOG.md b/CHANGELOG.md index 26f2137..5cdeed6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ semantic versioning. ### Fixed +- Corrected the `[External_Data] repeater_prefix_api_url` comment, which claimed that + leaving it empty "disables prefix command functionality" (#70). Empty is the normal + setup: the prefix command answers from the bot's own database. The option only adds + an optional external dataset, and its JSON contract is now documented. - `message_stats.path` no longer reports another packet's route (#80). When RF correlation failed, `find_recent_rf_data` fell back to the most recent packet in the cache, and the caller attributed that packet's route to the message — which is how a @@ -52,6 +56,10 @@ semantic versioning. ### Added +- Documented installing with `pipx`, which sidesteps PEP 668 on Debian 12+, Ubuntu + 23.04+, Fedora and Arch (#222), including where `config.ini`, the database and + `local/` live — everything resolves relative to the config file's directory, so an + absolute `--config` is what makes a pipx install deterministic. - Migration 23: nullable `snr` / `rssi` columns on `observed_paths` for zero-hop advert rows. - `{cmd: [args]}` placeholders in `[Scheduled_Messages]`: a scheduled message diff --git a/config.ini.example b/config.ini.example index 36307e6..3e2ef4a 100644 --- a/config.ini.example +++ b/config.ini.example @@ -675,9 +675,19 @@ airnow_api_key = # Paid tier (14 EUR/year): 3-6 day forecast, 15-30 minute resolution forecast_solar_api_key = -# Repeater prefix API URL for prefix command -# Leave empty to disable prefix command functionality -# Configure your own regional API endpoint +# Optional external repeater-prefix API for the prefix command. +# +# LEAVE THIS EMPTY unless you run your own endpoint. Empty does NOT disable the +# prefix command: the bot answers from its own database of heard repeaters, which +# is the normal setup. The API only augments that with node counts from a wider +# regional dataset; location details still come from the local database. +# +# This dates from when the project fetched repeater data from map.w0z.is, which is +# defunct. There is no drop-in public replacement. To serve your own, return JSON: +# {"data": [{"prefix": "AB", "node_count": 3, "node_names": ["Node One", ...]}, ...]} +# Fetched with a plain GET, must answer HTTP 200 with that JSON, 10s timeout. +# "prefix" is upper-cased by the bot; "node_count" is an int; "node_names" a list. +# Responses are cached for repeater_prefix_cache_hours below. repeater_prefix_api_url = # Repeater prefix cache duration in hours diff --git a/docs/command-reference.md b/docs/command-reference.md index 44ce95e..2779238 100644 --- a/docs/command-reference.md +++ b/docs/command-reference.md @@ -780,6 +780,27 @@ prefix free - Last seen time - Location (if available) +**Data source:** By default the bot answers from its own database of repeaters it has +heard. No external service is required, and `[External_Data] repeater_prefix_api_url` +should be left **empty** — leaving it empty does not disable the command. + +Setting that option adds an optional external dataset on top: node counts come from the +API while names and locations still come from the local database. The setting dates from +when the project fetched data from `map.w0z.is`, which is defunct, and there is no +drop-in public replacement. To serve your own, answer a plain `GET` with HTTP 200 and: + +```json +{ + "data": [ + {"prefix": "AB", "node_count": 3, "node_names": ["Node One", "Node Two", "Node Three"]} + ] +} +``` + +`prefix` is upper-cased by the bot, `node_count` is an integer, and `node_names` is a +list of strings. The request times out after 10 seconds, and responses are cached for +`repeater_prefix_cache_hours` (default 1). + --- ### `stats` diff --git a/docs/installation.md b/docs/installation.md index d4d783d..5002e34 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -7,12 +7,55 @@ Choose how to run the bot: | **[Docker](docker.md)** | Containers, consistent environments, easy updates | | **[Service (systemd)](service-installation.md)** | Linux servers, run at boot, no containers | | **Debian package** | `make deb` in the repo — see [README](https://github.com/agessaman/meshcore-bot/blob/main/README.md) | +| **[pipx](#pipx)** | A single-user install with no repo checkout and no venv management | ## Requirements - **Python 3.10+** - MeshCore-compatible device (USB, BLE, or TCP) +## pipx + +`pipx` installs the `meshcore-bot` and `meshcore-viewer` console scripts into their own +isolated environment, which sidesteps PEP 668 (`externally-managed-environment`) on +Debian 12+, Ubuntu 23.04+, Fedora and Arch without you managing a virtualenv: + +```bash +pipx install "git+https://github.com/agessaman/meshcore-bot@v1.0.0" +``` + +Upgrade to a newer tag with `pipx install --force "git+https://github.com/agessaman/meshcore-bot@vX.Y.Z"`. + +### Where your data lives + +The bot has no fixed data directory. **Everything is resolved relative to the directory +containing your `config.ini`**, so that directory is effectively your install: + +| What | Default | Resolved against | +|------|---------|------------------| +| Config | `config.ini` | your working directory, unless you pass `--config` | +| Database | `meshcore_bot.db` (`[Bot] db_path`) | the config file's directory | +| Local plugins | `local/` (`[Bot] local_dir_path`) | the config file's directory | + +Because a bare `meshcore-bot` looks for `config.ini` in the *current* directory, running +it from somewhere else silently starts a different, empty install. **Pass an absolute +`--config` so it is unambiguous:** + +```bash +mkdir -p ~/.local/share/meshcore-bot +cd ~/.local/share/meshcore-bot +# put your config.ini here, then: +meshcore-bot --config ~/.local/share/meshcore-bot/config.ini +``` + +The database and `local/` are then created alongside that `config.ini` no matter where +you launch from. Absolute paths in `db_path` or `local_dir_path` are used as-is. + +For a systemd unit, set `WorkingDirectory=` to that directory and use the absolute +`--config` in `ExecStart=`. Note the [service installer](service-installation.md) is a +separate, self-contained path — it builds its own virtualenv under `/opt/meshcore-bot` +and does not use pipx. + ## Development setup See [Getting started](getting-started.md) for a quick development setup (run from the repo with `python meshcore_bot.py`).