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:
@@ -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(¶ms.key).unwrap_or_default();
|
||||
|
||||
|
||||
match config.set(¶ms.key, ¶ms.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(¶ms.key).unwrap_or_default();
|
||||
|
||||
|
||||
match config.set(¶ms.key, ¶ms.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) => (
|
||||
|
||||
Reference in New Issue
Block a user