From 31d368979e4330fd6239514e2cfee0d1751831a0 Mon Sep 17 00:00:00 2001 From: coolcoala Date: Fri, 18 Jul 2025 04:12:55 +0300 Subject: [PATCH] =?UTF-8?q?added=20update=20profiles=20at=20startup,=20?= =?UTF-8?q?=E2=80=9Cannounce-url=E2=80=9D=20header,=20and=20also=20when=20?= =?UTF-8?q?adding=20check=20if=20the=20profile=20already=20exists=20and=20?= =?UTF-8?q?if=20it=20does,=20just=20update=20it?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src-tauri/src/cmd/profile.rs | 65 ++++++++++++++++++++++- src-tauri/src/config/prfitem.rs | 31 ++++++++++- src-tauri/src/config/profiles.rs | 1 + src-tauri/src/lib.rs | 9 ++++ src/components/profile/profile-viewer.tsx | 15 ++++++ src/services/types.d.ts | 3 ++ 6 files changed, 121 insertions(+), 3 deletions(-) diff --git a/src-tauri/src/cmd/profile.rs b/src-tauri/src/cmd/profile.rs index 73aea6df..10235fc2 100644 --- a/src-tauri/src/cmd/profile.rs +++ b/src-tauri/src/cmd/profile.rs @@ -129,8 +129,24 @@ pub async fn enhance_profiles() -> CmdResult { /// 导入配置文件 #[tauri::command] pub async fn import_profile(url: String, option: Option) -> CmdResult { - let item = wrap_err!(PrfItem::from_url(&url, None, None, option).await)?; - wrap_err!(Config::profiles().data().append_item(item)) + let existing_uid = { + let profiles = Config::profiles(); + let profiles = profiles.latest(); + + profiles.items.as_ref() + .and_then(|items| items.iter().find(|item| item.url.as_deref() == Some(&url))) + .and_then(|item| item.uid.clone()) + }; + + if let Some(uid) = existing_uid { + logging!(info, Type::Cmd, true, "The profile with URL {} already exists (UID: {}). Running the update...", url, uid); + update_profile(uid, option).await + } else { + logging!(info, Type::Cmd, true, "Profile with URL {} not found. Create a new one...", url); + let item = wrap_err!(PrfItem::from_url(&url, None, None, option).await)?; + wrap_err!(Config::profiles().data().append_item(item)) + } + } /// 重新排序配置文件 @@ -647,3 +663,48 @@ pub fn get_next_update_time(uid: String) -> CmdResult> { let next_time = timer.get_next_update_time(&uid); Ok(next_time) } + + +#[tauri::command] +pub async fn update_profiles_on_startup() -> CmdResult { + logging!(info, Type::Cmd, true, "Checking profiles for updates at startup..."); + + let profiles_to_update = { + let profiles = Config::profiles(); + let profiles = profiles.latest(); + + profiles.items.as_ref() + .map_or_else( + Vec::new, + |items| items.iter() + .filter(|item| item.option.as_ref().is_some_and(|opt| opt.update_always == Some(true))) + .filter_map(|item| item.uid.clone()) + .collect() + ) + }; + + if profiles_to_update.is_empty() { + logging!(info, Type::Cmd, true, "No profiles to update immediately."); + return Ok(()); + } + + logging!(info, Type::Cmd, true, "Found profiles to update: {:?}", profiles_to_update); + + let mut update_futures = Vec::new(); + for uid in profiles_to_update { + update_futures.push(update_profile(uid, None)); + } + + let results = futures::future::join_all(update_futures).await; + + + if results.iter().any(|res| res.is_ok()) { + logging!(info, Type::Cmd, true, "The startup update is complete, restart the kernel..."); + CoreManager::global().update_config().await.map_err(|e| e.to_string())?; + handle::Handle::refresh_clash(); + } else { + logging!(warn, Type::Cmd, true, "All updates completed with errors on startup."); + } + + Ok(()) +} diff --git a/src-tauri/src/config/prfitem.rs b/src-tauri/src/config/prfitem.rs index a6110d23..7ba8a149 100644 --- a/src-tauri/src/config/prfitem.rs +++ b/src-tauri/src/config/prfitem.rs @@ -63,6 +63,10 @@ pub struct PrfItem { #[serde(skip_serializing_if = "Option::is_none")] pub announce: Option, + /// profile announce url + #[serde(skip_serializing_if = "Option::is_none")] + pub announce_url: Option, + /// the file data #[serde(skip)] pub file_data: Option, @@ -126,6 +130,9 @@ pub struct PrfOption { #[serde(skip_serializing_if = "Option::is_none")] pub use_hwid: Option, + + #[serde(skip_serializing_if = "Option::is_none")] + pub update_always: Option, } impl PrfOption { @@ -146,6 +153,7 @@ impl PrfOption { a.groups = b.groups.or(a.groups); a.timeout_seconds = b.timeout_seconds.or(a.timeout_seconds); a.use_hwid = b.use_hwid.or(a.use_hwid); + a.update_always = b.update_always.or(a.update_always); Some(a) } t => t.0.or(t.1), @@ -246,6 +254,7 @@ impl PrfItem { home: None, support_url: None, announce: None, + announce_url: None, updated: Some(chrono::Local::now().timestamp() as usize), file_data: Some(file_data.unwrap_or(tmpl::ITEM_LOCAL.into())), }) @@ -267,7 +276,7 @@ impl PrfItem { let user_agent = opt_ref.and_then(|o| o.user_agent.clone()); let update_interval = opt_ref.and_then(|o| o.update_interval); let timeout = opt_ref.and_then(|o| o.timeout_seconds).unwrap_or(20); - let use_hwid = opt_ref.is_some_and(|o| o.use_hwid.unwrap_or(true)); + let use_hwid = Config::verge().latest().enable_send_hwid.unwrap_or(true); let mut merge = opt_ref.and_then(|o| o.merge.clone()); let mut script = opt_ref.and_then(|o| o.script.clone()); let mut rules = opt_ref.and_then(|o| o.rules.clone()); @@ -373,6 +382,11 @@ impl PrfItem { }, }; + let update_always = match header.get("update-always") { + Some(value) => value.to_str().unwrap_or("false").parse::().ok(), + None => None, + }; + let home = match header.get("profile-web-page-url") { Some(value) => { let str_value = value.to_str().unwrap_or(""); @@ -403,6 +417,14 @@ impl PrfItem { None => None, }; + let announce_url = match header.get("announce-url") { + Some(value) => { + let str_value = value.to_str().unwrap_or(""); + Some(str_value.to_string()) + } + None => None, + }; + let profile_title = match header.get("profile-title") { Some(value) => { let str_value = value.to_str().unwrap_or(""); @@ -472,6 +494,7 @@ impl PrfItem { extra, option: Some(PrfOption { update_interval, + update_always, merge, script, rules, @@ -482,6 +505,7 @@ impl PrfItem { home, support_url, announce, + announce_url, updated: Some(chrono::Local::now().timestamp() as usize), file_data: Some(data.into()), }) @@ -511,6 +535,7 @@ impl PrfItem { home: None, support_url: None, announce: None, + announce_url: None, updated: Some(chrono::Local::now().timestamp() as usize), file_data: Some(template), }) @@ -535,6 +560,7 @@ impl PrfItem { home: None, support_url: None, announce: None, + announce_url: None, selected: None, extra: None, option: None, @@ -558,6 +584,7 @@ impl PrfItem { home: None, support_url: None, announce: None, + announce_url: None, selected: None, extra: None, option: None, @@ -581,6 +608,7 @@ impl PrfItem { home: None, support_url: None, announce: None, + announce_url: None, selected: None, extra: None, option: None, @@ -604,6 +632,7 @@ impl PrfItem { home: None, support_url: None, announce: None, + announce_url: None, selected: None, extra: None, option: None, diff --git a/src-tauri/src/config/profiles.rs b/src-tauri/src/config/profiles.rs index 19857852..eec6f047 100644 --- a/src-tauri/src/config/profiles.rs +++ b/src-tauri/src/config/profiles.rs @@ -221,6 +221,7 @@ impl IProfiles { each.updated = item.updated; each.home = item.home; each.announce = item.announce; + each.announce_url = item.announce_url; each.support_url = item.support_url; each.name = item.name; each.url = item.url; diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 5751785d..b9bce378 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -216,6 +216,14 @@ pub fn run() { app.manage(Mutex::new(state::proxy::CmdProxyState::default())); app.manage(Mutex::new(state::lightweight::LightWeightState::default())); + tauri::async_runtime::spawn(async { + tokio::time::sleep(Duration::from_secs(5)).await; + logging!(info, Type::Cmd, true, "Running profile updates at startup..."); + if let Err(e) = crate::cmd::update_profiles_on_startup().await { + log::error!("Failed to update profiles on startup: {}", e); + } + }); + logging!(info, Type::Setup, true, "初始化完成,继续执行"); Ok(()) }) @@ -295,6 +303,7 @@ pub fn run() { cmd::read_profile_file, cmd::save_profile_file, cmd::get_next_update_time, + cmd::update_profiles_on_startup, // script validation cmd::script_validate_notice, cmd::validate_script_file, diff --git a/src/components/profile/profile-viewer.tsx b/src/components/profile/profile-viewer.tsx index 66729df5..96b4e738 100644 --- a/src/components/profile/profile-viewer.tsx +++ b/src/components/profile/profile-viewer.tsx @@ -447,6 +447,21 @@ export const ProfileViewer = forwardRef( )} /> + ( + + {t("Update on Startup")} + + + + + )} + />