diff --git a/vzdv-site/src/endpoints/facility.rs b/vzdv-site/src/endpoints/facility.rs index 6748d23..a16610f 100644 --- a/vzdv-site/src/endpoints/facility.rs +++ b/vzdv-site/src/endpoints/facility.rs @@ -11,6 +11,7 @@ use axum::{ Form, Router, }; use chrono::{DateTime, Months, Utc}; +use indexmap::IndexMap; use itertools::Itertools; use log::{error, warn}; use minijinja::context; @@ -21,7 +22,6 @@ use std::{ sync::Arc, }; use tower_sessions::Session; -use indexmap::IndexMap; use vzdv::{ config::Config, determine_staff_positions, @@ -39,6 +39,8 @@ struct StaffPosition { description: &'static str, } +type ParsedAlias = Vec<(String, Vec<(String, Vec)>)>; + fn generate_staff_outline(config: &Config) -> HashMap<&'static str, StaffPosition> { let email_domain = &config.staff.email_domain; HashMap::from([ @@ -398,75 +400,69 @@ async fn page_resources( Ok(Html(rendered)) } +pub async fn fetch_and_parse_alias_file() -> Result { + let url = "https://data-api.vnas.vatsim.net/Files/Aliases/ZDV.txt"; + let response = reqwest::get(url).await?.text().await?; + + let mut parsed_data: IndexMap>> = IndexMap::new(); + let mut current_h1 = String::new(); + let mut current_h2 = String::new(); + + for line in response.lines() { + if line.starts_with(";;;;") { + // New Heading 1 + current_h1 = line.strip_prefix(";;;;").unwrap_or(line).trim().to_string(); + parsed_data.entry(current_h1.clone()).or_default(); + current_h2 = String::new(); // Reset H2 + } else if line.starts_with(";;;") { + // New Heading 2 + current_h2 = line.strip_prefix(";;;").unwrap_or(line).trim().to_string(); + parsed_data + .entry(current_h1.clone()) + .or_default() + .entry(current_h2.clone()) + .or_default(); + } else if line.starts_with('.') { + // Command under current H1 or H2 + if !current_h1.is_empty() { + if !current_h2.is_empty() { + parsed_data + .entry(current_h1.clone()) + .or_default() + .entry(current_h2.clone()) + .or_default() + .push(line.trim().to_string()); + } else { + // Command directly under H1 + parsed_data + .entry(current_h1.clone()) + .or_default() + .entry("__root__".to_string()) + .or_default() + .push(line.trim().to_string()); + } + } + } + } + + // Convert IndexMap to Vec for Jinja compatibility + let parsed_vec: ParsedAlias = parsed_data + .into_iter() + .map(|(h1, h2_map)| { + let h2_vec = h2_map.into_iter().collect(); + (h1, h2_vec) + }) + .collect(); -pub async fn fetch_and_parse_alias_file() -> Result)>)>, reqwest::Error> { - let url = "https://data-api.vnas.vatsim.net/Files/Aliases/ZDV.txt"; - let response = reqwest::get(url).await?.text().await?; - - let mut parsed_data: IndexMap>> = IndexMap::new(); - let mut current_h1 = String::new(); - let mut current_h2 = String::new(); - - for line in response.lines() { - if line.starts_with(";;;;") { - // New Heading 1 - current_h1 = line[4..].trim().to_string(); - parsed_data.entry(current_h1.clone()).or_default(); - current_h2 = String::new(); // Reset H2 - } else if line.starts_with(";;;") { - // New Heading 2 - current_h2 = line[3..].trim().to_string(); - parsed_data - .entry(current_h1.clone()) - .or_default() - .entry(current_h2.clone()) - .or_default(); - } else if line.starts_with('.') { - // Command under current H1 or H2 - if !current_h1.is_empty() { - if !current_h2.is_empty() { - parsed_data - .entry(current_h1.clone()) - .or_default() - .entry(current_h2.clone()) - .or_default() - .push(line.trim().to_string()); - } else { - // Command directly under H1 - parsed_data - .entry(current_h1.clone()) - .or_default() - .entry("__root__".to_string()) - .or_default() - .push(line.trim().to_string()); - } - } - } - } - - // Convert IndexMap to Vec for Jinja compatibility - let parsed_vec: Vec<(String, Vec<(String, Vec)>)> = parsed_data - .into_iter() - .map(|(h1, h2_map)| { - let h2_vec = h2_map - .into_iter() - .map(|(h2, commands)| (h2, commands)) - .collect(); - (h1, h2_vec) - }) - .collect(); - - Ok(parsed_vec) + Ok(parsed_vec) } - /// View Alias commands for the facility. (Polled from the vNAS API) -async fn alias_ref( - State(state): State>) -> Result, AppError> { - let template = state.templates.get_template("facility/aliasref.jinja")?; - let alias_ref = fetch_and_parse_alias_file().await?; - let rendered = template.render(context! { alias_ref })?; - Ok(Html(rendered)) +async fn alias_ref(State(state): State>) -> Result, AppError> { + let template = state.templates.get_template("facility/aliasref.jinja")?; + let alias_ref = fetch_and_parse_alias_file().await?; + let rendered = template.render(context! { alias_ref })?; + Ok(Html(rendered)) } /// Check visitor requirements and submit an application.