webcheck save
This commit is contained in:
parent
2a714d029a
commit
17d43f0fd0
2 changed files with 127 additions and 19 deletions
|
@ -21,9 +21,11 @@ use super::{
|
|||
};
|
||||
|
||||
mod driver;
|
||||
mod save;
|
||||
mod utd_app;
|
||||
|
||||
pub struct WebcheckApp {
|
||||
reqwest_client: reqwest::Client,
|
||||
state: Mutex<WebcheckAppState>,
|
||||
}
|
||||
|
||||
|
@ -31,7 +33,7 @@ struct WebcheckAppState {
|
|||
config: Option<&'static Config>,
|
||||
global_app_state: Option<Arc<Mutex<AppState>>>,
|
||||
last_response: HashMap<String, LastResponse>,
|
||||
checkers: HashMap<String, Box<dyn WebDriverChecker + Send + Sync>>,
|
||||
checkers: HashMap<String, Checker>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
|
@ -54,6 +56,18 @@ async fn route_get_results(
|
|||
))
|
||||
}
|
||||
|
||||
pub enum Checker {
|
||||
WebDriver(Box<dyn WebDriverChecker + Send + Sync>),
|
||||
Reqwest(Box<dyn ReqwestChecker + Send + Sync>),
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
pub trait ReqwestChecker {
|
||||
fn init(&mut self, config: &HashMap<String, String>) -> anyhow::Result<()>;
|
||||
fn interval(&self) -> u64;
|
||||
async fn check(&self, client: &reqwest::Client) -> anyhow::Result<String>;
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
pub trait WebDriverChecker {
|
||||
fn init(&mut self, config: &HashMap<String, String>) -> anyhow::Result<()>;
|
||||
|
@ -64,6 +78,7 @@ pub trait WebDriverChecker {
|
|||
impl WebcheckApp {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
reqwest_client: reqwest::Client::new(),
|
||||
state: Mutex::new(WebcheckAppState {
|
||||
config: None,
|
||||
global_app_state: None,
|
||||
|
@ -76,8 +91,8 @@ impl WebcheckApp {
|
|||
pub async fn run_single_check(self: &Self, key: &str) -> anyhow::Result<()> {
|
||||
let mut state = self.state.lock().await;
|
||||
|
||||
let checker = state.checkers.get_mut(key).unwrap();
|
||||
|
||||
let response = match state.checkers.get_mut(key).unwrap() {
|
||||
Checker::WebDriver(checker) => {
|
||||
let mut driver = driver::chrome::ChromeDriver::new();
|
||||
driver.spawn(&["--enable-chrome-logs"])?;
|
||||
tokio::time::sleep(std::time::Duration::from_secs(5)).await;
|
||||
|
@ -95,6 +110,11 @@ impl WebcheckApp {
|
|||
}
|
||||
};
|
||||
driver.quit().await?;
|
||||
response
|
||||
}
|
||||
Checker::Reqwest(checker) => checker.check(&self.reqwest_client).await?,
|
||||
};
|
||||
info!("Webcheck for {} returned {}", key, response);
|
||||
|
||||
let new_response = LastResponse {
|
||||
response: response.clone(),
|
||||
|
@ -141,7 +161,10 @@ impl WebcheckApp {
|
|||
let interval = {
|
||||
let state = self_clone.state.lock().await;
|
||||
let checker = state.checkers.get(key.as_str()).unwrap();
|
||||
checker.interval()
|
||||
match checker {
|
||||
Checker::WebDriver(checker) => checker.interval(),
|
||||
Checker::Reqwest(checker) => checker.interval(),
|
||||
}
|
||||
};
|
||||
|
||||
let mut ticker = tokio::time::interval(std::time::Duration::from_secs(interval));
|
||||
|
@ -180,7 +203,18 @@ impl App for WebcheckApp {
|
|||
checker
|
||||
.init(config.get(key).unwrap())
|
||||
.expect("Failed to initialize UTDAppChecker");
|
||||
state.checkers.insert(key.clone(), Box::new(checker));
|
||||
state
|
||||
.checkers
|
||||
.insert(key.clone(), Checker::WebDriver(Box::new(checker)));
|
||||
}
|
||||
"save" => {
|
||||
let mut checker = save::SaveChecker::new();
|
||||
checker
|
||||
.init(config.get(key).unwrap())
|
||||
.expect("Failed to initialize SaveChecker");
|
||||
state
|
||||
.checkers
|
||||
.insert(key.clone(), Checker::Reqwest(Box::new(checker)));
|
||||
}
|
||||
_ => panic!("Invalid key in webcheck config: {}", key),
|
||||
});
|
||||
|
|
74
src/apps/webcheck/save.rs
Normal file
74
src/apps/webcheck/save.rs
Normal file
|
@ -0,0 +1,74 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use super::ReqwestChecker;
|
||||
use async_trait::async_trait;
|
||||
use serde::Deserialize;
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
pub struct SaveCaseCheckResp {
|
||||
#[serde(rename = "caseNumber")]
|
||||
case_number: String,
|
||||
#[serde(rename = "createdDate")]
|
||||
created_date: String,
|
||||
#[serde(rename = "agencyName")]
|
||||
agency_name: String,
|
||||
#[serde(rename = "caseStatus")]
|
||||
case_status: String,
|
||||
}
|
||||
|
||||
pub struct SaveChecker {
|
||||
config: HashMap<String, String>,
|
||||
}
|
||||
|
||||
impl SaveChecker {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
config: HashMap::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl ReqwestChecker for SaveChecker {
|
||||
fn init(&mut self, config: &HashMap<String, String>) -> anyhow::Result<()> {
|
||||
if config.get("case_id").is_none() {
|
||||
return Err(anyhow::anyhow!("case_id not set"));
|
||||
}
|
||||
|
||||
self.config = config.clone();
|
||||
Ok(())
|
||||
}
|
||||
fn interval(&self) -> u64 {
|
||||
let default_interval = "3600".to_string();
|
||||
let interval = self.config.get("interval").unwrap_or(&default_interval);
|
||||
interval.parse::<u64>().unwrap()
|
||||
}
|
||||
async fn check(&self, client: &reqwest::Client) -> anyhow::Result<String> {
|
||||
let case_id = self.config.get("case_id").unwrap();
|
||||
let req = client
|
||||
.request(
|
||||
reqwest::Method::GET,
|
||||
format!(
|
||||
"https://save.uscis.gov/api/save/read/cases/check/{}",
|
||||
case_id
|
||||
),
|
||||
)
|
||||
.header("Accept", "application/json")
|
||||
.header("Content-Type", "application/json")
|
||||
.header(
|
||||
"User-Agent",
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/117.0",
|
||||
)
|
||||
.header(
|
||||
"Referer",
|
||||
format!(
|
||||
"https://save.uscis.gov/save/app/client/ui/case-check/detail/{}",
|
||||
case_id
|
||||
),
|
||||
)
|
||||
.build()?;
|
||||
let resp = client.execute(req).await?;
|
||||
let res = resp.json::<SaveCaseCheckResp>().await?;
|
||||
Ok(format!("Case {} is {}", res.case_number, res.case_status,))
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue