117 lines
3.6 KiB
Rust
117 lines
3.6 KiB
Rust
use actix_web::{cookie::Cookie, get, web::Data, App, HttpRequest, HttpResponse, HttpServer, Responder};
|
|
use env_logger::Env;
|
|
use log::*;
|
|
use dotenv::dotenv;
|
|
use serde::Deserialize;
|
|
use services::{gtfs_pull, trip_tracking::{self}};
|
|
use templates::ContentTemplate;
|
|
use std::{fs::File, io::Read, sync::Arc, time::Instant};
|
|
use askama::Template;
|
|
|
|
mod services;
|
|
mod controllers;
|
|
mod templates;
|
|
|
|
pub struct AppState {
|
|
gtfs_service: services::gtfs_pull::GtfsPullService,
|
|
trip_tracking_service: services::trip_tracking::TripTrackingService
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
struct LocalStateQuery {
|
|
pub widescreen: Option<bool>
|
|
}
|
|
|
|
pub async fn perform_action<F, Fut, T >(req: HttpRequest, func: F) -> impl Responder
|
|
where T: Template,
|
|
F: Fn() -> Fut,
|
|
Fut: Future<Output = anyhow::Result<ContentTemplate<T>>> + 'static {
|
|
|
|
let start_time = Instant::now();
|
|
let mut enable_widescreen = true;
|
|
if let Some(widescreen_set) = req.cookie("widescreen") {
|
|
enable_widescreen = widescreen_set.value() == "true";
|
|
}
|
|
|
|
let query_params = actix_web::web::Query::<LocalStateQuery>::from_query(req.query_string()).unwrap();
|
|
|
|
if let Some(set_widescreen) = query_params.widescreen {
|
|
enable_widescreen = set_widescreen;
|
|
}
|
|
|
|
let x = func().await;
|
|
|
|
match x {
|
|
Ok(mut y) => {
|
|
y.widescreen = enable_widescreen;
|
|
y.load_time_ms = Some(start_time.elapsed().as_nanos());
|
|
let mut cookie = Cookie::new("widescreen", y.widescreen.to_string());
|
|
cookie.set_path("/");
|
|
HttpResponse::Ok()
|
|
.cookie(cookie)
|
|
.body(y.render().unwrap())
|
|
},
|
|
Err(_) => {
|
|
HttpResponse::InternalServerError().body("Error")
|
|
}
|
|
}
|
|
}
|
|
|
|
#[get("/")]
|
|
async fn get_index(req: HttpRequest) -> impl Responder {
|
|
perform_action(req, move || async {
|
|
Ok(templates::ContentTemplate {
|
|
page_title: None,
|
|
page_desc: None,
|
|
content: templates::IndexTemplate {},
|
|
load_time_ms: None,
|
|
widescreen: false
|
|
})
|
|
}).await
|
|
}
|
|
|
|
#[tokio::main]
|
|
async fn main() -> ::anyhow::Result<()> {
|
|
env_logger::init_from_env(Env::default().default_filter_or("septastic_api=info"));
|
|
dotenv().ok();
|
|
|
|
let version: &str = option_env!("CARGO_PKG_VERSION").expect("Expected package version");
|
|
info!("Starting the SEPTASTIC Server v{} (commit: {})", version, "NONE");
|
|
|
|
let mut file = File::open("./config.yaml")?;
|
|
let mut file_contents = String::new();
|
|
file.read_to_string(&mut file_contents);
|
|
|
|
let config_file = serde_yaml::from_str::<gtfs_pull::Config>(file_contents.as_str())?;
|
|
|
|
let tt_service = services::trip_tracking::TripTrackingService::new().await;
|
|
tt_service.start();
|
|
|
|
let svc = gtfs_pull::GtfsPullService::new(config_file);
|
|
svc.start();
|
|
svc.wait_for_ready();
|
|
|
|
let state = Arc::new(AppState {
|
|
gtfs_service: svc,
|
|
trip_tracking_service: tt_service
|
|
});
|
|
|
|
HttpServer::new(move || {
|
|
App::new()
|
|
.wrap(actix_cors::Cors::permissive())
|
|
.app_data(Data::new(state.clone()))
|
|
.service(controllers::route::api_get_route)
|
|
.service(controllers::route::api_get_schedule)
|
|
.service(controllers::route::get_route)
|
|
.service(controllers::route::get_routes_json)
|
|
.service(controllers::route::get_routes_html)
|
|
.service(controllers::route::get_directions)
|
|
.service(get_index)
|
|
.service(actix_files::Files::new("/assets", "./assets"))
|
|
})
|
|
.bind(("0.0.0.0", 8080))?
|
|
.run()
|
|
.await?;
|
|
|
|
Ok(())
|
|
}
|