feat: add webdav backup

This commit is contained in:
huzibaca
2024-11-09 23:11:02 +08:00
parent 44cb1c7f3e
commit b5e0374946
16 changed files with 703 additions and 577 deletions

View File

@@ -40,14 +40,27 @@ impl WebDavClient {
let url = verge.webdav_url.unwrap_or_default();
let username = verge.webdav_username.unwrap_or_default();
let password = verge.webdav_password.unwrap_or_default();
let url = url.trim_end_matches('/');
let client = reqwest_dav::ClientBuilder::new()
.set_agent(
reqwest::Client::builder()
.danger_accept_invalid_certs(true)
.build()
.unwrap(),
)
.set_host(url.to_owned())
.set_auth(reqwest_dav::Auth::Basic(
username.to_owned(),
password.to_owned(),
))
.build()?;
if let Err(_) = client
.list(dirs::BACKUP_DIR, reqwest_dav::Depth::Number(0))
.await
{
client.mkcol(dirs::BACKUP_DIR).await?;
}
*self.client.lock() = Some(client.clone());
}
Ok(self.client.lock().clone().unwrap())
@@ -61,10 +74,6 @@ impl WebDavClient {
pub async fn upload(&self, file_path: PathBuf, file_name: String) -> Result<(), Error> {
let client = self.get_client().await?;
if client.get(dirs::BACKUP_DIR).await.is_err() {
client.mkcol(dirs::BACKUP_DIR).await?;
}
let webdav_path: String = format!("{}/{}", dirs::BACKUP_DIR, file_name);
client
.put(webdav_path.as_ref(), fs::read(file_path)?)
@@ -72,7 +81,16 @@ impl WebDavClient {
Ok(())
}
pub async fn list_files(&self) -> Result<Vec<ListFile>, Error> {
pub async fn download(&self, filename: String, storage_path: PathBuf) -> Result<(), Error> {
let client = self.get_client().await?;
let path = format!("{}/{}", dirs::BACKUP_DIR, filename);
let response = client.get(&path.as_str()).await?;
let content = response.bytes().await?;
fs::write(&storage_path, &content)?;
Ok(())
}
pub async fn list(&self) -> Result<Vec<ListFile>, Error> {
let client = self.get_client().await?;
let files = client
.list(dirs::BACKUP_DIR, reqwest_dav::Depth::Number(1))
@@ -85,6 +103,13 @@ impl WebDavClient {
}
Ok(final_files)
}
pub async fn delete(&self, file_name: String) -> Result<(), Error> {
let client = self.get_client().await?;
let path = format!("{}/{}", dirs::BACKUP_DIR, file_name);
client.delete(&path).await?;
Ok(())
}
}
pub fn create_backup() -> Result<(String, PathBuf), Error> {
@@ -109,8 +134,17 @@ pub fn create_backup() -> Result<(String, PathBuf), Error> {
}
zip.start_file(dirs::CLASH_CONFIG, options)?;
zip.write_all(fs::read(dirs::clash_path()?)?.as_slice())?;
let mut verge_config: serde_json::Value =
serde_yaml::from_str(&fs::read_to_string(dirs::verge_path()?)?)?;
if let Some(obj) = verge_config.as_object_mut() {
obj.remove("webdav_username");
obj.remove("webdav_password");
obj.remove("webdav_url");
}
zip.start_file(dirs::VERGE_CONFIG, options)?;
zip.write_all(fs::read(dirs::verge_path()?)?.as_slice())?;
zip.write_all(serde_yaml::to_string(&verge_config)?.as_bytes())?;
zip.start_file(dirs::PROFILE_YAML, options)?;
zip.write_all(fs::read(dirs::profiles_path()?)?.as_slice())?;
zip.finish()?;

View File

@@ -87,6 +87,7 @@ impl CoreManager {
service::stop_core_by_service().await?;
}
*running = false;
Ok(())
}

View File

@@ -1,14 +1,14 @@
use crate::{
cmds,
config::Config,
core::CoreManager,
feat, log_err, t,
feat, t,
utils::{
dirs,
resolve::{self, VERSION},
},
};
use anyhow::Result;
use tauri::AppHandle;
use tauri::{
menu::CheckMenuItem,
tray::{MouseButton, MouseButtonState, TrayIconEvent, TrayIconId},
@@ -17,7 +17,6 @@ use tauri::{
menu::{MenuEvent, MenuItem, PredefinedMenuItem, Submenu},
Wry,
};
use tauri::{AppHandle, Manager};
use super::handle;
pub struct Tray {}
@@ -408,7 +407,7 @@ fn create_tray_menu(
Ok(menu)
}
fn on_menu_event(app_handle: &AppHandle, event: MenuEvent) {
fn on_menu_event(_: &AppHandle, event: MenuEvent) {
match event.id.as_ref() {
mode @ ("rule_mode" | "global_mode" | "direct_mode") => {
let mode = &mode[0..mode.len() - 5];
@@ -423,15 +422,7 @@ fn on_menu_event(app_handle: &AppHandle, event: MenuEvent) {
"open_core_dir" => crate::log_err!(cmds::open_core_dir()),
"open_logs_dir" => crate::log_err!(cmds::open_logs_dir()),
"restart_clash" => feat::restart_clash_core(),
"restart_app" => {
tauri::async_runtime::block_on(async move {
log_err!(CoreManager::global().stop_core().await);
});
resolve::resolve_reset();
//睡1秒再重启
std::thread::sleep(std::time::Duration::from_secs(1));
tauri::process::restart(&app_handle.env());
}
"restart_app" => feat::restart_app(),
"quit" => {
println!("quit");
feat::quit(Some(0));