Files
markbase/markbase-core/src/download/storage.rs
Warren d94cb2df4c 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
2026-06-19 05:21:38 +08:00

124 lines
3.6 KiB
Rust

use serde::{Deserialize, Serialize};
use std::path::Path;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FileInfo {
pub filename: String,
pub file_size: u64,
pub file_hash: Option<String>,
pub file_path: String,
pub relative_path: String,
pub upload_time: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FileListResponse {
pub user_id: String,
pub base_path: String,
pub files: Vec<FileInfo>,
pub total_files: usize,
pub total_size: u64,
}
pub fn scan_uploaded_files(user_id: &str) -> FileListResponse {
let base_path = format!("/Users/accusys/Downloads/{}", user_id);
let path = Path::new(&base_path);
let mut files = Vec::new();
let mut total_size = 0u64;
if path.exists() {
scan_directory_recursive(path, path, &mut files, &mut total_size);
}
FileListResponse {
user_id: user_id.to_string(),
base_path,
total_files: files.len(),
total_size,
files,
}
}
fn scan_directory_recursive(
base: &Path,
current: &Path,
files: &mut Vec<FileInfo>,
total_size: &mut u64,
) {
if let Ok(entries) = std::fs::read_dir(current) {
for entry in entries.flatten() {
let path = entry.path();
if path.is_file() {
let filename = path
.file_name()
.and_then(|n| n.to_str())
.unwrap_or("unknown")
.to_string();
let file_size = entry.metadata().map(|m| m.len()).unwrap_or(0);
let relative_path = path
.strip_prefix(base)
.ok()
.and_then(|p| p.to_str())
.map(|s| s.to_string())
.unwrap_or_else(|| filename.clone());
let upload_time = entry
.metadata()
.ok()
.and_then(|m| m.modified().ok())
.and_then(|t| {
let duration = t.duration_since(std::time::UNIX_EPOCH).ok()?;
chrono::DateTime::from_timestamp(duration.as_secs() as i64, 0)
.map(|dt| dt.format("%Y-%m-%dT%H:%M:%SZ").to_string())
})
.unwrap_or_else(|| chrono::Utc::now().format("%Y-%m-%dT%H:%M:%SZ").to_string());
let file_hash = if file_size > 0 {
compute_file_hash(&path).ok()
} else {
Some(
"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
.to_string(),
)
};
files.push(FileInfo {
filename,
file_size,
file_hash,
file_path: path.to_string_lossy().to_string(),
relative_path,
upload_time,
});
*total_size += file_size;
} else if path.is_dir() {
scan_directory_recursive(base, &path, files, total_size);
}
}
}
}
pub fn compute_file_hash(path: &Path) -> Result<String, std::io::Error> {
use sha2::{Digest, Sha256};
use std::io::Read;
let mut file = std::fs::File::open(path)?;
let mut hasher = Sha256::new();
let mut buffer = [0u8; 8192];
loop {
let bytes_read = file.read(&mut buffer)?;
if bytes_read == 0 {
break;
}
hasher.update(&buffer[..bytes_read]);
}
Ok(format!("{:x}", hasher.finalize()))
}