added partial settings updates
This commit is contained in:
@@ -2,7 +2,12 @@ use axum::{Json, extract::State, http::HeaderMap, response::IntoResponse};
|
|||||||
use std::{fs, sync::Arc};
|
use std::{fs, sync::Arc};
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
|
|
||||||
use crate::{AppState, auth::check_auth, error::AppError, models::SiteConfig};
|
use crate::{
|
||||||
|
AppState,
|
||||||
|
auth::check_auth,
|
||||||
|
error::AppError,
|
||||||
|
models::{SiteConfig, SiteConfigPatch},
|
||||||
|
};
|
||||||
|
|
||||||
pub async fn get_config(State(state): State<Arc<AppState>>) -> impl IntoResponse {
|
pub async fn get_config(State(state): State<Arc<AppState>>) -> impl IntoResponse {
|
||||||
let config_path = state.data_dir.join("config.json");
|
let config_path = state.data_dir.join("config.json");
|
||||||
@@ -17,12 +22,26 @@ pub async fn get_config(State(state): State<Arc<AppState>>) -> impl IntoResponse
|
|||||||
pub async fn update_config(
|
pub async fn update_config(
|
||||||
State(state): State<Arc<AppState>>,
|
State(state): State<Arc<AppState>>,
|
||||||
headers: HeaderMap,
|
headers: HeaderMap,
|
||||||
Json(payload): Json<SiteConfig>,
|
Json(patch): Json<SiteConfigPatch>,
|
||||||
) -> Result<Json<SiteConfig>, AppError> {
|
) -> Result<Json<SiteConfig>, AppError> {
|
||||||
check_auth(&headers, &state.admin_token)?;
|
check_auth(&headers, &state.admin_token)?;
|
||||||
|
|
||||||
let config_path = state.data_dir.join("config.json");
|
let config_path = state.data_dir.join("config.json");
|
||||||
let config_str = serde_json::to_string_pretty(&payload).map_err(|e| {
|
let mut config: SiteConfig = fs::read_to_string(&config_path)
|
||||||
|
.ok()
|
||||||
|
.and_then(|c| serde_json::from_str(&c).ok())
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
if let Some(v) = patch.title { config.title = v; }
|
||||||
|
if let Some(v) = patch.subtitle { config.subtitle = v; }
|
||||||
|
if let Some(v) = patch.welcome_title { config.welcome_title = v; }
|
||||||
|
if let Some(v) = patch.welcome_subtitle { config.welcome_subtitle = v; }
|
||||||
|
if let Some(v) = patch.footer { config.footer = v; }
|
||||||
|
if let Some(v) = patch.favicon { config.favicon = v; }
|
||||||
|
if let Some(v) = patch.theme { config.theme = v; }
|
||||||
|
if let Some(v) = patch.custom_css { config.custom_css = v; }
|
||||||
|
|
||||||
|
let config_str = serde_json::to_string_pretty(&config).map_err(|e| {
|
||||||
error!("Serialization error: {}", e);
|
error!("Serialization error: {}", e);
|
||||||
AppError::Internal("Serialization error".to_string(), Some(e.to_string()))
|
AppError::Internal("Serialization error".to_string(), Some(e.to_string()))
|
||||||
})?;
|
})?;
|
||||||
@@ -32,5 +51,5 @@ pub async fn update_config(
|
|||||||
AppError::Internal("Write error".to_string(), Some(e.to_string()))
|
AppError::Internal("Write error".to_string(), Some(e.to_string()))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
Ok(Json(payload))
|
Ok(Json(config))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,26 @@ impl Default for SiteConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Default)]
|
||||||
|
pub struct SiteConfigPatch {
|
||||||
|
#[serde(default)]
|
||||||
|
pub title: Option<String>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub subtitle: Option<String>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub welcome_title: Option<String>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub welcome_subtitle: Option<String>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub footer: Option<String>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub favicon: Option<String>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub theme: Option<String>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub custom_css: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Default)]
|
#[derive(Serialize, Deserialize, Clone, Default)]
|
||||||
pub struct PostMeta {
|
pub struct PostMeta {
|
||||||
pub date: NaiveDate,
|
pub date: NaiveDate,
|
||||||
|
|||||||
Reference in New Issue
Block a user