add logging
This commit is contained in:
@@ -46,6 +46,13 @@ pub struct ProgressEvent {
|
||||
pub status: String, // "downloading", "processing", "finished", "error"
|
||||
}
|
||||
|
||||
#[derive(Serialize, Clone, Debug)]
|
||||
pub struct LogEvent {
|
||||
pub id: String,
|
||||
pub message: String,
|
||||
pub level: String, // "info", "error"
|
||||
}
|
||||
|
||||
pub async fn fetch_metadata(app: &AppHandle, url: &str, parse_mix_playlist: bool) -> Result<MetadataResult> {
|
||||
let ytdlp_path = ytdlp::get_ytdlp_path(app)?;
|
||||
|
||||
@@ -148,31 +155,60 @@ pub async fn download_video(
|
||||
let mut child = Command::new(ytdlp_path)
|
||||
.args(&args)
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped())
|
||||
.stderr(Stdio::piped()) // Capture stderr for logs
|
||||
.spawn()?;
|
||||
|
||||
let stdout = child.stdout.take().ok_or(anyhow!("Failed to open stdout"))?;
|
||||
let mut reader = BufReader::new(stdout);
|
||||
let mut line = String::new();
|
||||
|
||||
// Regex for progress: [download] 42.5% of 10.00MiB at 2.00MiB/s ETA 00:05
|
||||
let stderr = child.stderr.take().ok_or(anyhow!("Failed to open stderr"))?;
|
||||
|
||||
let mut stdout_reader = BufReader::new(stdout);
|
||||
let mut stderr_reader = BufReader::new(stderr);
|
||||
|
||||
let re = Regex::new(r"\[download\]\s+(\d+\.?\d*)%").unwrap();
|
||||
|
||||
while reader.read_line(&mut line).await? > 0 {
|
||||
if let Some(caps) = re.captures(&line) {
|
||||
if let Some(pct_match) = caps.get(1) {
|
||||
if let Ok(pct) = pct_match.as_str().parse::<f64>() {
|
||||
// Emit event
|
||||
app.emit("download-progress", ProgressEvent {
|
||||
id: id.clone(),
|
||||
progress: pct,
|
||||
speed: "TODO".to_string(), // Speed parsing is a bit more complex, skipping for MVP or adding regex for it
|
||||
status: "downloading".to_string(),
|
||||
}).ok();
|
||||
// Loop to read both streams
|
||||
loop {
|
||||
let mut out_line = String::new();
|
||||
let mut err_line = String::new();
|
||||
|
||||
tokio::select! {
|
||||
res = stdout_reader.read_line(&mut out_line) => {
|
||||
if res.unwrap_or(0) == 0 {
|
||||
break; // EOF
|
||||
}
|
||||
|
||||
// Log info
|
||||
app.emit("download-log", LogEvent {
|
||||
id: id.clone(),
|
||||
message: out_line.trim().to_string(),
|
||||
level: "info".to_string(),
|
||||
}).ok();
|
||||
|
||||
// Parse progress
|
||||
if let Some(caps) = re.captures(&out_line) {
|
||||
if let Some(pct_match) = caps.get(1) {
|
||||
if let Ok(pct) = pct_match.as_str().parse::<f64>() {
|
||||
app.emit("download-progress", ProgressEvent {
|
||||
id: id.clone(),
|
||||
progress: pct,
|
||||
speed: "TODO".to_string(),
|
||||
status: "downloading".to_string(),
|
||||
}).ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
res = stderr_reader.read_line(&mut err_line) => {
|
||||
if res.unwrap_or(0) > 0 {
|
||||
// Log error
|
||||
app.emit("download-log", LogEvent {
|
||||
id: id.clone(),
|
||||
message: err_line.trim().to_string(),
|
||||
level: "error".to_string(),
|
||||
}).ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
line.clear();
|
||||
}
|
||||
|
||||
let status = child.wait().await?;
|
||||
@@ -194,4 +230,4 @@ pub async fn download_video(
|
||||
}).ok();
|
||||
Err(anyhow!("Download process failed"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user