clean up + update dfile
All checks were successful
Create and publish a Docker image / build-and-push-image (push) Successful in 6m0s
All checks were successful
Create and publish a Docker image / build-and-push-image (push) Successful in 6m0s
This commit is contained in:
parent
7904c80642
commit
8fd41b1090
8 changed files with 314 additions and 335 deletions
126
api/src/controllers/route.rs
Normal file
126
api/src/controllers/route.rs
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
use actix_web::{get, web::{Data, self}, HttpResponse, Responder};
|
||||
use std::{cmp::Ordering, sync::Arc};
|
||||
use libseptastic::{route::RouteType, stop_schedule::Trip};
|
||||
use serde::{Serialize, Deserialize};
|
||||
use askama::Template;
|
||||
|
||||
use crate::AppState;
|
||||
use crate::database;
|
||||
|
||||
#[get("/routes")]
|
||||
async fn get_routes_html(state: Data<Arc<AppState>>) -> impl Responder {
|
||||
|
||||
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::<u32>() {
|
||||
if let Ok(y_p) = y.id.parse::<u32>() {
|
||||
return if y_p > x_p { Ordering::Less } else { Ordering::Greater };
|
||||
}
|
||||
}
|
||||
|
||||
return if y.id > x.id { Ordering::Less } else { Ordering::Greater };
|
||||
});
|
||||
|
||||
HttpResponse::Ok().body(crate::templates::ContentTemplate {
|
||||
page_title: None,
|
||||
page_desc: None,
|
||||
content: crate::templates::RoutesTemplate {
|
||||
rr_routes: all_routes.clone().into_iter().filter(|x| x.route_type == RouteType::RegionalRail).collect(),
|
||||
subway_routes: all_routes.clone().into_iter().filter(|x| x.route_type == RouteType::SubwayElevated).collect(),
|
||||
trolley_routes: all_routes.clone().into_iter().filter(|x| x.route_type == RouteType::Trolley).collect(),
|
||||
bus_routes: all_routes.into_iter().filter(|x| x.route_type == RouteType::TracklessTrolley || x.route_type == RouteType::Bus).collect(),
|
||||
}
|
||||
}.render().unwrap())
|
||||
}
|
||||
|
||||
#[get("/routes.json")]
|
||||
async fn get_routes_json(state: Data<Arc<AppState>>) -> impl Responder {
|
||||
let all_routes = database::get_all_routes(&mut state.database.begin().await.unwrap()).await.unwrap();
|
||||
HttpResponse::Ok().json(all_routes)
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct MyQueryParams {
|
||||
#[serde(default)] // Optional: handle missing parameters with a default value
|
||||
stops: Option<String>,
|
||||
}
|
||||
|
||||
async fn get_route_by_id(id: String, state: Data<Arc<AppState>>) -> ::anyhow::Result<libseptastic::route::Route> {
|
||||
Ok(database::get_route_by_id(id, &mut state.database.begin().await?).await?)
|
||||
}
|
||||
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct RouteResponse {
|
||||
pub route: libseptastic::route::Route,
|
||||
pub directions: Vec<libseptastic::direction::Direction>,
|
||||
pub schedule: Vec<Trip>
|
||||
}
|
||||
|
||||
async fn get_route_info(route_id: String, state: Data<Arc<AppState>>) -> ::anyhow::Result<RouteResponse> {
|
||||
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?;
|
||||
|
||||
state.trip_tracking_service.annotate_trips(&mut trips);
|
||||
|
||||
Ok(RouteResponse{
|
||||
route,
|
||||
directions,
|
||||
schedule: trips
|
||||
})
|
||||
}
|
||||
|
||||
#[get("/route/{route_id}")]
|
||||
async fn get_route(state: Data<Arc<AppState>>, info: web::Query<MyQueryParams>, path: web::Path<String>) -> impl Responder {
|
||||
let mut filters: Option<Vec<i64>> = None;
|
||||
if let Some (stops_v) = info.stops.clone() {
|
||||
let mut items = Vec::new();
|
||||
|
||||
for sid in stops_v.split(",") {
|
||||
items.push(sid.parse::<i64>().unwrap());
|
||||
}
|
||||
filters = Some(items);
|
||||
}
|
||||
|
||||
let route_id = path.into_inner();
|
||||
let route_info_r = get_route_info(route_id, state).await;
|
||||
if let Ok(route_info) = route_info_r {
|
||||
HttpResponse::Ok().body(crate::templates::ContentTemplate {
|
||||
page_title: None,
|
||||
page_desc: None,
|
||||
content: crate::templates::RouteTemplate {
|
||||
route: route_info.route,
|
||||
directions: route_info.directions.clone(),
|
||||
timetables: crate::templates::build_timetables(route_info.directions.as_slice(), route_info.schedule.as_slice()),
|
||||
filter_stops: filters.clone()
|
||||
}
|
||||
}.render().unwrap())
|
||||
} else {
|
||||
HttpResponse::InternalServerError().body("Error")
|
||||
}
|
||||
}
|
||||
|
||||
#[get("/route/{route_id}.json")]
|
||||
async fn api_get_route(state: Data<Arc<AppState>>, path: web::Path<String>) -> impl Responder {
|
||||
let route_id = path.into_inner();
|
||||
let route_info_r = get_route_info(route_id, state).await;
|
||||
if let Ok(route_info) = route_info_r {
|
||||
HttpResponse::Ok().json(route_info)
|
||||
} else {
|
||||
HttpResponse::InternalServerError().body("Error")
|
||||
}
|
||||
}
|
||||
|
||||
#[get("/api/route/{route_id}/schedule")]
|
||||
async fn api_get_schedule(state: Data<Arc<AppState>>, path: web::Path<String>) -> impl Responder {
|
||||
let route_id = path.into_inner();
|
||||
let route_r = database::get_schedule_by_route_id(route_id, &mut state.database.begin().await.unwrap()).await;
|
||||
|
||||
if let Ok(route) = route_r {
|
||||
HttpResponse::Ok().json(route)
|
||||
} else {
|
||||
HttpResponse::InternalServerError().body("Error")
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue