123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- use crate::{
- config::{ProfileItem, ProfilesConfig},
- events::state::{ClashInfoState, ProfileLock},
- utils::{
- app_home_dir,
- clash::put_clash_profile,
- config::{read_profiles, save_profiles},
- fetch::fetch_profile,
- },
- };
- use std::fs::File;
- use std::io::Write;
- use std::time::{SystemTime, UNIX_EPOCH};
- use tauri::State;
- /// Import the profile from url
- /// and save to `profiles.yaml`
- #[tauri::command]
- pub async fn import_profile(url: String, lock: State<'_, ProfileLock>) -> Result<(), String> {
- let result = match fetch_profile(&url).await {
- Some(r) => r,
- None => {
- log::error!("failed to fetch profile from `{}`", url);
- return Err(format!("failed to fetch profile from `{}`", url));
- }
- };
- // get lock
- if lock.0.lock().is_err() {
- return Err(format!("can not get file lock"));
- }
- // save the profile file
- let path = app_home_dir().join("profiles").join(&result.file);
- let file_data = result.data.as_bytes();
- File::create(path).unwrap().write(file_data).unwrap();
- // update `profiles.yaml`
- let mut profiles = read_profiles();
- let mut items = profiles.items.unwrap_or(vec![]);
- let now = SystemTime::now()
- .duration_since(UNIX_EPOCH)
- .unwrap()
- .as_secs();
- items.push(ProfileItem {
- name: Some(result.name),
- file: Some(result.file),
- mode: Some(format!("rule")),
- url: Some(url),
- selected: Some(vec![]),
- extra: Some(result.extra),
- updated: Some(now as usize),
- });
- profiles.items = Some(items);
- save_profiles(&profiles)
- }
- /// Update the profile
- /// and save to `profiles.yaml`
- /// http request firstly
- /// then acquire the lock of `profiles.yaml`
- #[tauri::command]
- pub async fn update_profile(index: usize, lock: State<'_, ProfileLock>) -> Result<(), String> {
- // get lock
- if lock.0.lock().is_err() {
- return Err(format!("can not get file lock"));
- }
- // update `profiles.yaml`
- let mut profiles = read_profiles();
- let mut items = profiles.items.unwrap_or(vec![]);
- if index >= items.len() {
- return Err(format!("the index out of bound"));
- }
- let url = match &items[index].url {
- Some(u) => u,
- None => return Err(format!("invalid url")),
- };
- let result = match fetch_profile(&url).await {
- Some(r) => r,
- None => {
- log::error!("failed to fetch profile from `{}`", url);
- return Err(format!("failed to fetch profile from `{}`", url));
- }
- };
- let now = SystemTime::now()
- .duration_since(UNIX_EPOCH)
- .unwrap()
- .as_secs() as usize;
- // update file
- let file_path = &items[index].file.as_ref().unwrap();
- let file_path = app_home_dir().join("profiles").join(file_path);
- let file_data = result.data.as_bytes();
- File::create(file_path).unwrap().write(file_data).unwrap();
- items[index].name = Some(result.name);
- items[index].extra = Some(result.extra);
- items[index].updated = Some(now);
- profiles.items = Some(items);
- save_profiles(&profiles)
- }
- /// get all profiles from `profiles.yaml`
- /// do not acquire the lock of ProfileLock
- #[tauri::command]
- pub fn get_profiles() -> Result<ProfilesConfig, String> {
- Ok(read_profiles())
- }
- /// patch the profile config
- #[tauri::command]
- pub fn set_profiles(
- index: usize,
- profile: ProfileItem,
- lock: State<'_, ProfileLock>,
- ) -> Result<(), String> {
- // get lock
- if lock.0.lock().is_err() {
- return Err(format!("can not get file lock"));
- }
- let mut profiles = read_profiles();
- let mut items = profiles.items.unwrap_or(vec![]);
- if index >= items.len() {
- return Err(format!("the index out of bound"));
- }
- if profile.name.is_some() {
- items[index].name = profile.name;
- }
- if profile.file.is_some() {
- items[index].file = profile.file;
- }
- if profile.mode.is_some() {
- items[index].mode = profile.mode;
- }
- if profile.url.is_some() {
- items[index].url = profile.url;
- }
- if profile.selected.is_some() {
- items[index].selected = profile.selected;
- }
- if profile.extra.is_some() {
- items[index].extra = profile.extra;
- }
- profiles.items = Some(items);
- save_profiles(&profiles)
- }
- /// change the current profile
- #[tauri::command]
- pub async fn put_profiles(
- current: usize,
- lock: State<'_, ProfileLock>,
- clash_info: State<'_, ClashInfoState>,
- ) -> Result<(), String> {
- if lock.0.lock().is_err() {
- return Err(format!("can not get file lock"));
- }
- let clash_info = match clash_info.0.lock() {
- Ok(arc) => arc.clone(),
- _ => return Err(format!("can not get clash info")),
- };
- let mut profiles = read_profiles();
- let items_len = match &profiles.items {
- Some(list) => list.len(),
- None => 0,
- };
- if current >= items_len {
- return Err(format!("the index out of bound"));
- }
- profiles.current = Some(current);
- match save_profiles(&profiles) {
- Ok(_) => put_clash_profile(&clash_info).await,
- Err(err) => Err(err),
- }
- }
|