chore: git hooks for linter and formatter
This commit is contained in:
@@ -75,40 +75,41 @@ pub fn get_app_dir() -> CmdResult<String> {
|
||||
pub async fn download_icon_cache(url: String, name: String) -> CmdResult<String> {
|
||||
let icon_cache_dir = wrap_err!(dirs::app_home_dir())?.join("icons").join("cache");
|
||||
let icon_path = icon_cache_dir.join(&name);
|
||||
|
||||
|
||||
// 如果文件已存在,直接返回路径
|
||||
if icon_path.exists() {
|
||||
return Ok(icon_path.to_string_lossy().to_string());
|
||||
}
|
||||
|
||||
|
||||
// 确保缓存目录存在
|
||||
if !icon_cache_dir.exists() {
|
||||
let _ = std::fs::create_dir_all(&icon_cache_dir);
|
||||
}
|
||||
|
||||
|
||||
// 使用临时文件名来下载
|
||||
let temp_path = icon_cache_dir.join(format!("{}.downloading", &name));
|
||||
|
||||
|
||||
// 下载文件到临时位置
|
||||
let response = wrap_err!(reqwest::get(&url).await)?;
|
||||
|
||||
|
||||
// 检查内容类型是否为图片
|
||||
let content_type = response.headers()
|
||||
let content_type = response
|
||||
.headers()
|
||||
.get(reqwest::header::CONTENT_TYPE)
|
||||
.and_then(|v| v.to_str().ok())
|
||||
.unwrap_or("");
|
||||
|
||||
|
||||
let is_image = content_type.starts_with("image/");
|
||||
|
||||
|
||||
// 获取响应内容
|
||||
let content = wrap_err!(response.bytes().await)?;
|
||||
|
||||
|
||||
// 检查内容是否为HTML (针对CDN错误页面)
|
||||
let is_html = content.len() > 15 &&
|
||||
(content.starts_with(b"<!DOCTYPE html") ||
|
||||
content.starts_with(b"<html") ||
|
||||
content.starts_with(b"<?xml"));
|
||||
|
||||
let is_html = content.len() > 15
|
||||
&& (content.starts_with(b"<!DOCTYPE html")
|
||||
|| content.starts_with(b"<html")
|
||||
|| content.starts_with(b"<?xml"));
|
||||
|
||||
// 只有当内容确实是图片时才保存
|
||||
if is_image && !is_html {
|
||||
{
|
||||
@@ -122,14 +123,14 @@ pub async fn download_icon_cache(url: String, name: String) -> CmdResult<String>
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
wrap_err!(std::io::copy(&mut content.as_ref(), &mut file))?;
|
||||
}
|
||||
|
||||
|
||||
// 再次检查目标文件是否已存在,避免重命名覆盖其他线程已完成的文件
|
||||
if !icon_path.exists() {
|
||||
match std::fs::rename(&temp_path, &icon_path) {
|
||||
Ok(_) => {},
|
||||
Ok(_) => {}
|
||||
Err(_) => {
|
||||
let _ = std::fs::remove_file(&temp_path);
|
||||
if icon_path.exists() {
|
||||
@@ -140,11 +141,11 @@ pub async fn download_icon_cache(url: String, name: String) -> CmdResult<String>
|
||||
} else {
|
||||
let _ = std::fs::remove_file(&temp_path);
|
||||
}
|
||||
|
||||
|
||||
Ok(icon_path.to_string_lossy().to_string())
|
||||
} else {
|
||||
let _ = std::fs::remove_file(&temp_path);
|
||||
Err(format!("下载的内容不是有效图片: {}", url).into())
|
||||
Err(format!("下载的内容不是有效图片: {}", url))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,8 +159,7 @@ pub struct IconInfo {
|
||||
/// 复制图标文件
|
||||
#[tauri::command]
|
||||
pub fn copy_icon_file(path: String, icon_info: IconInfo) -> CmdResult<String> {
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
use std::{fs, path::Path};
|
||||
|
||||
let file_path = Path::new(&path);
|
||||
|
||||
|
||||
@@ -24,7 +24,8 @@ pub async fn patch_clash_config(payload: Mapping) -> CmdResult {
|
||||
/// 修改Clash模式
|
||||
#[tauri::command]
|
||||
pub async fn patch_clash_mode(payload: String) -> CmdResult {
|
||||
Ok(feat::change_clash_mode(payload))
|
||||
feat::change_clash_mode(payload);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// 切换Clash核心
|
||||
@@ -98,9 +99,11 @@ pub async fn save_dns_config(dns_config: Mapping) -> CmdResult {
|
||||
/// 应用或撤销DNS配置
|
||||
#[tauri::command]
|
||||
pub fn apply_dns_config(apply: bool) -> CmdResult {
|
||||
use crate::config::Config;
|
||||
use crate::core::{handle, CoreManager};
|
||||
use crate::utils::dirs;
|
||||
use crate::{
|
||||
config::Config,
|
||||
core::{handle, CoreManager},
|
||||
utils::dirs,
|
||||
};
|
||||
use tauri::async_runtime;
|
||||
|
||||
// 使用spawn来处理异步操作
|
||||
|
||||
@@ -4,29 +4,29 @@ use anyhow::Result;
|
||||
pub type CmdResult<T = ()> = Result<T, String>;
|
||||
|
||||
// Command modules
|
||||
pub mod profile;
|
||||
pub mod validate;
|
||||
pub mod uwp;
|
||||
pub mod webdav;
|
||||
pub mod app;
|
||||
pub mod network;
|
||||
pub mod clash;
|
||||
pub mod verge;
|
||||
pub mod network;
|
||||
pub mod profile;
|
||||
pub mod proxy;
|
||||
pub mod runtime;
|
||||
pub mod save_profile;
|
||||
pub mod system;
|
||||
pub mod proxy;
|
||||
pub mod uwp;
|
||||
pub mod validate;
|
||||
pub mod verge;
|
||||
pub mod webdav;
|
||||
|
||||
// Re-export all command functions for backwards compatibility
|
||||
pub use profile::*;
|
||||
pub use validate::*;
|
||||
pub use uwp::*;
|
||||
pub use webdav::*;
|
||||
pub use app::*;
|
||||
pub use network::*;
|
||||
pub use clash::*;
|
||||
pub use verge::*;
|
||||
pub use network::*;
|
||||
pub use profile::*;
|
||||
pub use proxy::*;
|
||||
pub use runtime::*;
|
||||
pub use save_profile::*;
|
||||
pub use system::*;
|
||||
pub use proxy::*;
|
||||
pub use uwp::*;
|
||||
pub use validate::*;
|
||||
pub use verge::*;
|
||||
pub use webdav::*;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use crate::wrap_err;
|
||||
use super::CmdResult;
|
||||
use sysproxy::{Autoproxy, Sysproxy};
|
||||
use serde_yaml::Mapping;
|
||||
use crate::wrap_err;
|
||||
use network_interface::NetworkInterface;
|
||||
use serde_yaml::Mapping;
|
||||
use sysproxy::{Autoproxy, Sysproxy};
|
||||
|
||||
/// get the system proxy
|
||||
#[tauri::command]
|
||||
@@ -46,8 +46,7 @@ pub fn get_network_interfaces() -> Vec<String> {
|
||||
/// 获取网络接口详细信息
|
||||
#[tauri::command]
|
||||
pub fn get_network_interfaces_info() -> CmdResult<Vec<NetworkInterface>> {
|
||||
use network_interface::NetworkInterface;
|
||||
use network_interface::NetworkInterfaceConfig;
|
||||
use network_interface::{NetworkInterface, NetworkInterfaceConfig};
|
||||
|
||||
let names = get_network_interfaces();
|
||||
let interfaces = wrap_err!(NetworkInterface::show())?;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
use super::CmdResult;
|
||||
use crate::{
|
||||
config::*,
|
||||
core::*,
|
||||
feat,
|
||||
feat, log_err, ret_err,
|
||||
utils::{dirs, help},
|
||||
log_err, ret_err, wrap_err,
|
||||
wrap_err,
|
||||
};
|
||||
use super::CmdResult;
|
||||
|
||||
/// 获取配置文件列表
|
||||
#[tauri::command]
|
||||
@@ -31,7 +31,7 @@ pub async fn enhance_profiles() -> CmdResult {
|
||||
}
|
||||
Err(e) => {
|
||||
println!("[enhance_profiles] 更新过程发生错误: {}", e);
|
||||
handle::Handle::notice_message("config_validate::process_terminated", &e.to_string());
|
||||
handle::Handle::notice_message("config_validate::process_terminated", e.to_string());
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -76,19 +76,17 @@ pub async fn delete_profile(index: String) -> CmdResult {
|
||||
|
||||
/// 修改profiles的配置
|
||||
#[tauri::command]
|
||||
pub async fn patch_profiles_config(
|
||||
profiles: IProfiles
|
||||
) -> CmdResult<bool> {
|
||||
pub async fn patch_profiles_config(profiles: IProfiles) -> CmdResult<bool> {
|
||||
println!("[cmd配置patch] 开始修改配置文件");
|
||||
|
||||
|
||||
// 保存当前配置,以便在验证失败时恢复
|
||||
let current_profile = Config::profiles().latest().current.clone();
|
||||
println!("[cmd配置patch] 当前配置: {:?}", current_profile);
|
||||
|
||||
|
||||
// 更新profiles配置
|
||||
println!("[cmd配置patch] 正在更新配置草稿");
|
||||
wrap_err!({ Config::profiles().draft().patch_config(profiles) })?;
|
||||
|
||||
|
||||
// 更新配置并进行验证
|
||||
match CoreManager::global().update_config().await {
|
||||
Ok((true, _)) => {
|
||||
@@ -102,7 +100,7 @@ pub async fn patch_profiles_config(
|
||||
Ok((false, error_msg)) => {
|
||||
println!("[cmd配置patch] 配置验证失败: {}", error_msg);
|
||||
Config::profiles().discard();
|
||||
|
||||
|
||||
// 如果验证失败,恢复到之前的配置
|
||||
if let Some(prev_profile) = current_profile {
|
||||
println!("[cmd配置patch] 尝试恢复到之前的配置: {}", prev_profile);
|
||||
@@ -124,7 +122,7 @@ pub async fn patch_profiles_config(
|
||||
Err(e) => {
|
||||
println!("[cmd配置patch] 更新过程发生错误: {}", e);
|
||||
Config::profiles().discard();
|
||||
handle::Handle::notice_message("config_validate::boot_error", &e.to_string());
|
||||
handle::Handle::notice_message("config_validate::boot_error", e.to_string());
|
||||
Ok(false)
|
||||
}
|
||||
}
|
||||
@@ -134,9 +132,12 @@ pub async fn patch_profiles_config(
|
||||
#[tauri::command]
|
||||
pub async fn patch_profiles_config_by_profile_index(
|
||||
_app_handle: tauri::AppHandle,
|
||||
profile_index: String
|
||||
profile_index: String,
|
||||
) -> CmdResult<bool> {
|
||||
let profiles = IProfiles{current: Some(profile_index), items: None};
|
||||
let profiles = IProfiles {
|
||||
current: Some(profile_index),
|
||||
items: None,
|
||||
};
|
||||
patch_profiles_config(profiles).await
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
use crate::{
|
||||
config::*,
|
||||
wrap_err,
|
||||
};
|
||||
use super::CmdResult;
|
||||
use crate::{config::*, wrap_err};
|
||||
use anyhow::Context;
|
||||
use std::collections::HashMap;
|
||||
use serde_yaml::Mapping;
|
||||
use std::collections::HashMap;
|
||||
|
||||
/// 获取运行时配置
|
||||
#[tauri::command]
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
use crate::{
|
||||
config::*,
|
||||
core::*,
|
||||
utils::dirs,
|
||||
wrap_err,
|
||||
};
|
||||
use super::CmdResult;
|
||||
use crate::{config::*, core::*, utils::dirs, wrap_err};
|
||||
use std::fs;
|
||||
|
||||
/// 保存profiles的配置
|
||||
@@ -20,7 +15,7 @@ pub async fn save_profile_file(index: String, file_data: Option<String>) -> CmdR
|
||||
let profiles_guard = profiles.latest();
|
||||
let item = wrap_err!(profiles_guard.get_item(&index))?;
|
||||
// 确定是否为merge类型文件
|
||||
let is_merge = item.itype.as_ref().map_or(false, |t| t == "merge");
|
||||
let is_merge = item.itype.as_ref().is_some_and(|t| t == "merge");
|
||||
let content = wrap_err!(item.read_file())?;
|
||||
let path = item.file.clone().ok_or("file field is null")?;
|
||||
let profiles_dir = wrap_err!(dirs::app_profiles_dir())?;
|
||||
@@ -29,14 +24,20 @@ pub async fn save_profile_file(index: String, file_data: Option<String>) -> CmdR
|
||||
|
||||
// 保存新的配置文件
|
||||
wrap_err!(fs::write(&file_path, file_data.clone().unwrap()))?;
|
||||
|
||||
|
||||
let file_path_str = file_path.to_string_lossy().to_string();
|
||||
println!("[cmd配置save] 开始验证配置文件: {}, 是否为merge文件: {}", file_path_str, is_merge_file);
|
||||
|
||||
println!(
|
||||
"[cmd配置save] 开始验证配置文件: {}, 是否为merge文件: {}",
|
||||
file_path_str, is_merge_file
|
||||
);
|
||||
|
||||
// 对于 merge 文件,只进行语法验证,不进行后续内核验证
|
||||
if is_merge_file {
|
||||
println!("[cmd配置save] 检测到merge文件,只进行语法验证");
|
||||
match CoreManager::global().validate_config_file(&file_path_str, Some(true)).await {
|
||||
match CoreManager::global()
|
||||
.validate_config_file(&file_path_str, Some(true))
|
||||
.await
|
||||
{
|
||||
Ok((true, _)) => {
|
||||
println!("[cmd配置save] merge文件语法验证通过");
|
||||
// 成功后尝试更新整体配置
|
||||
@@ -63,9 +64,12 @@ pub async fn save_profile_file(index: String, file_data: Option<String>) -> CmdR
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 非merge文件使用完整验证流程
|
||||
match CoreManager::global().validate_config_file(&file_path_str, None).await {
|
||||
match CoreManager::global()
|
||||
.validate_config_file(&file_path_str, None)
|
||||
.await
|
||||
{
|
||||
Ok((true, _)) => {
|
||||
println!("[cmd配置save] 验证成功");
|
||||
Ok(())
|
||||
@@ -74,16 +78,17 @@ pub async fn save_profile_file(index: String, file_data: Option<String>) -> CmdR
|
||||
println!("[cmd配置save] 验证失败: {}", error_msg);
|
||||
// 恢复原始配置文件
|
||||
wrap_err!(fs::write(&file_path, original_content))?;
|
||||
|
||||
|
||||
// 智能判断错误类型
|
||||
let is_script_error = file_path_str.ends_with(".js") ||
|
||||
error_msg.contains("Script syntax error") ||
|
||||
error_msg.contains("Script must contain a main function") ||
|
||||
error_msg.contains("Failed to read script file");
|
||||
|
||||
if error_msg.contains("YAML syntax error") ||
|
||||
error_msg.contains("Failed to read file:") ||
|
||||
(!file_path_str.ends_with(".js") && !is_script_error) {
|
||||
let is_script_error = file_path_str.ends_with(".js")
|
||||
|| error_msg.contains("Script syntax error")
|
||||
|| error_msg.contains("Script must contain a main function")
|
||||
|| error_msg.contains("Failed to read script file");
|
||||
|
||||
if error_msg.contains("YAML syntax error")
|
||||
|| error_msg.contains("Failed to read file:")
|
||||
|| (!file_path_str.ends_with(".js") && !is_script_error)
|
||||
{
|
||||
// 普通YAML错误使用YAML通知处理
|
||||
println!("[cmd配置save] YAML配置文件验证失败,发送通知");
|
||||
let result = (false, error_msg.clone());
|
||||
@@ -98,7 +103,7 @@ pub async fn save_profile_file(index: String, file_data: Option<String>) -> CmdR
|
||||
println!("[cmd配置save] 其他类型验证失败,发送一般通知");
|
||||
handle::Handle::notice_message("config_validate::error", &error_msg);
|
||||
}
|
||||
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Err(e) => {
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
use super::CmdResult;
|
||||
use crate::core::handle;
|
||||
use crate::module::sysinfo::PlatformSpecification;
|
||||
use crate::{
|
||||
core::{self, handle, service, CoreManager},
|
||||
module::sysinfo::PlatformSpecification,
|
||||
wrap_err,
|
||||
};
|
||||
use tauri_plugin_clipboard_manager::ClipboardExt;
|
||||
use crate::{core::{self, CoreManager, service}, wrap_err};
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn export_diagnostic_info() -> CmdResult<()> {
|
||||
@@ -11,8 +13,7 @@ pub async fn export_diagnostic_info() -> CmdResult<()> {
|
||||
|
||||
let app_handle = handle::Handle::global().app_handle().unwrap();
|
||||
let cliboard = app_handle.clipboard();
|
||||
|
||||
if let Err(_) = cliboard.write_text(info) {
|
||||
if cliboard.write_text(info).is_err() {
|
||||
log::error!(target: "app", "Failed to write to clipboard");
|
||||
}
|
||||
Ok(())
|
||||
|
||||
@@ -4,8 +4,7 @@ use super::CmdResult;
|
||||
#[cfg(windows)]
|
||||
mod platform {
|
||||
use super::CmdResult;
|
||||
use crate::core::win_uwp;
|
||||
use crate::wrap_err;
|
||||
use crate::{core::win_uwp, wrap_err};
|
||||
|
||||
pub async fn invoke_uwp_tool() -> CmdResult {
|
||||
wrap_err!(win_uwp::invoke_uwptools().await)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::core::*;
|
||||
use super::CmdResult;
|
||||
use crate::core::*;
|
||||
|
||||
/// 发送脚本验证通知消息
|
||||
#[tauri::command]
|
||||
@@ -13,7 +13,7 @@ pub async fn script_validate_notice(status: String, msg: String) -> CmdResult {
|
||||
pub fn handle_script_validation_notice(result: &(bool, String), file_type: &str) {
|
||||
if !result.0 {
|
||||
let error_msg = &result.1;
|
||||
|
||||
|
||||
// 根据错误消息内容判断错误类型
|
||||
let status = if error_msg.starts_with("File not found:") {
|
||||
"config_validate::file_not_found"
|
||||
@@ -27,7 +27,7 @@ pub fn handle_script_validation_notice(result: &(bool, String), file_type: &str)
|
||||
// 如果是其他类型错误,作为一般脚本错误处理
|
||||
"config_validate::script_error"
|
||||
};
|
||||
|
||||
|
||||
log::warn!(target: "app", "{} 验证失败: {}", file_type, error_msg);
|
||||
handle::Handle::notice_message(status, error_msg);
|
||||
}
|
||||
@@ -37,12 +37,15 @@ pub fn handle_script_validation_notice(result: &(bool, String), file_type: &str)
|
||||
#[tauri::command]
|
||||
pub async fn validate_script_file(file_path: String) -> CmdResult<bool> {
|
||||
log::info!(target: "app", "验证脚本文件: {}", file_path);
|
||||
|
||||
match CoreManager::global().validate_config_file(&file_path, None).await {
|
||||
|
||||
match CoreManager::global()
|
||||
.validate_config_file(&file_path, None)
|
||||
.await
|
||||
{
|
||||
Ok(result) => {
|
||||
handle_script_validation_notice(&result, "脚本文件");
|
||||
Ok(result.0) // 返回验证结果布尔值
|
||||
},
|
||||
Ok(result.0) // 返回验证结果布尔值
|
||||
}
|
||||
Err(e) => {
|
||||
let error_msg = e.to_string();
|
||||
log::error!(target: "app", "验证脚本文件过程发生错误: {}", error_msg);
|
||||
@@ -58,10 +61,10 @@ pub fn handle_yaml_validation_notice(result: &(bool, String), file_type: &str) {
|
||||
if !result.0 {
|
||||
let error_msg = &result.1;
|
||||
println!("[通知] 处理{}验证错误: {}", file_type, error_msg);
|
||||
|
||||
|
||||
// 检查是否为merge文件
|
||||
let is_merge_file = file_type.contains("合并");
|
||||
|
||||
|
||||
// 根据错误消息内容判断错误类型
|
||||
let status = if error_msg.starts_with("File not found:") {
|
||||
"config_validate::file_not_found"
|
||||
@@ -93,7 +96,7 @@ pub fn handle_yaml_validation_notice(result: &(bool, String), file_type: &str) {
|
||||
"config_validate::yaml_error"
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
log::warn!(target: "app", "{} 验证失败: {}", file_type, error_msg);
|
||||
println!("[通知] 发送通知: status={}, msg={}", status, error_msg);
|
||||
handle::Handle::notice_message(status, error_msg);
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
use crate::{
|
||||
config::*,
|
||||
feat,
|
||||
wrap_err,
|
||||
};
|
||||
use super::CmdResult;
|
||||
use crate::{config::*, feat, wrap_err};
|
||||
|
||||
/// 获取Verge配置
|
||||
#[tauri::command]
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
use crate::{
|
||||
core,
|
||||
config::*,
|
||||
feat,
|
||||
wrap_err,
|
||||
};
|
||||
use super::CmdResult;
|
||||
use crate::{config::*, core, feat, wrap_err};
|
||||
use reqwest_dav::list_cmd::ListFile;
|
||||
|
||||
/// 保存 WebDAV 配置
|
||||
|
||||
Reference in New Issue
Block a user