diff --git a/api/src/controllers/route.rs b/api/src/controllers/route.rs index 782e36c..6fbba9c 100644 --- a/api/src/controllers/route.rs +++ b/api/src/controllers/route.rs @@ -1,5 +1,5 @@ use actix_web::{get, web::{Data, self}, HttpResponse, Responder}; -use std::{cmp::Ordering, time::Instant, sync::Arc}; +use std::{time::Instant, sync::Arc}; use libseptastic::{route::RouteType, stop_schedule::Trip}; use serde::{Serialize, Deserialize}; use askama::Template; @@ -9,24 +9,15 @@ use crate::database; #[get("/routes")] async fn get_routes_html(state: Data>) -> impl Responder { - let start_time = Instant::now(); + let start_time = Instant::now(); + let all_routes = database::get_all_routes(&mut state.database.begin().await.unwrap()).await.unwrap(); - let mut all_routes = database::get_all_routes(&mut state.database.begin().await.unwrap()).await.unwrap(); - all_routes.sort_by(|x, y| { - if let Ok(x_p) = x.id.parse::() { - if let Ok(y_p) = y.id.parse::() { - return if y_p > x_p { Ordering::Less } else { Ordering::Greater }; - } - } + let rr_routes = all_routes.clone().into_iter().filter(|x| x.route_type == RouteType::RegionalRail).collect(); + let subway_routes = all_routes.clone().into_iter().filter(|x| x.route_type == RouteType::SubwayElevated).collect(); + let trolley_routes = all_routes.clone().into_iter().filter(|x| x.route_type == RouteType::Trolley).collect(); + let bus_routes = all_routes.into_iter().filter(|x| x.route_type == RouteType::TracklessTrolley || x.route_type == RouteType::Bus).collect(); - return if y.id > x.id { Ordering::Less } else { Ordering::Greater }; - }); - - let rr_routes = all_routes.clone().into_iter().filter(|x| x.route_type == RouteType::RegionalRail).collect(); - let subway_routes = all_routes.clone().into_iter().filter(|x| x.route_type == RouteType::SubwayElevated).collect(); - let trolley_routes = all_routes.clone().into_iter().filter(|x| x.route_type == RouteType::Trolley).collect(); - let bus_routes = all_routes.into_iter().filter(|x| x.route_type == RouteType::TracklessTrolley || x.route_type == RouteType::Bus).collect(); HttpResponse::Ok().body(crate::templates::ContentTemplate { page_title: Some(String::from("SEPTASTIC | Routes")), page_desc: Some(String::from("All SEPTA routes.")), @@ -47,16 +38,11 @@ async fn get_routes_json(state: Data>) -> impl Responder { } #[derive(Debug, Deserialize)] -pub struct MyQueryParams { +pub struct RouteQueryParams { #[serde(default)] // Optional: handle missing parameters with a default value stops: Option, } -async fn get_route_by_id(id: String, state: Data>) -> ::anyhow::Result { - Ok(database::get_route_by_id(id, &mut state.database.begin().await?).await?) -} - - #[derive(Serialize, Deserialize)] pub struct RouteResponse { pub route: libseptastic::route::Route, @@ -65,24 +51,25 @@ pub struct RouteResponse { } async fn get_route_info(route_id: String, state: Data>) -> ::anyhow::Result { + let mut tx = state.database.begin().await?; - let route = get_route_by_id(route_id.clone(), state.clone()).await?; - let directions = database::get_direction_by_route_id(route_id.clone(), &mut state.database.begin().await?).await?; - let mut trips = database::get_schedule_by_route_id(route_id.clone(), &mut state.database.begin().await?).await?; + let route = database::get_route_by_id(route_id.clone(), &mut tx).await?; + //let directions = database::get_direction_by_route_id(route_id.clone(), &mut tx).await?; + let mut trips = database::get_schedule_by_route_id(route_id.clone(), &mut tx).await?; state.trip_tracking_service.annotate_trips(&mut trips); Ok(RouteResponse{ route, - directions, + directions: Vec::new(), schedule: trips }) } #[get("/route/{route_id}")] -async fn get_route(state: Data>, info: web::Query, path: web::Path) -> impl Responder { +async fn get_route(state: Data>, info: web::Query, path: web::Path) -> impl Responder { + let start_time = Instant::now(); - let start_time = Instant::now(); let mut filters: Option> = None; if let Some (stops_v) = info.stops.clone() { let mut items = Vec::new(); @@ -95,16 +82,20 @@ async fn get_route(state: Data>, info: web::Query, let route_id = path.into_inner(); let route_info_r = get_route_info(route_id.clone(), state).await; + let load_time_ms = Some(start_time.elapsed().as_millis()); + if let Ok(route_info) = route_info_r { + let timetables = crate::templates::build_timetables(route_info.directions, route_info.schedule); + HttpResponse::Ok().body(crate::templates::ContentTemplate { page_title: Some(format!("SEPTASTIC | Schedules for {}", route_id.clone())), page_desc: Some(format!("Schedule information for {}", route_id.clone())), content: crate::templates::RouteTemplate { route: route_info.route, - timetables: crate::templates::build_timetables(route_info.directions.as_slice(), route_info.schedule.as_slice()), + timetables, filter_stops: filters.clone() }, - load_time_ms: Some(start_time.elapsed().as_millis()) + load_time_ms }.render().unwrap()) } else { HttpResponse::InternalServerError().body("Error") diff --git a/api/src/database.rs b/api/src/database.rs index a7c0c0d..df4bace 100644 --- a/api/src/database.rs +++ b/api/src/database.rs @@ -46,6 +46,12 @@ pub async fn get_all_routes( route_type as "route_type: libseptastic::route::RouteType" FROM septa_routes + ORDER BY + CASE + WHEN id ~ '^[0-9]+$' THEN CAST(id AS INT) + ELSE NULL + END ASC, + id ASC; ;"# ) .fetch_all(&mut **transaction) @@ -116,17 +122,11 @@ pub async fn get_schedule_by_route_id( trip_id, service_id, septa_stop_schedules.direction_id, - septa_directions.direction as "direction: libseptastic::direction::CardinalDirection", arrival_time, stop_id, stop_sequence FROM septa_stop_schedules - INNER JOIN septa_directions - ON - septa_directions.direction_id = septa_stop_schedules.direction_id - AND - septa_directions.route_id = septa_stop_schedules.route_id INNER JOIN septa_stops ON septa_stops.id = septa_stop_schedules.stop_id WHERE diff --git a/api/src/templates.rs b/api/src/templates.rs index 67f57b8..e185504 100644 --- a/api/src/templates.rs +++ b/api/src/templates.rs @@ -52,8 +52,8 @@ pub struct TimetableDirection { } pub fn build_timetables( - directions: &[Direction], - trips: &[Trip], + directions: Vec, + trips: Vec, ) -> Vec { let mut results = Vec::new(); @@ -115,12 +115,6 @@ pub fn build_timetables( } }); - assert!(trip_ids.len() == live_trips.len()); - for row in &rows { - assert!(row.times.len() == live_trips.len()); - } - - results.push(TimetableDirection { direction: direction.clone(), trip_ids,