67 lines
1.9 KiB
Rust
67 lines
1.9 KiB
Rust
use std::{
|
|
fmt,
|
|
io::{BufRead, BufReader},
|
|
process::{Child, Command, Stdio},
|
|
};
|
|
use sysinfo::{Pid, ProcessRefreshKind, RefreshKind, System, SystemExt};
|
|
|
|
#[derive(Debug, Clone)]
|
|
struct AddrInUse;
|
|
|
|
impl fmt::Display for AddrInUse {
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
write!(f, "address is in use")
|
|
}
|
|
}
|
|
|
|
pub struct Driver {
|
|
child: Child,
|
|
}
|
|
|
|
impl Driver {
|
|
pub fn new() -> Result<Self, anyhow::Error> {
|
|
let mut child = Command::new("chromedriver")
|
|
.stdout(Stdio::piped())
|
|
.arg("--port=6444")
|
|
.spawn()?;
|
|
let child_id = child.id();
|
|
let mut child_out = BufReader::new(child.stdout.as_mut().unwrap());
|
|
let mut line = String::new();
|
|
|
|
let mut sys_info = System::new_with_specifics(
|
|
RefreshKind::new().with_processes(ProcessRefreshKind::new()),
|
|
);
|
|
|
|
// Wait for it to say Chromedriver started successfully
|
|
loop {
|
|
child_out.read_line(&mut line).unwrap();
|
|
if line.contains("ChromeDriver was started successfully.") {
|
|
break;
|
|
}
|
|
if line.contains("bind() failed: Address already in use") || line.contains("Exiting...")
|
|
{
|
|
return Err(anyhow::anyhow!(line));
|
|
}
|
|
|
|
// Check if chromedriver has exited
|
|
sys_info.refresh_all();
|
|
if let None = sys_info.process(Pid::from(child_id.clone() as i32)) {
|
|
let status_code = child.wait()?;
|
|
println!("{}", status_code.code().unwrap());
|
|
return Err(anyhow::anyhow!(
|
|
"chromedriver exited with status code {}",
|
|
status_code.code().unwrap_or(1337),
|
|
));
|
|
}
|
|
}
|
|
|
|
println!("chromedriver started");
|
|
Ok(Self { child })
|
|
}
|
|
|
|
pub fn exit(&mut self) -> Result<(), anyhow::Error> {
|
|
self.child.kill()?;
|
|
Ok(())
|
|
}
|
|
}
|