yggdrasil/api/settings/
image_cache.rs1#![allow(clippy::unused_unit, deprecated, clippy::too_many_arguments)]
4
5use crate::api::error::ApiError;
6use leptos::prelude::*;
7
8#[cfg(feature = "server")]
9use crate::api::auth::get_current_admin_user;
10#[cfg(feature = "server")]
11use crate::api::error::AppError;
12#[cfg(feature = "server")]
13use crate::db::pool::get_conn;
14use crate::models::settings::ImageCacheSettings;
15#[cfg(feature = "server")]
17use crate::cache::invalidate_image_cache_settings;
18
19#[cfg(feature = "server")]
27pub(crate) async fn seed_image_cache_settings_from_env(
28 client: &tokio_postgres::Client,
29) -> Result<(), AppError> {
30 let mut seeds: Vec<(&'static str, String)> = Vec::new();
31
32 if let Ok(v) = std::env::var("IMAGE_DISK_CACHE_MAX_MB") {
33 match v.trim().parse::<u32>() {
34 Ok(n) => seeds.push((
35 "image_disk_cache_max_mb",
36 crate::models::settings::ImageCacheSettings::clamp_max_mb(n).to_string(),
37 )),
38 Err(_) => tracing::warn!("IMAGE_DISK_CACHE_MAX_MB={v:?} 非法(期望正整数),跳过"),
39 }
40 }
41 if let Ok(v) = std::env::var("IMAGE_DISK_CACHE_MAX_AGE_HOURS") {
42 match v.trim().parse::<u32>() {
43 Ok(n) => seeds.push((
44 "image_disk_cache_max_age_hours",
45 crate::models::settings::ImageCacheSettings::clamp_max_age_hours(n).to_string(),
46 )),
47 Err(_) => {
48 tracing::warn!("IMAGE_DISK_CACHE_MAX_AGE_HOURS={v:?} 非法(期望正整数),跳过")
49 }
50 }
51 }
52
53 super::insert_env_seeds(client, seeds).await
54}
55
56#[cfg(feature = "server")]
58pub(crate) async fn load_image_cache_settings(
59 client: &tokio_postgres::Client,
60) -> Result<crate::models::settings::ImageCacheSettings, AppError> {
61 let values = super::load_setting_values(
62 client,
63 &["image_disk_cache_max_mb", "image_disk_cache_max_age_hours"],
64 )
65 .await?;
66
67 let disk_cache_max_mb = values
68 .get("image_disk_cache_max_mb")
69 .and_then(|v| v.parse().ok())
70 .map(crate::models::settings::ImageCacheSettings::clamp_max_mb)
71 .unwrap_or(crate::models::settings::DEFAULT_IMAGE_DISK_CACHE_MAX_MB);
72 let disk_cache_max_age_hours = values
73 .get("image_disk_cache_max_age_hours")
74 .and_then(|v| v.parse().ok())
75 .map(crate::models::settings::ImageCacheSettings::clamp_max_age_hours)
76 .unwrap_or(crate::models::settings::DEFAULT_IMAGE_DISK_CACHE_MAX_AGE_HOURS);
77
78 Ok(crate::models::settings::ImageCacheSettings {
79 disk_cache_max_mb,
80 disk_cache_max_age_hours,
81 })
82}
83
84#[cfg(feature = "server")]
86pub(crate) async fn runtime_image_cache_settings() -> crate::models::settings::ImageCacheSettings {
87 if let Some(s) = crate::cache::get_image_cache_settings().await {
88 return s;
89 }
90 let fallback = crate::models::settings::ImageCacheSettings::default();
91 if std::env::var("DATABASE_URL").is_err() {
94 return fallback;
95 }
96 match get_conn().await {
97 Ok(client) => match load_image_cache_settings(&client).await {
98 Ok(s) => {
99 crate::cache::set_image_cache_settings(s.clone()).await;
100 s
101 }
102 Err(e) => {
103 tracing::warn!("读取图片缓存配置失败,回退默认值:{e:?}");
104 fallback
105 }
106 },
107 Err(e) => {
108 tracing::warn!("获取连接读取图片缓存配置失败,回退默认值:{e:?}");
109 fallback
110 }
111 }
112}
113
114#[server(GetImageCacheSettings, endpoint = "get_image_cache_settings", input = leptos::server_fn::codec::Json)]
116pub async fn get_image_cache_settings() -> Result<ImageCacheSettings, ApiError> {
117 let _user = get_current_admin_user().await?;
118
119 #[cfg(feature = "server")]
120 {
121 let client = get_conn().await.map_err(AppError::db_conn)?;
122 let s = load_image_cache_settings(&client)
123 .await
124 .map_err(<ApiError>::from)?;
125 crate::cache::set_image_cache_settings(s.clone()).await;
126 Ok(s)
127 }
128
129 #[cfg(not(feature = "server"))]
130 {
131 Ok(ImageCacheSettings::default())
132 }
133}
134
135#[server(UpdateImageCacheSettings, endpoint = "update_image_cache_settings", input = leptos::server_fn::codec::Json)]
137pub async fn update_image_cache_settings(
138 disk_cache_max_mb: u32,
139 disk_cache_max_age_hours: u32,
140) -> Result<ImageCacheSettings, ApiError> {
141 let _user = get_current_admin_user().await?;
142
143 let disk_cache_max_mb = ImageCacheSettings::clamp_max_mb(disk_cache_max_mb);
144 let disk_cache_max_age_hours =
145 ImageCacheSettings::clamp_max_age_hours(disk_cache_max_age_hours);
146
147 #[cfg(feature = "server")]
148 {
149 let client = get_conn().await.map_err(AppError::db_conn)?;
150
151 super::upsert_settings(
152 &**client,
153 &[
154 ("image_disk_cache_max_mb", disk_cache_max_mb.to_string()),
155 (
156 "image_disk_cache_max_age_hours",
157 disk_cache_max_age_hours.to_string(),
158 ),
159 ],
160 )
161 .await?;
162
163 invalidate_image_cache_settings();
164 tracing::info!(
165 "Image cache settings updated: max_mb={}, max_age_hours={}",
166 disk_cache_max_mb,
167 disk_cache_max_age_hours
168 );
169 }
170
171 Ok(ImageCacheSettings {
172 disk_cache_max_mb,
173 disk_cache_max_age_hours,
174 })
175}