yggdrasil/api/settings/
webp.rs1#![allow(clippy::unused_unit, deprecated, clippy::too_many_arguments)]
4
5use dioxus::prelude::*;
6
7#[cfg(feature = "server")]
8use crate::api::auth::get_current_admin_user;
9#[cfg(feature = "server")]
10use crate::api::error::AppError;
11#[cfg(feature = "server")]
12use crate::db::pool::get_conn;
13use crate::models::settings::WebpSettings;
14
15#[cfg(feature = "server")]
25pub(crate) async fn seed_webp_settings_from_env(
26 client: &tokio_postgres::Client,
27) -> Result<(), AppError> {
28 use crate::models::settings as m;
29
30 let mut seeds: Vec<(&'static str, String)> = Vec::new();
31
32 if let Ok(v) = std::env::var("WEBP_QUALITY") {
33 match v.trim().parse::<f32>() {
34 Ok(q) => seeds.push((
35 "webp_quality",
36 m::WebpSettings::clamp_quality(q).to_string(),
37 )),
38 Err(_) => tracing::warn!("WEBP_QUALITY={v:?} 非法(期望浮点数),跳过"),
39 }
40 }
41 if let Ok(v) = std::env::var("WEBP_METHOD") {
42 match v.trim().parse::<u32>() {
43 Ok(n) => seeds.push(("webp_method", m::WebpSettings::clamp_method(n).to_string())),
44 Err(_) => tracing::warn!("WEBP_METHOD={v:?} 非法(期望非负整数),跳过"),
45 }
46 }
47
48 super::insert_env_seeds(client, seeds).await
49}
50
51#[cfg(feature = "server")]
56pub(crate) async fn load_webp_settings(
57 client: &tokio_postgres::Client,
58) -> Result<WebpSettings, AppError> {
59 use crate::models::settings as m;
60
61 let values = super::load_setting_values(client, &["webp_quality", "webp_method"]).await?;
62 let quality = values
63 .get("webp_quality")
64 .and_then(|v| v.parse().ok())
65 .map(m::WebpSettings::clamp_quality)
66 .unwrap_or(m::DEFAULT_WEBP_QUALITY);
67 let method = values
68 .get("webp_method")
69 .and_then(|v| v.parse().ok())
70 .map(m::WebpSettings::clamp_method)
71 .unwrap_or(m::DEFAULT_WEBP_METHOD);
72
73 Ok(WebpSettings { quality, method })
74}
75
76#[server(GetWebpSettings, "/api")]
78pub async fn get_webp_settings() -> Result<WebpSettings, ServerFnError> {
79 let _user = get_current_admin_user().await?;
80
81 #[cfg(feature = "server")]
82 {
83 let client = get_conn().await.map_err(AppError::db_conn)?;
84 let s = load_webp_settings(&client)
85 .await
86 .map_err(ServerFnError::from)?;
87 Ok(s)
88 }
89
90 #[cfg(not(feature = "server"))]
91 {
92 Ok(WebpSettings::default())
93 }
94}
95
96#[server(UpdateWebpSettings, "/api")]
101pub async fn update_webp_settings(
102 quality: f32,
103 method: u32,
104) -> Result<WebpSettings, ServerFnError> {
105 let _user = get_current_admin_user().await?;
106
107 let quality = WebpSettings::clamp_quality(quality);
108 let method = WebpSettings::clamp_method(method);
109
110 #[cfg(feature = "server")]
111 {
112 let client = get_conn().await.map_err(AppError::db_conn)?;
113
114 for (key, value) in [
115 ("webp_quality", quality.to_string()),
116 ("webp_method", method.to_string()),
117 ] {
118 client
119 .execute(
120 "INSERT INTO settings (key, value, updated_at) VALUES ($1, $2, NOW())
121 ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value, updated_at = NOW()",
122 &[&key, &value],
123 )
124 .await
125 .map_err(AppError::query)?;
126 }
127
128 tracing::info!(
129 "WebP settings updated (需重启生效): quality={}, method={}",
130 quality,
131 method
132 );
133 }
134
135 Ok(WebpSettings { quality, method })
136}