大量重构。重写日志输出

This commit is contained in:
Lkhsss
2025-03-15 16:10:11 +08:00
parent ad3436d405
commit 341a568683
8 changed files with 292 additions and 369 deletions

View File

@ -17,6 +17,6 @@ pub struct Cli {
pub output: Option<String>,
/// 强制覆盖保存开关
#[arg(short,long,name="强制覆盖开关")]
pub forcesave:bool
#[arg(short, long, name = "强制覆盖开关")]
pub forcesave: bool,
}

View File

@ -1,47 +1,51 @@
use chrono;
use env_logger::Builder;
use std::io::Write;
use colored::Color::{Blue, Cyan, Green, Red, Yellow};
use colored::Colorize;
use indicatif::MultiProgress;
use log::{LevelFilter, Log, Metadata, Record, SetLoggerError};
use std::sync::Arc;
pub struct Logger {}
impl Logger {
pub fn new() {
let mut builder = Builder::new();
if cfg!(debug_assertions) {
builder.filter(None, log::LevelFilter::Debug);
} else {
builder.filter(None, log::LevelFilter::Info);
}
builder.format(move |buf, record| {
writeln!(
buf,
"[{} {}] {}",
format!("{}", chrono::Local::now().format("%H:%M:%S")),
match record.level() {
log::Level::Error => {
let style = buf.default_level_style(log::Level::Error);
format!("{style}Error{style:#}")
}
log::Level::Warn => {
let style = buf.default_level_style(log::Level::Warn);
format!("{style}Warn{style:#}")
}
log::Level::Info => {
let style = buf.default_level_style(log::Level::Info);
format!("{style}Info{style:#}")
}
log::Level::Debug => {
let style = buf.default_level_style(log::Level::Debug);
format!("{style}Debug{style:#}")
}
log::Level::Trace => {
let style = buf.default_level_style(log::Level::Trace);
format!("{style}Trace{style:#}")
}
},
record.args(),
)
});
builder.init(); //初始化logger
}
// 自定义Logger将日志发送到MultiProgress
pub struct MultiProgressLogger {
mp: Arc<MultiProgress>,
}
impl Log for MultiProgressLogger {
fn enabled(&self, _metadata: &Metadata) -> bool {
true
}
fn log(&self, record: &Record) {
if self.enabled(record.metadata()) {
let level = match record.level() {
log::Level::Error => ("Error").color(Red),
log::Level::Warn => ("Warn").color(Yellow),
log::Level::Info => ("Info").color(Green),
log::Level::Debug => ("Debug").color(Blue),
log::Level::Trace => ("Debug").color(Cyan),
};
let message = format!(
"[{}][{}] {}",
chrono::Local::now().format("%H:%M:%S"),
level,
record.args()
);
self.mp.println(message).expect("Failed to print log");
}
}
fn flush(&self) {}
}
// 初始化日志系统
pub fn init_logger() -> Result<(), SetLoggerError> {
let logger = MultiProgressLogger {
mp: crate::MP.clone(),
};
log::set_boxed_logger(Box::new(logger))?;
if cfg!(debug_assertions) {
log::set_max_level(LevelFilter::Debug);
} else {
log::set_max_level(LevelFilter::Info);
}
Ok(())
}

View File

@ -1,7 +1,8 @@
use ::clap::Parser;
#[allow(unused_imports)]
use colored::{Color, Colorize};
use indicatif::{MultiProgress, ProgressBar, ProgressStyle};
use lazy_static::lazy_static;
use log::{error, info, warn};
use messager::Signals;
use std::time::Duration;
use std::{
path::Path,
@ -11,22 +12,19 @@ use std::{
},
};
use colored::Colorize;
use walkdir::WalkDir; //遍历目录
mod clap;
mod logger;
mod messager;
mod ncmdump;
mod pathparse;
mod test;
mod threadpool;
use ncmdump::Ncmfile;
mod test;
fn main() {
let timer = ncmdump::TimeCompare::new();
// 初始化日志系统
logger::Logger::new();
logger::init_logger().unwrap();
let cli = clap::Cli::parse();
@ -46,44 +44,12 @@ fn main() {
let outputdir = cli.output.unwrap();
let forcesave = cli.forcesave;
if forcesave{
warn!("文件强制覆盖已开启!")
if forcesave {
warn!("文件{}已开启!", "强制覆盖".bright_red())
}
let mut undumpfile = Vec::new(); // 该列表将存入文件的路径
let undumpfile = pathparse::pathparse(input); // 该列表将存入文件的路径
for arg in input {
//解析传入的每一个路径文件or文件夹
let path = Path::new(&arg);
if path.is_file() {
// 当后缀符合为ncm时才加入列表
match path.extension() {
Some(extension) => {
if extension == "ncm" {
let _ = &mut undumpfile.push(arg.to_owned());
}
}
None => {}
}
} else if path.is_dir() {
for entry in WalkDir::new(path) {
let new_entry = entry.unwrap().clone();
let filepath = new_entry.into_path();
// 当后缀符合为ncm时才加入列表
match filepath.extension() {
Some(extension) => {
if extension == "ncm" {
let _ = &mut undumpfile.push(String::from(filepath.to_str().unwrap()));
}
}
None => {
continue;
}
}
}
}
}
let taskcount = undumpfile.len();
let successful = Arc::new(Mutex::new(0));
if taskcount == 0 {
@ -91,7 +57,10 @@ fn main() {
} else {
// 初始化线程池
let pool = threadpool::Pool::new(max_workers);
info!("启用{}线程", max_workers);
info!(
"将启用{}线程",
max_workers.to_string().color(Color::BrightGreen)
);
// 初始化通讯
let (tx, rx) = mpsc::channel();
@ -101,7 +70,7 @@ fn main() {
let successful = Arc::clone(&successful);
let sender: Sender<messager::Message> = tx.clone();
pool.execute(move || match Ncmfile::new(filepath.as_str()) {
Ok(mut n) => match n.dump(Path::new(&output), sender,forcesave) {
Ok(mut n) => match n.dump(Path::new(&output), sender, forcesave) {
Ok(_) => {
let mut num = successful.lock().unwrap();
*num += 1;
@ -114,31 +83,21 @@ fn main() {
//循环到此结束
//进度条
use indicatif::ProgressBar;
let progressbar = ProgressBar::new((taskcount) as u64)
let pb = ProgressBar::new((taskcount * 6) as u64) //长度乘积取决于Signal的数量
.with_elapsed(Duration::from_millis(50))
.with_message("破解中");
.with_style(
ProgressStyle::default_bar()
.progress_chars("#>-")
.template("{spinner:.green} [{wide_bar:.cyan/blue}] {percent_precise}% ({eta})")
.unwrap(),
)
.with_message("解密中");
let progressbar = MP.add(pb);
//接受消息
for messages in rx {
match messages.signal {
Signals::Start => {
// progressbar.inc(1);
info!("[{}] 开始读取文件", messages.name)
}
Signals::Decrypt => {
// progressbar.inc(1);
info!("[{}] 开始解密", messages.name)
}
Signals::Save => {
// progressbar.inc(1);
info!("[{}] 保存文件", messages.name)
}
Signals::End => {
progressbar.inc(1);
info!("[{}] 成功!", messages.name)
}
}
progressbar.inc(1);
messages.log(); //发送log
}
progressbar.finish_and_clear();
@ -159,3 +118,7 @@ fn main() {
showtime()
)
}
lazy_static! {
static ref MP: Arc<MultiProgress> = Arc::new(MultiProgress::new());
}

View File

@ -1,3 +1,6 @@
use colored::Colorize;
use log::info;
use crate::messager;
use std::fmt::Debug;
use std::sync::mpsc;
@ -10,9 +13,24 @@ pub struct Message {
pub name: String,
pub signal: Signals,
}
impl Message {
// 定义一个公共方法 log用于记录不同信号状态下的日志信息
pub fn log(&self) {
let loginfo = match &self.signal {
Signals::Start => "读取文件",
Signals::GetMetaInfo => "解密歌曲元信息",
Signals::GetCover => "解密封面图片数据",
Signals::Decrypt => "解密歌曲信息",
Signals::Save => "保存文件",
Signals::End => "成功!",
};
info!("[{}] {}", self.name.cyan(), loginfo)
}
}
pub enum Signals {
Start,
GetMetaInfo,
GetCover,
Decrypt,
Save,
End,
@ -32,10 +50,12 @@ impl Messager {
impl Debug for Message {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let message = match &self.signal {
Signals::Start => "开始破解".to_string(),
Signals::Decrypt => "开始解密".to_string(),
Signals::Save => "保存文件".to_string(),
Signals::End => "破解完成".to_string(),
Signals::Start => "开始破解",
Signals::Decrypt => "开始解密",
Signals::Save => "保存文件",
Signals::End => "破解完成",
Signals::GetMetaInfo => "获取元数据",
Signals::GetCover => "获取封面",
};
write!(f, "[{}] {}", self.name, message)
}

View File

@ -152,11 +152,8 @@ impl Ncmfile {
&mut self,
outputdir: &Path,
tx: mpsc::Sender<messager::Message>,
force_save:bool
force_save: bool,
) -> Result<(), NcmError> {
let messager = messager::Messager::new(self.fullfilename.clone(), tx);
let _ = messager.send(Signals::Start);
//TODO 通讯合法化
@ -201,6 +198,7 @@ impl Ncmfile {
//读取meta信息的数据大小
trace!("获取meta信息数据大小");
let meta_length = u32::from_le_bytes(self.seekread(4)?.try_into().unwrap()) as u64;
let _ = messager.send(Signals::GetMetaInfo);
// 读取meta信息
trace!("读取meta信息");
@ -255,7 +253,7 @@ impl Ncmfile {
debug!("文件路径: {:?}", path);
// 先检查是否存在
if !force_save && Path::new(&path).exists(){
if !force_save && Path::new(&path).exists() {
return Err(NcmError::ProtectFile);
}
@ -268,6 +266,7 @@ impl Ncmfile {
trace!("跳过5个字节");
self.skip(5)?;
let _ = messager.send(Signals::GetCover);
// 获取图片数据的大小
trace!("获取图片数据的大小");
let image_data_length = u32::from_le_bytes(self.seekread(4)?.try_into().unwrap()) as u64;
@ -367,7 +366,6 @@ impl Ncmfile {
//退出循环,写入文件
let _ = messager.send(Signals::Save);
self.save(&path, music_data)?;
@ -399,7 +397,6 @@ impl Ncmfile {
Ok(())
}
fn save(&mut self, path: &PathBuf, data: Vec<u8>) -> Result<(), NcmError> {
let music_file = match File::create(path) {
Ok(o) => o,
Err(_) => return Err(NcmError::FileWriteError),
@ -590,7 +587,10 @@ impl std::fmt::Display for NcmError {
Self::FileReadError => write!(f, "读取文件时发生错误"),
Self::FileWriteError => write!(f, "写入文件时错误"),
Self::FullFilenameError => write!(f, "文件名不符合规范"),
Self::ProtectFile=>write!(f, "已关闭文件强制覆盖且文件已存在。使用-f或-forcesave开启强制覆盖。"),
Self::ProtectFile => write!(
f,
"已关闭文件强制覆盖且文件已存在。使用-f或-forcesave开启强制覆盖。"
),
_ => write!(f, "未知错误"),
}
}

40
src/pathparse.rs Normal file
View File

@ -0,0 +1,40 @@
use std::path::Path;
use walkdir::WalkDir;
pub fn pathparse(input: Vec<String>) -> Vec<String> {
let mut undumpfile = Vec::new(); // 该列表将存入文件的路径
// 遍历输入的每一个路径参数
for arg in input {
//解析传入的每一个路径文件or文件夹
let path = Path::new(&arg);
if path.is_file() {
// 当后缀符合为ncm时才加入列表
match path.extension() {
Some(extension) => {
if extension == "ncm" {
let _ = &mut undumpfile.push(arg.to_owned());
}
}
None => {}
}
} else if path.is_dir() {
for entry in WalkDir::new(path) {
let new_entry = entry.unwrap().clone();
let filepath = new_entry.into_path();
// 当后缀符合为ncm时才加入列表
match filepath.extension() {
Some(extension) => {
if extension == "ncm" {
let _ = &mut undumpfile.push(String::from(filepath.to_str().unwrap()));
}
}
None => {
continue;
}
}
}
}
}
undumpfile
}