184 lines
5.4 KiB
Rust
184 lines
5.4 KiB
Rust
use std::time::Duration;
|
|
|
|
use chrono::Local;
|
|
use reqwest::StatusCode;
|
|
use serde::Serialize;
|
|
use tokio::time::sleep;
|
|
|
|
use crate::traewelling::{
|
|
model::{JsonableData, Status, StopJourneyPart},
|
|
RequestErr, TraewellingClient,
|
|
};
|
|
|
|
pub async fn get_current_journey() -> anyhow::Result<()> {
|
|
let client = TraewellingClient::new()?;
|
|
|
|
let mut state;
|
|
let mut cur_active_checkin = None;
|
|
|
|
loop {
|
|
match client.get_active_checkin().await {
|
|
Ok(status) => {
|
|
cur_active_checkin = Some(status);
|
|
state = State::Live;
|
|
}
|
|
Err(err) => {
|
|
if err == RequestErr::WithStatus(StatusCode::NOT_FOUND) {
|
|
state = State::NoCheckin;
|
|
cur_active_checkin = None;
|
|
} else {
|
|
state = State::NoConnectionOrSomethingElseDoesntWork;
|
|
}
|
|
}
|
|
};
|
|
|
|
match (state, &cur_active_checkin) {
|
|
(State::Live | State::NoConnectionOrSomethingElseDoesntWork, Some(status)) => {
|
|
let live = state == State::Live;
|
|
let out = CurrentJourneyOutput::new(&status, live);
|
|
|
|
println!(
|
|
"{}",
|
|
serde_json::to_string(&out)
|
|
.expect("serde should not make you sad but it does because it's serde")
|
|
);
|
|
sleep(Duration::from_secs(20)).await;
|
|
}
|
|
(_, None) | (State::NoCheckin, Some(_)) => {
|
|
println!("null");
|
|
sleep(Duration::from_secs(60)).await;
|
|
}
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
|
enum State {
|
|
Live,
|
|
NoConnectionOrSomethingElseDoesntWork,
|
|
NoCheckin,
|
|
}
|
|
|
|
#[derive(Serialize)]
|
|
struct CurrentJourneyOutput {
|
|
live: bool,
|
|
// Journey progress, 0.0-1.0
|
|
progress: Option<f32>,
|
|
time_left: Option<i64>,
|
|
icon: String,
|
|
line: String,
|
|
|
|
// Invalid data received?
|
|
departure_err: bool,
|
|
departure_planned: Option<i64>,
|
|
departure_real: Option<i64>,
|
|
departure_station: String,
|
|
departure_ril100: Option<String>,
|
|
departure_platform_data_available: bool,
|
|
departure_platform_planned: Option<String>,
|
|
departure_platform_real: Option<String>,
|
|
|
|
// Invalid data received?
|
|
arrival_err: bool,
|
|
arrival_planned: Option<i64>,
|
|
arrival_real: Option<i64>,
|
|
arrival_station: String,
|
|
arrival_ril100: Option<String>,
|
|
arrival_platform_data_available: bool,
|
|
arrival_platform_planned: Option<String>,
|
|
arrival_platform_real: Option<String>,
|
|
}
|
|
|
|
impl CurrentJourneyOutput {
|
|
fn new(checkin: &Status, live: bool) -> Self {
|
|
let JsonableData {
|
|
time_err: departure_err,
|
|
time_planned: departure_planned,
|
|
time_real: departure_real,
|
|
station: departure_station,
|
|
ril100: departure_ril100,
|
|
platform_data_available: departure_platform_data_available,
|
|
platform_planned: departure_platform_planned,
|
|
platform_real: departure_platform_real,
|
|
} = checkin.train.origin.get_time_data(StopJourneyPart::Origin);
|
|
let JsonableData {
|
|
time_err: arrival_err,
|
|
time_planned: arrival_planned,
|
|
time_real: arrival_real,
|
|
station: arrival_station,
|
|
ril100: arrival_ril100,
|
|
platform_data_available: arrival_platform_data_available,
|
|
platform_planned: arrival_platform_planned,
|
|
platform_real: arrival_platform_real,
|
|
} = checkin
|
|
.train
|
|
.destination
|
|
.get_time_data(StopJourneyPart::Destination);
|
|
|
|
let (progress, time_left) = if !departure_err && !arrival_err {
|
|
let departure = departure_real.unwrap_or(departure_planned.unwrap());
|
|
let arrival = arrival_real.unwrap_or(arrival_planned.unwrap());
|
|
let dur = arrival - departure;
|
|
|
|
let now = Local::now().timestamp();
|
|
|
|
let progress = ((now - departure) as f32) / dur as f32;
|
|
let time_left = arrival - now;
|
|
|
|
(Some(progress), Some(time_left))
|
|
} else {
|
|
(None, None)
|
|
};
|
|
|
|
let icon = match checkin.train.category.as_str() {
|
|
"nationalExpress" | "national" => "longDistanceTrans",
|
|
"regionalExp" | "regional" => "regionalTrans",
|
|
"suburban" => "localTrans",
|
|
"subway" => "subTrans",
|
|
"bus" => "bus",
|
|
"tram" => "tram",
|
|
"ferry" => "ferry",
|
|
_ => "other",
|
|
}
|
|
.to_string();
|
|
|
|
CurrentJourneyOutput {
|
|
live,
|
|
progress,
|
|
time_left,
|
|
icon,
|
|
line: checkin.train.line_name.clone(),
|
|
departure_err,
|
|
departure_planned,
|
|
departure_real,
|
|
departure_station,
|
|
departure_ril100,
|
|
departure_platform_data_available,
|
|
departure_platform_planned,
|
|
departure_platform_real,
|
|
arrival_err,
|
|
arrival_planned,
|
|
arrival_real,
|
|
arrival_station,
|
|
arrival_ril100,
|
|
arrival_platform_data_available,
|
|
arrival_platform_planned,
|
|
arrival_platform_real,
|
|
}
|
|
}
|
|
}
|
|
|
|
enum TransportType {
|
|
// FV, ob jetzt NJ, IC, ICE... egal
|
|
LongDistanceTrans,
|
|
RegionalTrans,
|
|
// S-bahn...
|
|
LocalTrans,
|
|
// U-bahn
|
|
SubTrans,
|
|
Bus,
|
|
Tram,
|
|
Ferry,
|
|
}
|