chore: initialiser le projet imagod-web (Rust)
- Structure du projet Cargo avec dépendances (clap, axum, reqwest, rusqlite, arboard, tray-icon) - CLI avec sous-commandes start, serve, stop, status, config, install, uninstall, logs - Module config: parsing TOML, chemins Windows/Linux - Module dedup: dédoublonnage SHA-256 avec cache SQLite - Module imago_client: client HTTP pour API Imago (upload, search, get) - Module watcher: boucle de polling stub - Module server: serveur web axum avec routes API REST stub - Platform-specific: clipboard, tray, service, window_info (Windows) - Frontend placeholder HTML - Config par défaut (imagod.toml) - README.md, LICENSE (MIT), .gitignore
This commit is contained in:
+132
@@ -0,0 +1,132 @@
|
||||
//! Gestion de la configuration TOML
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::path::PathBuf;
|
||||
|
||||
/// Configuration complète d'imagod-web
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Config {
|
||||
#[serde(default)]
|
||||
pub imago: ImagoConfig,
|
||||
#[serde(default)]
|
||||
pub watcher: WatcherConfig,
|
||||
#[serde(default)]
|
||||
pub dedup: DedupConfig,
|
||||
#[serde(default)]
|
||||
pub ui: UiConfig,
|
||||
#[serde(default)]
|
||||
pub logging: LoggingConfig,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct ImagoConfig {
|
||||
pub url: String,
|
||||
pub api_key: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct WatcherConfig {
|
||||
pub capture_images: bool,
|
||||
pub poll_interval_ms: u64,
|
||||
pub filters: WatcherFilters,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct WatcherFilters {
|
||||
pub only_apps: Vec<String>,
|
||||
pub exclude_apps: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct DedupConfig {
|
||||
pub method: String,
|
||||
pub cache_size: usize,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct UiConfig {
|
||||
pub show_notifications: bool,
|
||||
pub show_tray_icon: bool,
|
||||
pub notification_timeout_sec: u64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct LoggingConfig {
|
||||
pub level: String,
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
imago: ImagoConfig {
|
||||
url: "http://imago.dracodev.net:8000".into(),
|
||||
api_key: String::new(),
|
||||
},
|
||||
watcher: WatcherConfig {
|
||||
capture_images: true,
|
||||
poll_interval_ms: 500,
|
||||
filters: WatcherFilters {
|
||||
only_apps: vec![],
|
||||
exclude_apps: vec!["mstsc".into()],
|
||||
},
|
||||
},
|
||||
dedup: DedupConfig {
|
||||
method: "sha256".into(),
|
||||
cache_size: 10000,
|
||||
},
|
||||
ui: UiConfig {
|
||||
show_notifications: true,
|
||||
show_tray_icon: true,
|
||||
notification_timeout_sec: 3,
|
||||
},
|
||||
logging: LoggingConfig {
|
||||
level: "info".into(),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Config {
|
||||
/// Charge la configuration depuis `%APPDATA%/imagod-web/imagod.toml`
|
||||
pub fn load() -> Result<Self> {
|
||||
let path = Self::config_path()?;
|
||||
if path.exists() {
|
||||
let content = std::fs::read_to_string(&path)
|
||||
.with_context(|| format!("Impossible de lire {}", path.display()))?;
|
||||
let config: Config = toml::from_str(&content)
|
||||
.with_context(|| "Erreur de parsing du fichier de configuration")?;
|
||||
Ok(config)
|
||||
} else {
|
||||
// Premier lancement — créer la config par défaut
|
||||
let config = Config::default();
|
||||
config.save()?;
|
||||
Ok(config)
|
||||
}
|
||||
}
|
||||
|
||||
/// Sauvegarde la configuration
|
||||
pub fn save(&self) -> Result<()> {
|
||||
let path = Self::config_path()?;
|
||||
if let Some(parent) = path.parent() {
|
||||
std::fs::create_dir_all(parent)?;
|
||||
}
|
||||
let content = toml::to_string_pretty(self)?;
|
||||
std::fs::write(&path, content)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Chemin du fichier de configuration
|
||||
fn config_path() -> Result<PathBuf> {
|
||||
let base = if cfg!(target_os = "windows") {
|
||||
let appdata = std::env::var("APPDATA")
|
||||
.context("Variable APPDATA non définie")?;
|
||||
PathBuf::from(appdata)
|
||||
} else {
|
||||
let home = std::env::var("HOME")
|
||||
.context("Variable HOME non définie")?;
|
||||
PathBuf::from(home).join(".config")
|
||||
};
|
||||
Ok(base.join("imagod-web").join("imagod.toml"))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user