Fix code quality: trailing whitespace, unused imports, clippy warnings

- Fix trailing whitespace in kex.rs and s3.rs
- Add missing KexProposal import in kex_complete.rs
- Auto-fix clippy warnings across all crates
- All 153 tests pass
This commit is contained in:
Warren
2026-06-19 05:21:38 +08:00
parent 4b37e524cf
commit d94cb2df4c
135 changed files with 7256 additions and 4321 deletions

View File

@@ -1,22 +1,23 @@
use anyhow::Context;
use axum::{
extract::DefaultBodyLimit,
extract::{Path, Query, State},
http::{HeaderMap, StatusCode},
response::{Html, IntoResponse, Json},
routing::{delete, get, patch, post, put},
Router,
extract::DefaultBodyLimit,
};
use serde::Deserialize;
use std::str::FromStr;
use std::sync::{Arc, Mutex};
use crate::archive::{
ArchiveConfig, ArchiveFormat, ArchiveProcessor, FormatDetector, ProcessorRegistry,
};
use crate::audio;
use crate::auth::{AuthState, LoginRequest};
use crate::provider::sqlite::SqliteProvider;
use crate::render;
use crate::download;
use crate::archive::{self, ArchiveFormat, ArchiveProcessor, FormatDetector, ArchiveConfig, ProcessorRegistry};
use filetree::{self, FileTree};
#[derive(Clone)]
@@ -60,7 +61,7 @@ pub async fn run(port: u16, file: Option<String>) -> anyhow::Result<()> {
db_dir: "data/users".to_string(),
auth: AuthState::with_provider(Box::new(
SqliteProvider::new("data/auth.sqlite")
.map_err(|e| anyhow::anyhow!("Failed to init SqliteProvider: {}", e))?
.map_err(|e| anyhow::anyhow!("Failed to init SqliteProvider: {}", e))?,
)),
auth_db_path: "data/auth.sqlite".to_string(),
s3_keys: Arc::new(Mutex::new(load_s3_keys())),
@@ -578,7 +579,7 @@ async fn search_tree(
ORDER BY sort_order ASC, created_at ASC",
)?;
let nodes: Vec<filetree::node::FileNode> = stmt
let _nodes: Vec<filetree::node::FileNode> = stmt
.query_map([&search_pattern], |row| {
let children_json: String = row.get(6)?;
let children: Vec<String> =
@@ -607,7 +608,7 @@ async fn search_tree(
.filter_map(|r| r.ok())
.collect();
let tree = filetree::FileTree {
let tree = filetree::FileTree {
user_id: user_id.clone(),
tree_type: "untitled folder".to_string(),
nodes: vec![],
@@ -914,69 +915,78 @@ fn extract_and_register_archive(
user_id: &str,
original_filename: &str,
) -> anyhow::Result<(u64, u64, String)> {
use std::path::PathBuf;
use sha2::{Sha256, Digest};
use sha2::{Digest, Sha256};
// Initialize archive system
let config = ArchiveConfig::default();
let mut registry = ProcessorRegistry::new(config);
registry.initialize()?;
// Detect format
let detector = FormatDetector::new();
let format = detector.detect(archive_path)?;
eprintln!("[archive] Detected format: {} for file: {}", format, archive_path.display());
eprintln!(
"[archive] Detected format: {} for file: {}",
format,
archive_path.display()
);
// Get processor
let processor = registry.get_processor_mut(archive_path)?;
// Create extraction directory
let base_name = original_filename
.rsplit_once('.')
.map(|(name, _)| name)
.unwrap_or(original_filename);
let extraction_dir = archive_path.parent()
let extraction_dir = archive_path
.parent()
.unwrap_or(std::path::Path::new("."))
.join(format!("{}_extracted", base_name));
std::fs::create_dir_all(&extraction_dir)?;
// Open and extract
let metadata = processor.open(archive_path)?;
eprintln!("[archive] Archive metadata: {} files, {} bytes",
metadata.total_files, metadata.total_size);
eprintln!(
"[archive] Archive metadata: {} files, {} bytes",
metadata.total_files, metadata.total_size
);
let result = processor.extract_all(&extraction_dir)?;
eprintln!("[archive] Extracted {} files ({} bytes)",
result.success_files, result.total_bytes);
eprintln!(
"[archive] Extracted {} files ({} bytes)",
result.success_files, result.total_bytes
);
// Register extracted files to database
let conn = FileTree::init_user_db(user_id)?;
let now = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_secs() as i64;
// Get MAC address for UUID generation
let mac_output = std::process::Command::new("ifconfig")
.arg("en0")
.output()
.map(|o| String::from_utf8_lossy(&o.stdout).to_string())
.unwrap_or_default();
let mac = mac_output
.lines()
.find(|l| l.contains("ether"))
.and_then(|l| l.split_whitespace().nth(1))
.unwrap_or("00:00:00:00:00:00");
let mut registered_count = 0u64;
// Recursively scan extracted directory
fn scan_directory(
dir: &std::path::Path,
@@ -986,11 +996,11 @@ fn extract_and_register_archive(
now: i64,
) -> anyhow::Result<u64> {
let mut count = 0u64;
for entry in std::fs::read_dir(dir)? {
let entry = entry?;
let path = entry.path();
if path.is_dir() {
count += scan_directory(&path, conn, user_id, mac, now)?;
} else if path.is_file() {
@@ -998,16 +1008,15 @@ fn extract_and_register_archive(
let file_data = std::fs::read(&path)?;
let file_hash = format!("{:x}", Sha256::digest(&file_data));
let file_size = file_data.len() as i64;
let filename = path.file_name()
let filename = path
.file_name()
.and_then(|n| n.to_str())
.unwrap_or("unknown")
.to_string();
let file_path_str = path.to_str()
.unwrap_or("unknown")
.to_string();
let file_path_str = path.to_str().unwrap_or("unknown").to_string();
// Generate file UUID
let mtime = std::fs::metadata(&path)
.ok()
@@ -1015,48 +1024,55 @@ fn extract_and_register_archive(
.and_then(|t| t.duration_since(std::time::UNIX_EPOCH).ok())
.map(|d| d.as_millis() as u64)
.unwrap_or(0);
let input = format!("{}|{}|{}|{}", file_path_str, filename, mac, mtime);
let hash = Sha256::digest(input.as_bytes());
let hex = format!("{:x}", hash);
let file_uuid = hex[0..32].to_string();
// Register file (no sha256 in file_registry)
conn.execute(
"INSERT INTO file_registry (file_uuid, original_name, file_size, file_type, registered_at)
VALUES (?1, ?2, ?3, ?4, ?5)",
rusqlite::params![&file_uuid, &filename, file_size, "", now],
)?;
// Add file location
conn.execute(
"INSERT OR IGNORE INTO file_locations (file_uuid, location, added_at)
VALUES (?1, ?2, ?3)",
rusqlite::params![&file_uuid, &file_path_str, now],
)?;
// Add file node
let uuid_str = uuid::Uuid::new_v4().to_string().replace('-', "");
let node_id = format!("node-{}", &uuid_str[0..8]);
conn.execute(
"INSERT INTO file_nodes (node_id, label, file_uuid, sha256, node_type, file_size, created_at, updated_at)
VALUES (?1, ?2, ?3, ?4, 'file', ?5, ?6, ?7)",
rusqlite::params![&node_id, &filename, &file_uuid, &file_hash, file_size, now, now],
)?;
count += 1;
}
}
Ok(count)
}
registered_count = scan_directory(&extraction_dir, &conn, user_id, mac, now)?;
eprintln!("[archive] Registered {} extracted files to database", registered_count);
Ok((result.success_files, result.total_bytes, extraction_dir.to_str().unwrap_or("unknown").to_string()))
eprintln!(
"[archive] Registered {} extracted files to database",
registered_count
);
Ok((
result.success_files,
result.total_bytes,
extraction_dir.to_str().unwrap_or("unknown").to_string(),
))
}
async fn upload_file(
@@ -1147,23 +1163,23 @@ async fn upload_file(
// Auto-extract archive files
let file_path_buf = std::path::PathBuf::from(&file_path);
let detector = FormatDetector::new();
if let Ok(format) = detector.detect(&file_path_buf) {
if format != ArchiveFormat::Unknown {
eprintln!("[upload] Detected archive format: {}, extracting...", format);
eprintln!(
"[upload] Detected archive format: {}, extracting...",
format
);
let user_id_clone = user_id.clone();
let filename_clone = filename.clone();
// Extract in blocking thread
let extraction_result = tokio::task::spawn_blocking(move || {
extract_and_register_archive(
&file_path_buf,
&user_id_clone,
&filename_clone,
)
}).await;
extract_and_register_archive(&file_path_buf, &user_id_clone, &filename_clone)
})
.await;
match extraction_result {
Ok(Ok((count, bytes, extract_dir))) => {
extracted_info = Some((count, bytes, extract_dir));
@@ -1208,13 +1224,13 @@ async fn upload_file(
let hex = format!("{:x}", hash);
let file_uuid = hex[0..32].to_string();
// Save to database (user-specific SQLite)
// Save to database (user-specific SQLite)
let file_uuid_clone = file_uuid.clone();
let file_hash_clone = file_hash.clone();
let filename_clone = filename.clone();
let file_path_clone = file_path.clone();
let user_id_clone = user_id.clone();
let db_result = tokio::task::spawn_blocking(move || -> anyhow::Result<()> {
let conn = filetree::FileTree::init_user_db(&user_id_clone)?;
@@ -1281,7 +1297,7 @@ async fn upload_file(
"sha256": file_hash,
"size": file_size,
});
if let Some((count, bytes, extract_dir)) = extracted_info {
response["extracted"] = serde_json::json!({
"count": count,
@@ -1289,12 +1305,8 @@ async fn upload_file(
"directory": extract_dir,
});
}
(
StatusCode::CREATED,
Json(response),
)
.into_response()
(StatusCode::CREATED, Json(response)).into_response()
}
async fn upload_unlimited(
@@ -1798,7 +1810,7 @@ async fn logout_handler(State(state): State<AppState>, headers: HeaderMap) -> im
let auth_header = headers
.get("Authorization")
.and_then(|h| h.to_str().ok())
.and_then(|h| crate::auth::parse_auth_header(h));
.and_then(crate::auth::parse_auth_header);
match auth_header {
Some(token) => {
@@ -1824,7 +1836,7 @@ async fn verify_handler(State(state): State<AppState>, headers: HeaderMap) -> im
let auth_header = headers
.get("Authorization")
.and_then(|h| h.to_str().ok())
.and_then(|h| crate::auth::parse_auth_header(h));
.and_then(crate::auth::parse_auth_header);
match auth_header {
Some(token) => match state.auth.verify_token(&token) {
@@ -1857,7 +1869,7 @@ fn verify_auth(state: &AppState, headers: &HeaderMap) -> Result<String, StatusCo
let auth_header = headers
.get("Authorization")
.and_then(|h| h.to_str().ok())
.and_then(|h| crate::auth::parse_auth_header(h));
.and_then(crate::auth::parse_auth_header);
match auth_header {
Some(token) => match state.auth.verify_token(&token) {
@@ -2039,7 +2051,7 @@ async fn edit_config_handler(Query(params): Query<EditConfigQuery>) -> impl Into
match crate::config::MarkBaseConfig::load(config_path) {
Ok(mut config) => {
let old_value = config.get(&params.key).unwrap_or_default();
match config.set(&params.key, &params.value) {
Ok(_) => match config.validate() {
Ok(_) => match config.save(config_path) {
@@ -2056,7 +2068,7 @@ async fn edit_config_handler(Query(params): Query<EditConfigQuery>) -> impl Into
) {
log::warn!("Failed to write audit log: {}", e);
}
(StatusCode::OK, Json(serde_json::json!({"ok": true}))).into_response()
}
Err(e) => (
@@ -2133,7 +2145,7 @@ async fn edit_s3_config_handler(Query(params): Query<EditConfigQuery>) -> impl I
match crate::s3_config::S3Config::load_default() {
Ok(mut config) => {
let old_value = config.get(&params.key).unwrap_or_default();
match config.set(&params.key, &params.value) {
Ok(_) => match config.validate() {
Ok(_) => match config.save("config/s3.toml") {
@@ -2150,7 +2162,7 @@ async fn edit_s3_config_handler(Query(params): Query<EditConfigQuery>) -> impl I
) {
log::warn!("Failed to write audit log: {}", e);
}
(StatusCode::OK, Json(serde_json::json!({"ok": true}))).into_response()
}
Err(e) => (
@@ -2343,7 +2355,7 @@ async fn audit_handler() -> Json<serde_json::Value> {
// Category View API handlers (Phase 1: 双视图管理)
async fn get_all_categories_handler() -> impl IntoResponse {
let base_path = std::path::Path::new("/Users/accusys/markbase");
let _base_path = std::path::Path::new("/Users/accusys/markbase");
match crate::category_view::get_all_categories() {
Ok(response) => (StatusCode::OK, Json(response)).into_response(),
Err(e) => (
@@ -2354,10 +2366,8 @@ async fn get_all_categories_handler() -> impl IntoResponse {
}
}
async fn get_category_detail_handler(
Path(category_name): Path<String>,
) -> impl IntoResponse {
let base_path = std::path::Path::new("/Users/accusys/markbase");
async fn get_category_detail_handler(Path(category_name): Path<String>) -> impl IntoResponse {
let _base_path = std::path::Path::new("/Users/accusys/markbase");
match crate::category_view::get_category_detail(&category_name) {
Ok(response) => (StatusCode::OK, Json(response)).into_response(),
Err(e) => (
@@ -2369,7 +2379,7 @@ async fn get_category_detail_handler(
}
async fn get_all_series_handler() -> impl IntoResponse {
let base_path = std::path::Path::new("/Users/accusys/markbase");
let _base_path = std::path::Path::new("/Users/accusys/markbase");
match crate::category_view::get_all_series() {
Ok(response) => (StatusCode::OK, Json(response)).into_response(),
Err(e) => (
@@ -2380,10 +2390,8 @@ async fn get_all_series_handler() -> impl IntoResponse {
}
}
async fn get_series_detail_handler(
Path(series_name): Path<String>,
) -> impl IntoResponse {
let base_path = std::path::Path::new("/Users/accusys/markbase");
async fn get_series_detail_handler(Path(series_name): Path<String>) -> impl IntoResponse {
let _base_path = std::path::Path::new("/Users/accusys/markbase");
match crate::category_view::get_series_detail(&series_name) {
Ok(response) => (StatusCode::OK, Json(response)).into_response(),
Err(e) => (
@@ -2400,10 +2408,8 @@ struct SearchQuery {
view: String,
}
async fn search_files_handler(
Query(query): Query<SearchQuery>,
) -> impl IntoResponse {
let base_path = std::path::Path::new("/Users/accusys/markbase");
async fn search_files_handler(Query(query): Query<SearchQuery>) -> impl IntoResponse {
let _base_path = std::path::Path::new("/Users/accusys/markbase");
match crate::category_view::search_files(&query.q, &query.view) {
Ok(response) => (StatusCode::OK, Json(response)).into_response(),
Err(e) => (