proper config file

This commit is contained in:
Robin Appelman 2026-02-08 20:03:59 +01:00
commit 6cf28c4504
4 changed files with 1211 additions and 470 deletions

59
src/config.rs Normal file
View file

@ -0,0 +1,59 @@
use demostf_client::ApiClient;
use serde::Deserialize;
use std::fs::read_to_string;
use thiserror::Error;
#[derive(Debug, Error)]
pub enum ConfigError {
#[error("Failed to read config from {path}: {error}")]
Read { error: std::io::Error, path: String },
#[error("Failed to parse config from {path}: {error}")]
Parse {
error: toml::de::Error,
path: String,
},
}
#[derive(Debug, Deserialize)]
pub struct Config {
pub api: ApiConfig,
pub storage: StorageConfig,
pub cleanup: CleanupConfig,
}
impl Config {
pub fn load(path: String) -> Result<Self, ConfigError> {
let content = read_to_string(&path).map_err(|error| ConfigError::Read {
error,
path: path.clone(),
})?;
toml::from_str(&content).map_err(|error| ConfigError::Parse { error, path })
}
}
#[derive(Debug, Deserialize)]
pub struct ApiConfig {
#[serde(default = "default_api_base")]
pub url: String,
pub key_file: String,
}
fn default_api_base() -> String {
ApiClient::DEMOS_TF_BASE_URL.into()
}
#[derive(Debug, Deserialize)]
pub struct CleanupConfig {
#[serde(default = "default_from_backend")]
pub from_backend: String,
pub age: u64,
}
fn default_from_backend() -> String {
"freezer".into()
}
#[derive(Debug, Deserialize)]
pub struct StorageConfig {
pub root: String,
}

View file

@ -1,44 +1,65 @@
use chrono::{Duration, Utc};
mod config;
use crate::config::Config;
use clap::Parser;
use demostf_client::{ApiClient, ListOrder, ListParams};
use main_error::MainError;
use std::fs::remove_file;
use std::path::PathBuf;
use time::{Duration, OffsetDateTime};
use tracing::{error, info, info_span};
#[derive(Debug, Parser)]
struct Args {
/// Config file
config: String,
}
#[tokio::main]
async fn main() -> Result<(), MainError> {
let key = dotenv::var("DEMOSTF_KEY").expect("DEMOSTF_KEY not set");
let root = PathBuf::from(dotenv::var("DEMOS_ROOT").expect("DEMOS_ROOT not set"));
tracing_subscriber::fmt::init();
let client = ApiClient::new();
let args = Args::parse();
let config = Config::load(args.config)?;
let api_key = load(&config.api.key_file)?;
let client = ApiClient::with_base_url(config.api.url)?;
let demos = client
.list(
ListParams::default()
.with_order(ListOrder::Ascending)
.with_backend("freezer"),
.with_backend(&config.cleanup.from_backend),
1,
)
.await?;
let cutoff_time = Utc::now() - Duration::days(3 * 365);
let cutoff_time = OffsetDateTime::now_utc() - Duration::seconds(config.cleanup.age as i64);
let root = PathBuf::from(config.storage.root);
for demo in demos {
if demo.time > cutoff_time {
break;
}
let _span = info_span!("processing", id = demo.id).entered();
let path = root.join(&demo.path.trim_start_matches('/'));
let path = root.join(
demo.path
.trim_start_matches('/')
.trim_start_matches("demos/"),
);
if !path.exists() {
eprintln!("Demo not found: {}", path.to_str().unwrap());
error!(path = ?path, "Demo not found");
break;
}
info!("removing");
client
.set_url(demo.id, "deleted", "", "", demo.hash, &key)
.set_url(demo.id, "deleted", "", "", demo.hash, &api_key)
.await?;
remove_file(&path)?;
println!("{} {}", demo.id, demo.name);
info!("{} {}", demo.id, demo.name);
}
Ok(())