Compare commits
2 Commits
1957ff7f9f
...
d7c5f0f048
Author | SHA1 | Date | |
---|---|---|---|
|
d7c5f0f048 | ||
|
2a89528b8f |
@ -4,6 +4,7 @@ version = "0.1.0"
|
|||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
async-tungstenite = {version="0.29.1", features=["tokio-rustls-webpki-roots"]}
|
||||||
chrono = "0.4.41"
|
chrono = "0.4.41"
|
||||||
env_logger = "0.11.8"
|
env_logger = "0.11.8"
|
||||||
futures-lite = "2.6.0"
|
futures-lite = "2.6.0"
|
||||||
@ -12,6 +13,7 @@ lazy_static = "1.5.0"
|
|||||||
nusb = "0.1.13"
|
nusb = "0.1.13"
|
||||||
reqwest = { version = "0.12.15", features = ["json", "multipart", "http2", "cookies"] }
|
reqwest = { version = "0.12.15", features = ["json", "multipart", "http2", "cookies"] }
|
||||||
reqwest-middleware = "0.4.2"
|
reqwest-middleware = "0.4.2"
|
||||||
|
rustls = "0.23.27"
|
||||||
serde = {version = "1.0.219", features=["derive"]}
|
serde = {version = "1.0.219", features=["derive"]}
|
||||||
serde_json = "1.0.140"
|
serde_json = "1.0.140"
|
||||||
tokio = {version = "1.45.0", features=["time", "fs", "io-util", "macros"]}
|
tokio = {version = "1.45.0", features=["time", "fs", "io-util", "macros"]}
|
||||||
|
@ -3,6 +3,5 @@
|
|||||||
"SAVING_INTERVAL": 60,
|
"SAVING_INTERVAL": 60,
|
||||||
"STATION_ID": 2,
|
"STATION_ID": 2,
|
||||||
"HOST": "https://beta.alkator.cz",
|
"HOST": "https://beta.alkator.cz",
|
||||||
"LOGIN": "station_register@alkator.cz",
|
"WSS_HOST": "wss://beta.alkator.cz"
|
||||||
"PASSWORD": "password_heslo"
|
|
||||||
}
|
}
|
@ -12,8 +12,7 @@ pub struct Config {
|
|||||||
pub SAVING_INTERVAL: u64,
|
pub SAVING_INTERVAL: u64,
|
||||||
pub STATION_ID: usize,
|
pub STATION_ID: usize,
|
||||||
pub HOST: String,
|
pub HOST: String,
|
||||||
pub LOGIN: String,
|
pub WSS_HOST: String,
|
||||||
pub PASSWORD: String,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_config_from_file<P: AsRef<Path>>(path: P) -> Result<Config, Box<dyn Error>> {
|
fn read_config_from_file<P: AsRef<Path>>(path: P) -> Result<Config, Box<dyn Error>> {
|
||||||
|
@ -0,0 +1,50 @@
|
|||||||
|
use iced::futures;
|
||||||
|
use iced::task::{Never, Sipper, sipper};
|
||||||
|
|
||||||
|
use futures::stream::StreamExt;
|
||||||
|
|
||||||
|
use async_tungstenite::tungstenite;
|
||||||
|
use crate::config::CONFIG;
|
||||||
|
|
||||||
|
pub fn connect() -> impl Sipper<Never, Event> {
|
||||||
|
sipper(async |mut output| {
|
||||||
|
let endpoint_addr: String = CONFIG.WSS_HOST.clone() + "/api/live/racers";
|
||||||
|
loop {
|
||||||
|
|
||||||
|
let mut websocket =
|
||||||
|
match async_tungstenite::tokio::connect_async(endpoint_addr.as_str()).await
|
||||||
|
{
|
||||||
|
Ok((websocket, _)) => {
|
||||||
|
websocket.fuse()
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
tokio::time::sleep(tokio::time::Duration::from_secs(1))
|
||||||
|
.await;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
println!("Websocket Connected!");
|
||||||
|
loop {
|
||||||
|
futures::select! {
|
||||||
|
received = websocket.select_next_some() => {
|
||||||
|
match received {
|
||||||
|
Ok(tungstenite::Message::Text(message)) => {
|
||||||
|
output.send(Event::MessageReceived(String::from(message.as_str()))).await;
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
println!("Websocket Disconnected!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Ok(_) => {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum Event {
|
||||||
|
MessageReceived(String),
|
||||||
|
}
|
@ -57,38 +57,31 @@ struct RegisterRacer{
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn station_register(card_id: usize, time: DateTime::<Local>) -> Result<(), reqwest::Error>{
|
async fn station_register(card_id: usize, time: DateTime::<Local>) -> Result<(), reqwest::Error>{
|
||||||
let client = reqwest::Client::builder()
|
|
||||||
.cookie_store(true)
|
|
||||||
.build()
|
|
||||||
.unwrap();
|
|
||||||
let result = client
|
|
||||||
.post(CONFIG.HOST.clone() + "/api/login")
|
|
||||||
.form(&[
|
|
||||||
("login", CONFIG.LOGIN.as_str()),
|
|
||||||
("password", CONFIG.PASSWORD.as_str()),
|
|
||||||
]);
|
|
||||||
.send()
|
|
||||||
.await?;
|
|
||||||
let register_racer = RegisterRacer{
|
let register_racer = RegisterRacer{
|
||||||
card_id: card_id,
|
card_id: card_id,
|
||||||
station_id: CONFIG.STATION_ID,
|
station_id: CONFIG.STATION_ID,
|
||||||
time: format!("{}", time.format("%d.%m.%Y %H:%M:%S.%f")),
|
time: format!("{}", time.format("%d.%m.%Y %H:%M:%S.%6f")),
|
||||||
};
|
};
|
||||||
client
|
Client::new()
|
||||||
.post(CONFIG.HOST.clone() + "/api/station/register")
|
.post(CONFIG.HOST.clone() + "/api/station/register")
|
||||||
.json(®ister_racer)
|
.json(®ister_racer)
|
||||||
.send()
|
.send()
|
||||||
.await?;
|
.await?;
|
||||||
|
// Result can be error (400 and so on), whatever for now
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
impl State{
|
impl State{
|
||||||
fn update(&mut self, message: Message) -> Task<Message>{
|
fn update(&mut self, message: Message) -> Task<Message>{
|
||||||
match message {
|
match message {
|
||||||
Message::RacerAdded(racer) => {
|
Message::RacerRecieved(event) => {
|
||||||
self.db.insert(racer.card_id, racer);
|
match event {
|
||||||
Task::none()
|
db_update::Event::MessageReceived(s) => {
|
||||||
},
|
let racer: Racer = serde_json::from_str(s.as_str()).unwrap();
|
||||||
|
self.db.insert(racer.card_id, racer);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
Message::Tick(time) => {
|
Message::Tick(time) => {
|
||||||
if let Some(racer_time) = self.racers.iter().next() {
|
if let Some(racer_time) = self.racers.iter().next() {
|
||||||
if time - racer_time.time > Duration::new(CONFIG.DURATION + 10, 0){
|
if time - racer_time.time > Duration::new(CONFIG.DURATION + 10, 0){
|
||||||
@ -107,8 +100,10 @@ impl State{
|
|||||||
let time = Instant::now();
|
let time = Instant::now();
|
||||||
let datetime = Local::now();
|
let datetime = Local::now();
|
||||||
if let Some(racer) = self.db.get(&card_id){
|
if let Some(racer) = self.db.get(&card_id){
|
||||||
let racer_time = RacerTime{time, racer: racer.clone()};
|
if !self.racers.iter().any(|rt| rt.racer.card_id == card_id){
|
||||||
self.racers.push(racer_time);
|
let racer_time = RacerTime{time, racer: racer.clone()};
|
||||||
|
self.racers.push(racer_time);
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
println!("Racer {} not found in db!", card_id)
|
println!("Racer {} not found in db!", card_id)
|
||||||
}
|
}
|
||||||
@ -165,6 +160,7 @@ impl State{
|
|||||||
time::every(milliseconds(10)).map(Message::Tick),
|
time::every(milliseconds(10)).map(Message::Tick),
|
||||||
time::every(seconds(CONFIG.SAVING_INTERVAL)).map(Message::DumpState),
|
time::every(seconds(CONFIG.SAVING_INTERVAL)).map(Message::DumpState),
|
||||||
Subscription::run(card_reader::connect).map(Message::CardReader),
|
Subscription::run(card_reader::connect).map(Message::CardReader),
|
||||||
|
Subscription::run(db_update::connect).map(Message::RacerRecieved)
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
fn theme(&self) -> Theme {
|
fn theme(&self) -> Theme {
|
||||||
@ -180,7 +176,7 @@ struct Racer{
|
|||||||
|
|
||||||
enum Message{
|
enum Message{
|
||||||
CardReader(card_reader::Event),
|
CardReader(card_reader::Event),
|
||||||
RacerAdded(Racer),
|
RacerRecieved(db_update::Event),
|
||||||
Tick(Instant),
|
Tick(Instant),
|
||||||
DumpState(Instant),
|
DumpState(Instant),
|
||||||
Nothing,
|
Nothing,
|
||||||
@ -197,6 +193,7 @@ impl std::fmt::Debug for Message {
|
|||||||
pub fn main() -> iced::Result {
|
pub fn main() -> iced::Result {
|
||||||
let init_state = || -> State {read_to_string("state.json").ok().map(|s| serde_json::from_str(&s).ok()).flatten().unwrap_or_else(||Default::default())} ;
|
let init_state = || -> State {read_to_string("state.json").ok().map(|s| serde_json::from_str(&s).ok()).flatten().unwrap_or_else(||Default::default())} ;
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
|
rustls::crypto::aws_lc_rs::default_provider().install_default().unwrap();
|
||||||
iced::application(init_state, State::update, State::view)
|
iced::application(init_state, State::update, State::view)
|
||||||
.subscription(State::subscription)
|
.subscription(State::subscription)
|
||||||
.theme(State::theme)
|
.theme(State::theme)
|
||||||
|
2
log.json
2
log.json
@ -1 +1 @@
|
|||||||
[]
|
[{"url": "https://beta.alkator.cz/api/card/register", "json": {"racer_id": 60, "starting_number": 2, "card_id": 1364550814, "time": "10.05.2025 17:40:13.486403"}}, {"url": "https://beta.alkator.cz/api/station/register", "json": {"card_id": 1364550814, "time": "10.05.2025 17:42:45.425016", "station_id": 1}}]
|
Loading…
x
Reference in New Issue
Block a user