149 lines
5.4 KiB
Markdown
149 lines
5.4 KiB
Markdown
# **hledger** Discourse Plugin
|
|
|
|
[](https://gitea.kosmos.org/raucao/discourse-hledger/actions)
|
|
[](https://gitea.kosmos.org/raucao/discourse-hledger/releases)
|
|
|
|
Render [hledger](https://hledger.org) journal reports inside Discourse topics.
|
|
|
|
Put an hledger journal in a fenced `hledger` code block in a topic's first
|
|
post. The block is replaced by a dashboard with five reports, generated live
|
|
by the `hledger` command line tool:
|
|
|
|
- 📋 Accounts and balances (a full account tree, each name capitalized)
|
|
- ⚖️ Balance sheet (indented account tree under each section)
|
|
- 📈 Profit & loss / P&L (indented account tree under each section)
|
|
- 👥 Equity distribution (account tree with per-commodity shares from absolute
|
|
balances; contributed capital, not legal ownership)
|
|
- 🧾 Journal (a detailed transaction log: date, description and postings)
|
|
|
|
## Screenshots
|
|
|
|
Rendered from the [example journal](docs/example.journal):
|
|
|
|
| Accounts | P&L | Journal |
|
|
| - | - | - |
|
|
| [](docs/screenshots/accounts.png) | [](docs/screenshots/pnl.png) | [](docs/screenshots/journal.png) |
|
|
|
|
## Installation
|
|
|
|
The plugin requires the `hledger` executable on the server.
|
|
|
|
### Default Docker deployment
|
|
|
|
The recommended self-hosted setup runs Discourse in a container built from an
|
|
`app.yml` file ([install guide](https://github.com/discourse/discourse/blob/main/docs/INSTALL-cloud.md)).
|
|
Add the plugin and the `hledger` package to `/var/discourse/containers/app.yml`:
|
|
|
|
```yaml
|
|
hooks:
|
|
after_code:
|
|
- exec:
|
|
cd: $home/plugins
|
|
cmd:
|
|
- git clone https://gitea.kosmos.org/raucao/discourse-hledger.git
|
|
- exec:
|
|
cd: $home
|
|
cmd:
|
|
- apt-get update
|
|
- DEBIAN_FRONTEND=noninteractive apt-get install -y hledger
|
|
```
|
|
|
|
Then rebuild the container to apply the changes:
|
|
|
|
```sh
|
|
cd /var/discourse
|
|
./launcher rebuild app
|
|
```
|
|
|
|
The `after_code` hook runs on every rebuild, so the plugin and `hledger` stay
|
|
installed across rebuilds.
|
|
|
|
### Other installs
|
|
|
|
Follow the [plugin installation guide](https://meta.discourse.org/t/install-a-plugin/19157).
|
|
Install `hledger` with your package manager (for example
|
|
`apt-get install hledger`) and point the `hledger path` site setting at it if it
|
|
is not on the default `PATH`.
|
|
|
|
### Docker development environment
|
|
|
|
Inside the Discourse dev container, install the plugin's system dependencies
|
|
(hledger, Chromium and the Playwright browser used by the test suite) with:
|
|
|
|
```sh
|
|
docker exec -u root discourse_dev bash /src/plugins/discourse-hledger/bin/setup-dev
|
|
```
|
|
|
|
## How to use
|
|
|
|
1. Enable the plugin under `Admin > Settings > Plugins` (`hledger enabled`).
|
|
2. Add an hledger journal to the first post of a topic:
|
|
|
|
````
|
|
```hledger
|
|
2024-01-01 Opening balances
|
|
assets:bank:checking 1000.00 EUR
|
|
equity:alice -600.00 EUR
|
|
equity:bob -400.00 EUR
|
|
```
|
|
````
|
|
|
|
3. The code block is replaced by the report dashboard. Reports can be filtered
|
|
by a start and end date; the end date is inclusive.
|
|
|
|
Reports are generated on demand and cached per post revision, so editing the
|
|
journal refreshes them.
|
|
|
|
Account names can reference Discourse users: a path segment written as
|
|
`@username` (for example `equity:@alice`) is rendered as a mention link, with the
|
|
same profile card as mentions in posts. Only segments matching an existing user
|
|
are linked; anything else stays plain text.
|
|
|
|
## Security
|
|
|
|
Journals are untrusted input. The plugin runs `hledger` as an unprivileged
|
|
subprocess with a scrubbed environment, a private working directory, a hard
|
|
timeout, CPU, file-size and memory limits and an output cap, and it rejects
|
|
`include` directives so a journal cannot read arbitrary server files.
|
|
|
|
Defenses are layered: Discourse authorization, a per-IP rate limit and the
|
|
global rate limit, the journal size and line limits, the execution timeout, the
|
|
resource limits and the output cap.
|
|
|
|
For installations where untrusted users can create public topics, additionally
|
|
sandbox `hledger` at the OS or container level — for example a systemd unit with
|
|
`ProtectSystem=strict`, `ProtectHome=true`, `PrivateTmp=true`,
|
|
`NoNewPrivileges=true`, `RestrictAddressFamilies=AF_UNIX`, `MemoryMax=` and
|
|
`TasksMax=`, or a dedicated container runtime. Those controls are stronger than
|
|
in-process resource limits.
|
|
|
|
### Relevant settings
|
|
|
|
- `hledger max journal bytes` and `hledger max journal lines` limit the size of
|
|
an accepted journal.
|
|
- `hledger timeout seconds` limits the wall-clock time of each `hledger`
|
|
invocation.
|
|
- `hledger memory limit mb` caps the process memory (`0` disables it).
|
|
- `hledger max output bytes` caps the captured output.
|
|
- `hledger global rate limit per minute` throttles report generation across all
|
|
users (`0` disables it).
|
|
|
|
## Development
|
|
|
|
```sh
|
|
# Ruby specs (run `bin/setup-dev` first for the integration specs)
|
|
bin/rspec plugins/discourse-hledger/spec/lib plugins/discourse-hledger/spec/requests
|
|
bin/rspec plugins/discourse-hledger/spec/system
|
|
|
|
# Frontend tests
|
|
DISCOURSE_DISABLE_BROWSER_SANDBOX=1 bin/qunit plugins/discourse-hledger/test/javascripts
|
|
```
|
|
|
|
## License
|
|
|
|
MIT
|
|
|
|
## Contact
|
|
|
|
E-Mail, Chat, Social, Lightning: raucao@kosmos.org
|