Add TOML dependency and new config/startup modules
The TOML dependency is added to `Cargo.lock` to support configuration file parsing. New modules `config` and `startup` are introduced in `doctate-client-core`: - `config`: Handles client configuration loading and saving, including defaults for polling intervals and window hours. - `startup`: Contains routines for initial cleanup tasks, such as removing stale markers and orphan audio files based on defined retention periods.
This commit is contained in:
+16
-36
@@ -14,10 +14,13 @@ use std::sync::Arc;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
use doctate_client_core::{
|
||||
cleanup_orphan_audio, write_sidecar, CaseMarker, CaseStore, PendingUpload, ServerSync,
|
||||
SnapshotCache, SyncConfig, UploadEvent, WorkerSnapshot, WorkerState,
|
||||
pick_footer_status, run_startup_cleanup, write_sidecar, CaseMarker, CaseStore, FooterStatus,
|
||||
PendingUpload, ServerSync, SnapshotCache, SyncConfig, UploadEvent, WorkerSnapshot, WorkerState,
|
||||
DEFAULT_MARKER_RETENTION, DEFAULT_ORPHAN_AUDIO_RETENTION,
|
||||
};
|
||||
use doctate_common::timestamp::{
|
||||
extract_hhmm, now_rfc3339, parse_rfc3339, recorded_at_to_filename_stem,
|
||||
};
|
||||
use doctate_common::timestamp::{now_rfc3339, recorded_at_to_filename_stem};
|
||||
use eframe::egui;
|
||||
use tokio::runtime::Runtime;
|
||||
use tokio::sync::{mpsc, watch};
|
||||
@@ -26,7 +29,7 @@ use uuid::Uuid;
|
||||
|
||||
use crate::config::Config;
|
||||
use crate::recorder::{Recorder, RecorderEvent};
|
||||
use crate::state::{pick_footer_status, AppState, FooterStatus};
|
||||
use crate::state::AppState;
|
||||
|
||||
pub struct DoctateApp {
|
||||
runtime: Arc<Runtime>,
|
||||
@@ -72,7 +75,7 @@ impl DoctateApp {
|
||||
cases_dir: PathBuf,
|
||||
snapshot_cache_path: PathBuf,
|
||||
) -> Self {
|
||||
let config = match Config::load() {
|
||||
let config = match crate::config::load() {
|
||||
Ok(Some(c)) => Some(c),
|
||||
Ok(None) => None,
|
||||
Err(e) => {
|
||||
@@ -102,18 +105,13 @@ impl DoctateApp {
|
||||
let store = case_store.clone();
|
||||
let pending = pending_dir.clone();
|
||||
runtime.block_on(async move {
|
||||
let marker_cutoff = time::OffsetDateTime::now_utc() - time::Duration::hours(72);
|
||||
match store.cleanup_stale(marker_cutoff).await {
|
||||
Ok(n) if n > 0 => info!(count = n, "startup cleanup: stale markers removed"),
|
||||
Ok(_) => {}
|
||||
Err(e) => warn!(error = %e, "startup cleanup: marker sweep failed"),
|
||||
}
|
||||
let audio_cutoff =
|
||||
std::time::SystemTime::now() - std::time::Duration::from_secs(24 * 3600);
|
||||
let n = cleanup_orphan_audio(&pending, audio_cutoff).await;
|
||||
if n > 0 {
|
||||
info!(count = n, "startup cleanup: orphan audio removed");
|
||||
}
|
||||
run_startup_cleanup(
|
||||
&store,
|
||||
&pending,
|
||||
DEFAULT_MARKER_RETENTION,
|
||||
DEFAULT_ORPHAN_AUDIO_RETENTION,
|
||||
)
|
||||
.await;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -164,7 +162,7 @@ impl DoctateApp {
|
||||
.as_ref()
|
||||
.and_then(|c| c.oneliner_window_hours),
|
||||
};
|
||||
if let Err(e) = cfg.save() {
|
||||
if let Err(e) = crate::config::save(&cfg) {
|
||||
error!(error = %e, "config save failed");
|
||||
self.state = AppState::Error {
|
||||
message: format!("Speichern: {e}"),
|
||||
@@ -641,24 +639,6 @@ fn spawn_worker(
|
||||
(sync, events_rx, snapshot_rx)
|
||||
}
|
||||
|
||||
fn parse_rfc3339(s: &str) -> Option<time::OffsetDateTime> {
|
||||
time::OffsetDateTime::parse(s, &time::format_description::well_known::Rfc3339).ok()
|
||||
}
|
||||
|
||||
/// Extract `HH:MM` from an RFC3339 UTC timestamp. Returns the raw string
|
||||
/// truncated to the first 16 chars as a fallback on parse failure — the
|
||||
/// user still gets something readable.
|
||||
fn extract_hhmm(ts: &str) -> String {
|
||||
match parse_rfc3339(ts) {
|
||||
Some(t) => {
|
||||
let local = t
|
||||
.to_offset(time::UtcOffset::current_local_offset().unwrap_or(time::UtcOffset::UTC));
|
||||
format!("{:02}:{:02}", local.hour(), local.minute())
|
||||
}
|
||||
None => ts.chars().take(16).collect(),
|
||||
}
|
||||
}
|
||||
|
||||
impl eframe::App for DoctateApp {
|
||||
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
|
||||
self.drain_recorder_events();
|
||||
|
||||
Reference in New Issue
Block a user