feat: add logic for journey->train identifier resolving, add recording of journeys, build api bearer auth

This commit is contained in:
2025-05-11 01:12:23 +02:00
parent 6b389e2d95
commit 41651dac21
25 changed files with 2833 additions and 125 deletions

43
src/model/app.rs Normal file
View File

@@ -0,0 +1,43 @@
use std::collections::HashMap;
use std::sync::Arc;
use sqlx::{PgPool};
use sqlx::pool::PoolOptions;
use tokio::sync::Mutex;
use crate::config::IceBingoConfig;
#[derive(Clone)]
pub(crate) struct AppState
{
pub state: Arc<Mutex<HashMap<String, String>>>,
pub db: Arc<PgPool>,
}
impl AppState {
pub(crate) async fn new(config: IceBingoConfig) -> Result<Self, sqlx::Error> {
let kv_store: HashMap<String, String> = HashMap::new();
let state_mutex = Arc::new(Mutex::new(kv_store));
let db_url = get_db_url(&config);
let pool_options = PoolOptions::new()
.max_connections(20)
.min_connections(5);
let pool = pool_options.connect(db_url.as_str()).await?;
Ok(Self {
state: state_mutex,
db: Arc::new(pool)
})
}
}
fn get_db_url(config: &IceBingoConfig) -> String {
match config.database.db_type.as_str() {
"postgresql" => format!(
"postgresql://{}:{}@{}/{}",
config.database.user,
config.database.password,
config.database.host,
config.database.database
),
_ => "".to_string()
}
}

6
src/model/bingo_card.rs Normal file
View File

@@ -0,0 +1,6 @@
use crate::model::train::Train;
struct BingoCard {
id: uuid::Uuid,
fields: [Train; 24],
}

14
src/model/database.rs Normal file
View File

@@ -0,0 +1,14 @@
use uuid::Uuid;
#[derive(sqlx::FromRow, Debug, Clone)]
pub struct User {
pub uuid: Uuid,
pub name: String,
}
#[derive(sqlx::FromRow, Debug, Clone)]
pub struct Train {
pub uuid: Uuid,
pub tz_id: i32,
pub name: Option<String>,
}

View File

@@ -0,0 +1,26 @@
use serde::Deserialize;
use crate::model::travelynx::TrainType;
#[derive(Debug, Deserialize)]
pub struct TrainOrdering {
#[serde(rename = "fahrzeuggruppen")]
pub train_sets: Vec<TrainSet>,
}
#[derive(Debug, Deserialize)]
pub struct TrainSet {
#[serde(rename = "bezeichnung")]
pub identifier: String,
#[serde(rename = "fahrtreferenz")]
pub journey: Journey,
}
#[derive(Debug, Deserialize)]
pub struct Journey {
#[serde(rename = "typ")]
pub category: String,
#[serde(rename = "gattung")]
pub train_type: TrainType,
#[serde(rename = "fahrtnummer")]
pub trip_number: usize,
}

8
src/model/mod.rs Normal file
View File

@@ -0,0 +1,8 @@
pub mod uic;
pub mod db_vendo_navigator_api;
pub(crate) mod travelynx;
pub(crate) mod traewelling;
mod bingo_card;
mod train;
pub(crate) mod app;
pub(crate) mod database;

6
src/model/traewelling.rs Normal file
View File

@@ -0,0 +1,6 @@
use serde::Deserialize;
#[derive(Debug, Deserialize)]
pub(crate) struct CheckIn {
}

4
src/model/train.rs Normal file
View File

@@ -0,0 +1,4 @@
use crate::model::uic::UIC;
pub(crate) struct Train {
uic: UIC,
}

92
src/model/travelynx.rs Normal file
View File

@@ -0,0 +1,92 @@
use serde::{de, Deserialize};
use strum_macros::{Display, EnumString};
#[derive(Debug, Deserialize)]
pub(crate) struct CheckIn {
#[serde(deserialize_with = "reason_to_enum")]
pub reason: CheckInReason,
pub status: CheckInStatus,
}
#[derive(Debug, Deserialize, EnumString)]
#[strum(ascii_case_insensitive)]
pub enum CheckInReason {
PING,
CHECKIN,
UPDATE,
UNDO,
}
fn reason_to_enum<'de, D>(deserializer: D) -> Result<CheckInReason, D::Error>
where
D: de::Deserializer<'de>,
{
let s: &str = de::Deserialize::deserialize(deserializer)?;
CheckInReason::try_from(s).map_err(de::Error::custom)
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CheckInStatus {
action_time: usize,
backend: Backend,
checked_in: bool,
comment: Option<String>,
deprecated: bool,
pub from_station: Station,
//pub to_station: Station,
pub train: Train
}
#[derive(Debug, Deserialize, EnumString)]
#[strum(ascii_case_insensitive)]
enum BackendType {
DBRIS,
}
#[derive(Debug, Deserialize)]
struct Backend {
id: u8,
name: String,
#[serde(rename = "type")]
backend_type: BackendType,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Station {
ds100: Option<String>,
latitude: Option<f64>,
longitude: Option<f64>,
platform: Option<String>,
real_time: Option<usize>,
pub scheduled_time: Option<usize>,
pub uic: usize,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Train {
hafas_id: Option<String>,
id: String,
line: Option<String>,
#[serde(rename = "no")]
pub number: Option<String>,
#[serde(rename = "type")]
pub train_type: Option<TrainType>,
}
#[derive(Debug, Display, Deserialize, EnumString, Copy, Clone)]
#[serde(rename_all = "UPPERCASE")]
pub enum TrainType {
ICE,
IC,
ECE,
EC,
RE,
RB,
MEX,
S,
U,
BUS,
}

98
src/model/uic.rs Normal file
View File

@@ -0,0 +1,98 @@
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub(crate) struct UIC {
type_code: TypeCode,
country_code: CountryCode,
national_block: NationalBlock,
check: char,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
enum TypeCode {
Miscellaneous = 90,
ElectricLocomotive = 91,
DieselLocomotive = 92,
ElectricMultipleUnitHighSpeed = 93,
ElectricMultipleUnitLowSpeed = 94,
DieselMultipleUnit = 95,
SpecialisedTrailer = 96,
ElectricShunter = 97,
DieselShunter = 98,
SpecialVehicle = 99,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
enum CountryCode {
Finland = 10,
Russia = 20,
Belarus = 21,
Ukraine = 22,
Moldova = 23,
Lithuania = 24,
Latvia = 25,
Estonia = 26,
Kazakhstan = 27,
Georgia = 28,
Uzbekistan = 29,
NorthKorea = 30,
Mongolia = 31,
Vietnam = 32,
China = 33,
Laos = 34,
Cuba = 40,
Albania = 41,
Japan = 42,
SerbRepublicOfBosniaHerzegovina = 44,
BosniaHerzegovina = 49,
MuslimCroatFederationOfBosniaHerzegovina = 50,
Poland = 51,
Bulgaria = 52,
Romania = 53,
CzechRepublic = 54,
Hungary = 55,
Slovakia = 56,
Azerbaijan = 57,
Armenia = 58,
Kyrgyzstan = 59,
Ireland = 60,
SouthKorea = 61,
Montenegro = 62,
NorthMacedonia = 65,
Tajikistan = 66,
Turkmenistan = 67,
Afghanistan = 68,
UnitedKingdom = 70,
Spain = 71,
Serbia = 72,
GreeceKingdom = 73,
Sweden = 74,
Turkey = 75,
Norway = 76,
Croatia = 78,
Slovenia = 79,
Germany = 80,
Austria = 81,
Luxembourg = 82,
Italian = 83,
Netherlands = 84,
Switzerland = 85,
Denmark = 86,
France = 87,
Belgium = 88,
Tanzania = 89,
Egypt = 90,
Tunesia = 91,
Algeria = 92,
Marocco = 93,
Portugal = 94,
Israel = 95,
Iran = 96,
Syriac = 97,
Lebanon = 98,
Iraq = 99,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
struct NationalBlock {
digits: [char; 7],
}