mirror of https://github.com/jackwener/wx-cli.git
Merge 3aa5984a9e into 08af894594
commit
904b3d9cba
|
|
@ -233,6 +233,11 @@ fn detect_db_dir_impl() -> Option<PathBuf> {
|
|||
let home = sudo_user_home_dir().or_else(dirs::home_dir)?;
|
||||
|
||||
let base = home.join("Library/Containers/com.tencent.xinWeChat/Data/Documents/xwechat_files");
|
||||
detect_db_dir_under(&base)
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
fn detect_db_dir_under(base: &Path) -> Option<PathBuf> {
|
||||
if !base.exists() {
|
||||
return None;
|
||||
}
|
||||
|
|
@ -245,11 +250,7 @@ fn detect_db_dir_impl() -> Option<PathBuf> {
|
|||
}
|
||||
}
|
||||
}
|
||||
candidates.sort_by_key(|p| {
|
||||
std::fs::metadata(p)
|
||||
.and_then(|m| m.modified())
|
||||
.unwrap_or(std::time::SystemTime::UNIX_EPOCH)
|
||||
});
|
||||
candidates.sort_by_key(|p| latest_db_mtime(p).unwrap_or(std::time::SystemTime::UNIX_EPOCH));
|
||||
candidates.into_iter().next_back()
|
||||
}
|
||||
|
||||
|
|
@ -284,7 +285,7 @@ fn detect_db_dir_impl() -> Option<PathBuf> {
|
|||
candidates.into_iter().next_back()
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "windows"))]
|
||||
#[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))]
|
||||
/// 递归查找 db_storage 目录下所有 .db 文件的最新 mtime
|
||||
fn latest_db_mtime(dir: &Path) -> Option<std::time::SystemTime> {
|
||||
let mut latest = None;
|
||||
|
|
@ -416,8 +417,8 @@ fn detect_db_dir_impl() -> Option<PathBuf> {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{
|
||||
config_path_in_dir, default_config_path, find_existing_config_path, home_config_path,
|
||||
resolve_cli_home,
|
||||
config_path_in_dir, default_config_path, detect_db_dir_under, find_existing_config_path,
|
||||
home_config_path, resolve_cli_home,
|
||||
};
|
||||
#[cfg(target_os = "windows")]
|
||||
use super::{known_documents_dir, resolve_windows_data_root};
|
||||
|
|
@ -480,6 +481,34 @@ mod tests {
|
|||
assert_eq!(path, cwd.join("config.json"));
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[test]
|
||||
fn auto_detect_db_dir_prefers_latest_db_file_mtime_over_directory_mtime() {
|
||||
let home = temp_dir("macos-home");
|
||||
|
||||
let base = home.join("Library/Containers/com.tencent.xinWeChat/Data/Documents/xwechat_files");
|
||||
let active_db_dir = base.join("wxid_active/db_storage");
|
||||
let stale_db_dir = base.join("wxid_stale/db_storage");
|
||||
let active_db_file = active_db_dir.join("message/session.db");
|
||||
let stale_db_file = stale_db_dir.join("message/session.db");
|
||||
|
||||
fs::create_dir_all(active_db_file.parent().unwrap()).unwrap();
|
||||
fs::write(&active_db_file, b"active").unwrap();
|
||||
fs::create_dir_all(stale_db_file.parent().unwrap()).unwrap();
|
||||
fs::write(&stale_db_file, b"stale").unwrap();
|
||||
set_file_mtime(
|
||||
&active_db_file,
|
||||
SystemTime::now()
|
||||
.checked_add(std::time::Duration::from_secs(3600))
|
||||
.unwrap(),
|
||||
);
|
||||
|
||||
let detected = detect_db_dir_under(&base).unwrap();
|
||||
assert_eq!(detected, active_db_dir);
|
||||
|
||||
fs::remove_dir_all(home).unwrap();
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
#[test]
|
||||
fn resolve_windows_data_root_passes_through_absolute_path() {
|
||||
|
|
@ -499,4 +528,28 @@ mod tests {
|
|||
assert_eq!(resolved, docs, "keyword {keyword:?}");
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn set_file_mtime(path: &std::path::Path, mtime: SystemTime) {
|
||||
use std::ffi::CString;
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
use std::time::Duration;
|
||||
|
||||
let dur = mtime
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap_or(Duration::from_secs(0));
|
||||
let times = [
|
||||
libc::timeval {
|
||||
tv_sec: dur.as_secs() as libc::time_t,
|
||||
tv_usec: dur.subsec_micros() as libc::suseconds_t,
|
||||
},
|
||||
libc::timeval {
|
||||
tv_sec: dur.as_secs() as libc::time_t,
|
||||
tv_usec: dur.subsec_micros() as libc::suseconds_t,
|
||||
},
|
||||
];
|
||||
let c_path = CString::new(path.as_os_str().as_bytes()).unwrap();
|
||||
let rc = unsafe { libc::utimes(c_path.as_ptr(), times.as_ptr()) };
|
||||
assert_eq!(rc, 0, "failed to update mtime for {}", path.display());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue