use std::error::Error; use std::fs::{self, File, OpenOptions}; use std::io::Write; use std::time::Duration; use std::{env, thread}; const URL: &str = "https://theboardr.com/events/"; fn main() { let last_event_id_filename = env::var("LAST_EVENT_ID_PATH").expect("Environment variable LAST_EVENT_ID_PATH is not set"); let potential_cph_open_filename = env::var("POTENTIAL_CPH_OPEN_PATH") .expect("Environment variable POTENTIAL_CPH_OPEN_PATH is not set"); create_file_if_not_exists(&potential_cph_open_filename); let last_checked_event_id = get_last_checked_event_id(&last_event_id_filename) .expect("Failed to get last checked event id"); let most_recent_event_id: u64 = find_most_recent_event_id(&potential_cph_open_filename, last_checked_event_id) .expect("Failed to find most recent event id"); // Check next event update_last_checked_event_id(&last_event_id_filename, most_recent_event_id); } fn get_last_checked_event_id(filename: &String) -> Result> { let last_checked_event_id = fs::read_to_string(filename)?.trim().parse()?; Ok(last_checked_event_id) } fn find_most_recent_event_id(cph_filepath: &str, last_checked: u64) -> Result> { let mut check_ahead = 0; let mut last_checked_event_id = last_checked; while check_ahead < 3 { let id_to_check = last_checked_event_id + 1 + check_ahead; println!("Checking event: {}", id_to_check); let (exists, is_cph_open) = check_event(id_to_check); println!("- Exists: {}", exists); println!("- CPH-OPEN: {}", is_cph_open); thread::sleep(Duration::from_secs(2)); if is_cph_open { save_event_id(cph_filepath, id_to_check); } if !exists { check_ahead += 1; } else { last_checked_event_id = id_to_check; check_ahead = 0; } } Ok(last_checked_event_id) } fn check_event(id: u64) -> (bool, bool) { let mut no_requests = 0; let mut event_confirmed = false; let mut matches = false; while no_requests < 5 && !event_confirmed { no_requests += 1; let content = reqwest::blocking::get(format!("{URL}{id}")) .expect("") .text() .expect(""); event_confirmed = content.contains(&format!("\"EventID\":{id}")); matches = content.to_lowercase().contains(&format!("cph")) || content.to_lowercase().contains(&format!("copenhagen")); if !event_confirmed { thread::sleep(Duration::from_secs(10)); } } (event_confirmed, matches) } fn save_event_id(filename: &str, id: u64) { let mut cph_file = OpenOptions::new() .append(true) .open(filename) .expect(&format!("Failed to open file: {}", filename)); let id_to_write = format!("{}\n", id.to_string()); cph_file .write(id_to_write.as_bytes()) .expect("Failed to write last checked event"); } fn update_last_checked_event_id(filename: &str, id: u64) { let content = format!("{}\n", id.to_string()); fs::write(filename, content).expect("Failed to write last checked event"); } fn create_file_if_not_exists(filename: &str) { if !std::path::Path::new(filename).exists() { // If the file doesn't exist, create it File::create(filename).expect(""); } }