Skip to content

Commit

Permalink
Shows flights currently in airspace
Browse files Browse the repository at this point in the history
Both on the homepage and also the flights page.
  • Loading branch information
Celeo committed Oct 16, 2024
1 parent 5b4959d commit 31351eb
Show file tree
Hide file tree
Showing 8 changed files with 299 additions and 83 deletions.
131 changes: 129 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@ This app makes few assertions about how it should be ran. You can run it directl

Licensed under either of

* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
* MIT license ([LICENSE-MIT](LICENSE-MIT))
- Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
- MIT license ([LICENSE-MIT](LICENSE-MIT))

Loading indicator from [SamHerbert/SVG-Loaders](https://github.com/SamHerbert/SVG-Loaders).
Loading indicator from [SamHerbert/SVG-Loaders](https://github.com/SamHerbert/SVG-Loaders). Geo boundary data from [vatspy-data-project](https://github.com/vatsimnetwork/vatspy-data-project). See 'Cargo.toml' files for a list of used libraries.

## Contributing

Expand Down
1 change: 1 addition & 0 deletions vzdv-site/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,4 @@ tower-sessions-sqlx-store = { version = "0.13.0", features = ["sqlite"] }
uuid = { version = "1.10.0", features = ["v4", "fast-rng"] }
vatsim_utils = "0.5.0"
voca_rs = "1.15.2"
geo = "0.28.0"
66 changes: 19 additions & 47 deletions vzdv-site/src/endpoints/airspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
use crate::{
flashed_messages,
flights::get_relevant_flights,
shared::{AppError, AppState, CacheEntry, UserInfo, SESSION_USER_INFO_KEY},
};
use axum::{
Expand All @@ -13,9 +14,9 @@ use axum::{
use itertools::Itertools;
use log::{info, warn};
use minijinja::{context, Environment};
use serde::{Deserialize, Serialize};
use serde::Deserialize;
use serde_json::json;
use std::{sync::Arc, time::Instant};
use std::{collections::HashSet, sync::Arc, time::Instant};
use thousands::Separable;
use tower_sessions::Session;
use vatsim_utils::live_api::Vatsim;
Expand All @@ -38,60 +39,31 @@ async fn page_flights(
State(state): State<Arc<AppState>>,
session: Session,
) -> Result<Html<String>, AppError> {
#[derive(Serialize, Default)]
struct OnlineFlight<'a> {
pilot_name: &'a str,
pilot_cid: u64,
callsign: &'a str,
departure: &'a str,
arrival: &'a str,
altitude: String,
speed: String,
}

// cache this endpoint's returned data for 60 seconds
// cache this endpoint's returned data for 15 seconds
let cache_key = "ONLINE_FLIGHTS_FULL";
if let Some(cached) = state.cache.get(&cache_key) {
let elapsed = Instant::now() - cached.inserted;
if elapsed.as_secs() < 60 {
if elapsed.as_secs() < 15 {
return Ok(Html(cached.data));
}
state.cache.invalidate(&cache_key);
}

let artcc_fields: Vec<_> = state
.config
.airports
.all
.iter()
.map(|airport| &airport.code)
.collect();
let vatsim_data = Vatsim::new().await?.get_v3_data().await?;
let flights: Vec<OnlineFlight> = vatsim_data
.pilots
.iter()
.flat_map(|flight| {
if let Some(plan) = &flight.flight_plan {
let from = artcc_fields.contains(&&plan.departure);
let to = artcc_fields.contains(&&plan.arrival);
if from || to {
Some(OnlineFlight {
pilot_name: &flight.name,
pilot_cid: flight.cid,
callsign: &flight.callsign,
departure: &plan.departure,
arrival: &plan.arrival,
altitude: flight.altitude.separate_with_commas(),
speed: flight.groundspeed.separate_with_commas(),
})
} else {
None
}
} else {
None
}
})
.collect();
let flights = {
let all = get_relevant_flights(&state.config, &vatsim_data.pilots);
let mut flights = HashSet::with_capacity(all.plan_within.len()); // won't be all of them, but might save one allocation
flights.extend(all.actually_within);
flights.extend(all.plan_from);
flights.extend(all.plan_to);
flights.extend(all.plan_within);
let flights: Vec<_> = flights
.iter()
.cloned()
.sorted_by(|a, b| a.callsign.cmp(&b.callsign))
.collect();
flights
};

let user_info: Option<UserInfo> = session.get(SESSION_USER_INFO_KEY).await?;
let template = state.templates.get_template("airspace/flights")?;
Expand Down
Loading

0 comments on commit 31351eb

Please sign in to comment.