2022-06-26 18:51:08 +01:00
|
|
|
mod botdriver;
|
|
|
|
mod browser;
|
|
|
|
mod chromedriver;
|
|
|
|
mod webserve;
|
2022-07-03 22:46:15 +01:00
|
|
|
use botdriver::BotDriver;
|
|
|
|
use browser::BrowserSession;
|
|
|
|
use chromedriver::Driver;
|
|
|
|
use futures::channel::oneshot;
|
|
|
|
use serde::{Deserialize, Serialize};
|
2022-07-01 23:04:03 +01:00
|
|
|
use std::{
|
|
|
|
io::{self, Write},
|
|
|
|
sync::{
|
|
|
|
atomic::{AtomicBool, Ordering},
|
|
|
|
Arc,
|
|
|
|
},
|
2022-07-03 22:46:15 +01:00
|
|
|
time::Duration,
|
2022-07-01 23:04:03 +01:00
|
|
|
};
|
2022-07-03 22:46:15 +01:00
|
|
|
use tokio::time;
|
2022-06-26 18:51:08 +01:00
|
|
|
|
|
|
|
const STATIC_ADDR: &str = "127.0.0.1:8010";
|
|
|
|
|
|
|
|
#[tokio::main]
|
2022-07-03 22:46:15 +01:00
|
|
|
async fn main() {
|
|
|
|
if let Err(e) = main_but_with_result().await {
|
|
|
|
println!("frc exited with error: {}", e);
|
|
|
|
std::process::exit(1);
|
|
|
|
}
|
|
|
|
std::process::exit(0);
|
|
|
|
}
|
|
|
|
async fn main_but_with_result() -> Result<(), anyhow::Error> {
|
2022-06-26 18:51:08 +01:00
|
|
|
let mut cfg: FRCConfig = confy::load_path(CFG_NAME)?;
|
|
|
|
if cfg.username == None || cfg.token == None {
|
|
|
|
cfg = create_config()?;
|
|
|
|
confy::store_path(CFG_NAME, cfg.clone())?;
|
|
|
|
}
|
|
|
|
let username = cfg.username.unwrap();
|
|
|
|
let static_handle = webserve::start_server(STATIC_ADDR.to_string()).await?;
|
|
|
|
|
|
|
|
println!("Starting frc with username to listen to: {}", username);
|
|
|
|
|
|
|
|
let mut chr = Driver::new()?;
|
|
|
|
|
|
|
|
let driver = BrowserSession::new().await?;
|
|
|
|
let browser = driver.handle();
|
|
|
|
|
|
|
|
let mut bot = BotDriver::new(cfg.token.unwrap(), username);
|
|
|
|
browser.start(STATIC_ADDR).await?;
|
2022-07-03 22:46:15 +01:00
|
|
|
println!();
|
|
|
|
println!("#####################");
|
|
|
|
println!("# launching frc #");
|
|
|
|
println!("# #");
|
|
|
|
println!("# frc can be closed #");
|
|
|
|
println!("# by an interrupt #");
|
|
|
|
println!("# (Ctl-C) #");
|
|
|
|
println!("#####################");
|
|
|
|
println!();
|
|
|
|
|
2022-06-26 18:51:08 +01:00
|
|
|
tokio::spawn(async move {
|
2022-07-03 22:46:15 +01:00
|
|
|
let should_exit = Arc::new(AtomicBool::new(false));
|
|
|
|
|
|
|
|
let (chr_sender, mut chr_receiver) = oneshot::channel();
|
|
|
|
chr.exit_waiter(chr_sender);
|
|
|
|
|
|
|
|
signal_hook::flag::register(signal_hook::consts::SIGINT, Arc::clone(&should_exit)).unwrap();
|
|
|
|
signal_hook::flag::register(signal_hook::consts::SIGTERM, Arc::clone(&should_exit))
|
|
|
|
.unwrap();
|
2022-06-26 18:51:08 +01:00
|
|
|
|
2022-07-01 23:04:03 +01:00
|
|
|
loop {
|
2022-07-03 22:46:15 +01:00
|
|
|
if should_exit.load(Ordering::Relaxed) || chr_receiver.try_recv().unwrap().is_some() {
|
2022-07-01 23:04:03 +01:00
|
|
|
break;
|
|
|
|
}
|
2022-07-03 22:46:15 +01:00
|
|
|
time::sleep(Duration::from_millis(100)).await;
|
|
|
|
}
|
|
|
|
|
|
|
|
println!();
|
|
|
|
println!("closing down");
|
|
|
|
static_handle.abort();
|
|
|
|
driver.stop().await.expect("failed killing browser");
|
|
|
|
let output = chr.exit_with_output().expect("failed killing chromedriver");
|
|
|
|
println!("chromedriver exited with status code {}", output.status);
|
|
|
|
if output.stderr.len() > 0 {
|
|
|
|
print!("chromedriver stderr output:");
|
|
|
|
io::stdout().write(&output.stderr).unwrap();
|
|
|
|
println!();
|
|
|
|
}
|
|
|
|
if output.stdout.len() > 0 {
|
|
|
|
print!("chromedriver stdout output:");
|
|
|
|
io::stdout().write(&output.stdout).unwrap();
|
|
|
|
println!();
|
2022-06-26 18:51:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
std::process::exit(0);
|
|
|
|
});
|
|
|
|
bot.listen_and_paste(browser).await.unwrap();
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
const CFG_NAME: &str = "frc.toml";
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
|
|
|
struct FRCConfig {
|
|
|
|
username: Option<String>,
|
|
|
|
token: Option<String>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ::std::default::Default for FRCConfig {
|
|
|
|
fn default() -> Self {
|
|
|
|
Self {
|
|
|
|
username: None,
|
|
|
|
token: None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn create_config() -> Result<FRCConfig, anyhow::Error> {
|
|
|
|
let username = get_config_from_user("Enter username to listen to:")?;
|
|
|
|
let token = get_config_from_user("Enter telegram bot token:")?;
|
|
|
|
Ok(FRCConfig {
|
|
|
|
username: Some(username),
|
|
|
|
token: Some(token),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
fn get_config_from_user(prompt: &str) -> Result<String, anyhow::Error> {
|
|
|
|
print!("{} ", prompt);
|
|
|
|
io::stdout().flush()?;
|
|
|
|
let mut value = String::new();
|
|
|
|
io::stdin().read_line(&mut value)?;
|
|
|
|
Ok(value.trim().to_string())
|
|
|
|
}
|