diff --git a/src/trx-client/src/remote_client.rs b/src/trx-client/src/remote_client.rs index aaf3312..b0a8edc 100644 --- a/src/trx-client/src/remote_client.rs +++ b/src/trx-client/src/remote_client.rs @@ -410,6 +410,7 @@ mod tests { initialized: true, server_callsign: Some("N0CALL".to_string()), server_version: Some("test".to_string()), + server_build_date: Some("2026-01-01".to_string()), server_latitude: None, server_longitude: None, pskreporter_status: Some("Disabled".to_string()), diff --git a/src/trx-client/trx-frontend/trx-frontend-http-json/src/server.rs b/src/trx-client/trx-frontend/trx-frontend-http-json/src/server.rs index 68f5ed8..b505268 100644 --- a/src/trx-client/trx-frontend/trx-frontend-http-json/src/server.rs +++ b/src/trx-client/trx-frontend/trx-frontend-http-json/src/server.rs @@ -333,6 +333,7 @@ mod tests { initialized: true, server_callsign: Some("N0CALL".to_string()), server_version: Some("test".to_string()), + server_build_date: Some("2026-01-01".to_string()), server_latitude: None, server_longitude: None, pskreporter_status: Some("Disabled".to_string()), diff --git a/src/trx-client/trx-frontend/trx-frontend-http/Cargo.toml b/src/trx-client/trx-frontend/trx-frontend-http/Cargo.toml index 75bc19a..1f7cacb 100644 --- a/src/trx-client/trx-frontend/trx-frontend-http/Cargo.toml +++ b/src/trx-client/trx-frontend/trx-frontend-http/Cargo.toml @@ -6,6 +6,7 @@ name = "trx-frontend-http" version = "0.1.0" edition = "2021" +build = "build.rs" [dependencies] trx-core = { path = "../../../trx-core" } diff --git a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/app.js b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/app.js index 4e9278a..a2c7d53 100644 --- a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/app.js +++ b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/app.js @@ -629,10 +629,19 @@ function setDisabled(disabled) { } let serverVersion = null; +let serverBuildDate = null; let serverCallsign = null; let serverLat = null; let serverLon = null; +function updateFooterBuildInfo() { + const serverEl = document.getElementById("footer-server-build"); + if (!serverEl) return; + const ver = serverVersion || "--"; + const build = serverBuildDate || "--"; + serverEl.textContent = `trx-server v${ver} ${build}`; +} + function updateTitle() { let title = rigName || "Rig"; if (serverCallsign) title = `${serverCallsign}'s ${title}`; @@ -643,10 +652,12 @@ function render(update) { if (!update) return; if (update.info && update.info.model) rigName = update.info.model; if (update.server_version) serverVersion = update.server_version; + if (update.server_build_date) serverBuildDate = update.server_build_date; if (update.server_callsign) serverCallsign = update.server_callsign; if (update.server_latitude != null) serverLat = update.server_latitude; if (update.server_longitude != null) serverLon = update.server_longitude; updateTitle(); + updateFooterBuildInfo(); initialized = !!update.initialized; if (!initialized) { diff --git a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/index.html b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/index.html index b936703..134dcc0 100644 --- a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/index.html +++ b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/index.html @@ -266,7 +266,11 @@ diff --git a/src/trx-client/trx-frontend/trx-frontend-http/build.rs b/src/trx-client/trx-frontend/trx-frontend-http/build.rs new file mode 100644 index 0000000..882c673 --- /dev/null +++ b/src/trx-client/trx-frontend/trx-frontend-http/build.rs @@ -0,0 +1,25 @@ +use std::time::{SystemTime, UNIX_EPOCH}; + +fn utc_ymd_from_unix_secs(secs: i64) -> (i32, u32, u32) { + let days = secs.div_euclid(86_400); + let z = days + 719_468; + let era = if z >= 0 { z } else { z - 146_096 } / 146_097; + let doe = z - era * 146_097; + let yoe = (doe - doe / 1_460 + doe / 36_524 - doe / 146_096) / 365; + let mut y = yoe + era * 400; + let doy = doe - (365 * yoe + yoe / 4 - yoe / 100); + let mp = (5 * doy + 2) / 153; + let d = doy - (153 * mp + 2) / 5 + 1; + let m = mp + if mp < 10 { 3 } else { -9 }; + y += if m <= 2 { 1 } else { 0 }; + (y as i32, m as u32, d as u32) +} + +fn main() { + let secs = match SystemTime::now().duration_since(UNIX_EPOCH) { + Ok(d) => d.as_secs() as i64, + Err(_) => 0, + }; + let (y, m, d) = utc_ymd_from_unix_secs(secs); + println!("cargo:rustc-env=TRX_CLIENT_BUILD_DATE={y:04}-{m:02}-{d:02}"); +} diff --git a/src/trx-client/trx-frontend/trx-frontend-http/src/api.rs b/src/trx-client/trx-frontend/trx-frontend-http/src/api.rs index c489fea..818c607 100644 --- a/src/trx-client/trx-frontend/trx-frontend-http/src/api.rs +++ b/src/trx-client/trx-frontend/trx-frontend-http/src/api.rs @@ -625,6 +625,7 @@ async fn wait_for_view(mut rx: watch::Receiver) -> Result String { INDEX_HTML .replace("{pkg}", PKG_NAME) .replace("{ver}", PKG_VERSION) + .replace("{client_build_date}", CLIENT_BUILD_DATE) } diff --git a/src/trx-client/trx-frontend/trx-frontend-rigctl/src/server.rs b/src/trx-client/trx-frontend/trx-frontend-rigctl/src/server.rs index 3d8af41..b1e6a00 100644 --- a/src/trx-client/trx-frontend/trx-frontend-rigctl/src/server.rs +++ b/src/trx-client/trx-frontend/trx-frontend-rigctl/src/server.rs @@ -657,6 +657,7 @@ mod tests { initialized: true, server_callsign: None, server_version: None, + server_build_date: None, server_latitude: None, server_longitude: None, pskreporter_status: None, diff --git a/src/trx-core/src/rig/state.rs b/src/trx-core/src/rig/state.rs index 6422235..709f26f 100644 --- a/src/trx-core/src/rig/state.rs +++ b/src/trx-core/src/rig/state.rs @@ -21,6 +21,8 @@ pub struct RigState { #[serde(default, skip_serializing_if = "Option::is_none")] pub server_version: Option, #[serde(default, skip_serializing_if = "Option::is_none")] + pub server_build_date: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] pub server_latitude: Option, #[serde(default, skip_serializing_if = "Option::is_none")] pub server_longitude: Option, @@ -114,6 +116,7 @@ impl RigState { control: RigControl::default(), server_callsign: None, server_version: None, + server_build_date: None, server_latitude: None, server_longitude: None, pskreporter_status: None, @@ -135,6 +138,7 @@ impl RigState { pub fn new_with_metadata( callsign: Option, version: Option, + build_date: Option, latitude: Option, longitude: Option, initial_freq_hz: u64, @@ -143,6 +147,7 @@ impl RigState { let mut state = Self::new_uninitialized(); state.server_callsign = callsign; state.server_version = version; + state.server_build_date = build_date; state.server_latitude = latitude; state.server_longitude = longitude; state.status.freq = Freq { @@ -170,6 +175,7 @@ impl RigState { }, server_callsign: snapshot.server_callsign, server_version: snapshot.server_version, + server_build_date: snapshot.server_build_date, server_latitude: snapshot.server_latitude, server_longitude: snapshot.server_longitude, pskreporter_status: snapshot.pskreporter_status, @@ -206,6 +212,7 @@ impl RigState { initialized: self.initialized, server_callsign: self.server_callsign.clone(), server_version: self.server_version.clone(), + server_build_date: self.server_build_date.clone(), server_latitude: self.server_latitude, server_longitude: self.server_longitude, pskreporter_status: self.pskreporter_status.clone(), @@ -255,6 +262,8 @@ pub struct RigSnapshot { #[serde(default, skip_serializing_if = "Option::is_none")] pub server_version: Option, #[serde(default, skip_serializing_if = "Option::is_none")] + pub server_build_date: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] pub server_latitude: Option, #[serde(default, skip_serializing_if = "Option::is_none")] pub server_longitude: Option, diff --git a/src/trx-server/Cargo.toml b/src/trx-server/Cargo.toml index 39a694a..82878e3 100644 --- a/src/trx-server/Cargo.toml +++ b/src/trx-server/Cargo.toml @@ -6,6 +6,7 @@ name = "trx-server" version = "0.1.0" edition = "2021" +build = "build.rs" [dependencies] tokio = { workspace = true, features = ["full"] } diff --git a/src/trx-server/build.rs b/src/trx-server/build.rs new file mode 100644 index 0000000..00f46e0 --- /dev/null +++ b/src/trx-server/build.rs @@ -0,0 +1,25 @@ +use std::time::{SystemTime, UNIX_EPOCH}; + +fn utc_ymd_from_unix_secs(secs: i64) -> (i32, u32, u32) { + let days = secs.div_euclid(86_400); + let z = days + 719_468; + let era = if z >= 0 { z } else { z - 146_096 } / 146_097; + let doe = z - era * 146_097; + let yoe = (doe - doe / 1_460 + doe / 36_524 - doe / 146_096) / 365; + let mut y = yoe + era * 400; + let doy = doe - (365 * yoe + yoe / 4 - yoe / 100); + let mp = (5 * doy + 2) / 153; + let d = doy - (153 * mp + 2) / 5 + 1; + let m = mp + if mp < 10 { 3 } else { -9 }; + y += if m <= 2 { 1 } else { 0 }; + (y as i32, m as u32, d as u32) +} + +fn main() { + let secs = match SystemTime::now().duration_since(UNIX_EPOCH) { + Ok(d) => d.as_secs() as i64, + Err(_) => 0, + }; + let (y, m, d) = utc_ymd_from_unix_secs(secs); + println!("cargo:rustc-env=TRX_SERVER_BUILD_DATE={y:04}-{m:02}-{d:02}"); +} diff --git a/src/trx-server/src/main.rs b/src/trx-server/src/main.rs index c256bab..bef86f2 100644 --- a/src/trx-server/src/main.rs +++ b/src/trx-server/src/main.rs @@ -224,6 +224,7 @@ fn build_rig_task_config( initial_mode: cfg.rig.initial_mode.clone(), server_callsign: resolved.callsign.clone(), server_version: Some(env!("CARGO_PKG_VERSION").to_string()), + server_build_date: Some(env!("TRX_SERVER_BUILD_DATE").to_string()), server_latitude: resolved.latitude, server_longitude: resolved.longitude, pskreporter_status, @@ -302,6 +303,7 @@ async fn main() -> DynResult<()> { let initial_state = RigState::new_with_metadata( resolved.callsign.clone(), Some(env!("CARGO_PKG_VERSION").to_string()), + Some(env!("TRX_SERVER_BUILD_DATE").to_string()), resolved.latitude, resolved.longitude, cfg.rig.initial_freq_hz, diff --git a/src/trx-server/src/rig_task.rs b/src/trx-server/src/rig_task.rs index 686cc6c..7b92e05 100644 --- a/src/trx-server/src/rig_task.rs +++ b/src/trx-server/src/rig_task.rs @@ -38,6 +38,7 @@ pub struct RigTaskConfig { pub initial_mode: RigMode, pub server_callsign: Option, pub server_version: Option, + pub server_build_date: Option, pub server_latitude: Option, pub server_longitude: Option, pub pskreporter_status: Option, @@ -60,6 +61,7 @@ impl Default for RigTaskConfig { initial_mode: RigMode::USB, server_callsign: None, server_version: None, + server_build_date: None, server_latitude: None, server_longitude: None, pskreporter_status: None, @@ -102,6 +104,7 @@ pub async fn run_rig_task( let mut state = RigState::new_with_metadata( config.server_callsign.clone(), config.server_version.clone(), + config.server_build_date.clone(), config.server_latitude, config.server_longitude, config.initial_freq_hz,