From 8825521945faa8eb5d18dfab880c4f49dc6c4223 Mon Sep 17 00:00:00 2001 From: Luke Berndt Date: Sat, 17 Oct 2026 15:33:28 -0400 Subject: [PATCH] 0.1.3: the system, site and talkgroup in a script's environment Trunk Recorder Pro's systems now have sites (trunk-recorder-plugin 0.4.0): a call heard on several is saved once, in the system's folder, its JSON saying the site it was kept from. Scripts get SHORT_NAME, SITE and TALKGROUP in their environment, so one that told sites apart by their short name or folder can still do it. Co-Authored-By: Claude Opus 5.5 --- CHANGELOG.md | 8 ++++++++ Cargo.lock | 6 +++--- Cargo.toml | 4 ++-- README.md | 9 ++++++++- src/main.rs | 16 +++++++++++++++- src/script.rs | 6 ++++-- 6 files changed, 40 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6482a9f..8bc6498 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## [0.1.3] + +- A system's sites: Trunk Recorder Pro now has systems with several sites, and a + call heard on more than one is saved once, in the system's folder. Scripts get + `SHORT_NAME`, `SITE` (the site the call was kept from) and `TALKGROUP` in + their environment, so one can tell sites apart without reading the JSON. +- Built with trunk-recorder-plugin 0.4.0. + ## [0.1.2] - A system can override the script and the time limit (a script set in the system's own settings still comes first). diff --git a/Cargo.lock b/Cargo.lock index 222b358..0950316 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -173,9 +173,9 @@ dependencies = [ [[package]] name = "trunk-recorder-plugin" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f6a3ae3954c34ae02ca4a347777d30481ec4f6b456c6adc7bbe59e8117751e" +checksum = "587edb957af1d5bd2cd1a8a0e362419d731d95b78e3ca4181a1494d0f8831753" dependencies = [ "schemars", "serde", @@ -190,7 +190,7 @@ checksum = "d245f478577f809a851594d02313b640fb437e0bb33866753cff937863096954" [[package]] name = "upload-script" -version = "0.1.2" +version = "0.1.3" dependencies = [ "schemars", "serde", diff --git a/Cargo.toml b/Cargo.toml index b2260fb..8fc8b5a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "upload-script" -version = "0.1.2" +version = "0.1.3" edition = "2024" description = "Runs a script of yours on each recorded call, as Trunk Recorder's uploadScript does." license = "GPL-3.0-or-later" @@ -9,7 +9,7 @@ authors = ["Luke Berndt "] publish = false [dependencies] -trunk-recorder-plugin = "0.3.0" +trunk-recorder-plugin = "0.4.0" schemars = "1" serde = { version = "1", features = ["derive"] } serde_json = "1" diff --git a/README.md b/README.md index a2090bc..dbbc168 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,11 @@ The M4A is there when the recorder has an M4A encoder (built into macOS; install [ffmpeg](https://ffmpeg.org) elsewhere). Without one, the third path is where it would be, and there's no file there. +In its environment: `SHORT_NAME` (the call's system), `SITE` (the site it was +kept from) and `TALKGROUP`, the same as in its JSON. A system can have several +sites, and a call heard on more than one is saved once, in the system's folder: +a script that told sites apart by their short name or folder can use `SITE`. + The script runs in the recorder's capture folder. ## When it fails @@ -51,7 +56,9 @@ are kept, and run again when it starts. (Trunk Recorder never retries.) Paste each system's `uploadScript` into its **Script** (or set one for all of them), with the script's full path in place of `./`. The arguments are the -same, in the same order. +same, in the same order. Trunk Recorder systems that are sites of one system +(`multiSite`) are one system here, with one script: it can tell them apart by +`SITE`. What becomes of the call's files afterwards is up to the recorder's `audioArchive`, `callLog` and `archiveFilesOnFailure` settings, as in Trunk diff --git a/src/main.rs b/src/main.rs index 4d55d25..629f2f1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -93,7 +93,10 @@ impl Plugin for UploadScript { }; // (Where it would be, as Trunk Recorder passes it, when it couldn't be made.) let m4a = call.files.m4a.clone().unwrap_or_else(|| call.files.wav.with_extension("m4a")); - script.run(&[&call.files.wav, &call.files.json, &m4a], &cwd, &log, &call.path) + // Which system, site and talkgroup, without reading the JSON (a system's sites share its folder). + let c = &call.call; + let env = [("SHORT_NAME", c.short_name.clone()), ("SITE", c.site.clone()), ("TALKGROUP", c.talkgroup.to_string())]; + script.run(&[&call.files.wav, &call.files.json, &m4a], &env, &cwd, &log, &call.path) }); Ok(UploadScript { queue }) } @@ -156,6 +159,17 @@ mod tests { assert_eq!(args.lines().collect::>(), want); } + /// A call heard on several sites of a system is its system's: the site it was kept from comes as SITE. + #[test] + fn the_system_site_and_talkgroup_in_its_environment() { + let dir = testing::temp_dir("upload-script"); + let s = script(&dir, "up.sh", r#"echo "$SHORT_NAME $SITE $TALKGROUP" > "$(dirname "$0")/env.txt""#); + let mut call = testing::call(&dir, "sys1", 101); + call.call.site = "south".into(); + testing::run::([hello(&dir, json!({ "script": s }), Value::Null), HostMessage::CallConcluded(call)]); + assert_eq!(std::fs::read_to_string(dir.join("env.txt")).unwrap(), "sys1 south 101\n"); + } + #[test] fn a_failing_script_says_why() { let dir = testing::temp_dir("upload-script"); diff --git a/src/script.rs b/src/script.rs index 1e9ccf0..659258b 100644 --- a/src/script.rs +++ b/src/script.rs @@ -56,10 +56,12 @@ impl Script { Ok(Script { program, args: words, timeout, text: text.to_string() }) } - /// Run it with `files` after its own arguments, in `cwd`; `call`: for the log. - pub fn run(&self, files: &[&Path], cwd: &Path, log: &Host, call: &str) -> Attempt { + /// Run it with `files` after its own arguments and `env` in its + /// environment, in `cwd`; `call`: for the log. + pub fn run(&self, files: &[&Path], env: &[(&str, String)], cwd: &Path, log: &Host, call: &str) -> Attempt { let mut c = Command::new(&self.program); c.args(&self.args).args(files).current_dir(cwd).stdin(Stdio::null()).stdout(Stdio::piped()).stderr(Stdio::piped()); + c.envs(env.iter().map(|(k, v)| (k, v))); // A group of its own, so what it starts can be stopped with it. #[cfg(unix)] std::os::unix::process::CommandExt::process_group(&mut c, 0);