Skip to content

Commit 66da4be

Browse files
committed
Moved LeFrecce code to a separate module
1 parent 51488c6 commit 66da4be

File tree

6 files changed

+256
-252
lines changed

6 files changed

+256
-252
lines changed

src/lefrecce.rs

Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
use chrono::TimeZone;
2+
use serde::{Deserialize, Serialize};
3+
4+
use crate::types::{TrainStation, TrainTrip};
5+
6+
#[derive(Serialize, Deserialize, Debug)]
7+
pub struct LFTrain {
8+
pub trainidentifier: String,
9+
pub trainacronym: Option<String>,
10+
pub traintype: char,
11+
pub pricetype: char,
12+
}
13+
14+
#[derive(Serialize, Deserialize, Debug)]
15+
pub struct LFSolution {
16+
pub idsolution: String,
17+
pub origin: String,
18+
pub destination: String,
19+
pub direction: String,
20+
pub departuretime: u64,
21+
pub arrivaltime: u64,
22+
pub minprice: Option<f64>,
23+
pub optionaltext: Option<String>,
24+
pub duration: String,
25+
pub changesno: u8,
26+
pub bookable: bool,
27+
pub saleable: bool,
28+
pub trainlist: Vec<LFTrain>,
29+
pub onlycustom: bool,
30+
pub extraInfo: Vec<String>,
31+
pub showSeat: bool,
32+
pub specialOffer: Option<f64>,
33+
pub transportMeasureList: Vec<String>,
34+
}
35+
36+
#[derive(Serialize, Deserialize, Debug)]
37+
pub struct LFLeg {
38+
pub idleg: String,
39+
pub bookingtype: char,
40+
pub segments: Vec<LFSegment>,
41+
pub servicelist: Vec<LFService>,
42+
pub gift: bool,
43+
pub trainidentifier: String,
44+
pub trainacronym: String,
45+
pub departurestation: String,
46+
pub departuretime: String,
47+
pub arrivalstation: String,
48+
pub arrivaltime: String,
49+
}
50+
#[derive(Serialize, Deserialize, Debug)]
51+
pub struct LFCredential {
52+
pub credentialid: u16,
53+
pub format: u8,
54+
pub name: String,
55+
pub description: String,
56+
pub possiblevalues: String,
57+
pub typeCredential: char,
58+
}
59+
60+
#[derive(Serialize, Deserialize, Debug)]
61+
pub struct LFOffer {
62+
pub name: String,
63+
pub extraInfo: Vec<String>,
64+
pub points: f64,
65+
pub price: f64,
66+
pub message: String,
67+
pub offeridlist: Vec<LFOfferID>,
68+
//pub credentials: Option<Vec<LFCredential>>,
69+
pub available: i64,
70+
pub visible: bool,
71+
pub selected: bool,
72+
pub specialOffers: Vec<LFOffer>,
73+
//pub standingPlace: bool,
74+
pub seatToPay: bool,
75+
pub disableSeatmapSelection: bool,
76+
pub transportMeasure: Option<String>,
77+
pub saleable: bool,
78+
}
79+
80+
#[derive(Serialize, Deserialize, Debug)]
81+
pub struct LFOfferID {
82+
pub xmlid: String,
83+
pub price: f64,
84+
pub eligible: Option<String>,
85+
pub messages: Vec<String>,
86+
}
87+
88+
#[derive(Serialize, Deserialize, Debug)]
89+
pub struct LFSubService {
90+
pub name: String,
91+
pub offerlist: Vec<LFOffer>,
92+
pub hasGift: bool,
93+
pub minprice: Option<f64>,
94+
}
95+
96+
#[derive(Serialize, Deserialize, Debug)]
97+
pub struct LFService {
98+
pub name: String,
99+
pub offerlist: Option<Vec<LFOffer>>,
100+
pub subservicelist: Option<Vec<LFSubService>>,
101+
pub hasGift: bool,
102+
pub minprice: Option<f64>,
103+
}
104+
105+
#[derive(Serialize, Deserialize, Debug)]
106+
pub struct LFSegment {
107+
pub trainidentifier: String,
108+
pub trainacronym: Option<String>,
109+
pub departurestation: String,
110+
pub departuretime: String,
111+
pub arrivalstation: String,
112+
pub arrivaltime: String,
113+
pub nodexmlid: String,
114+
pub showseatmap: bool,
115+
}
116+
117+
#[derive(Serialize, Deserialize, Debug)]
118+
pub struct LFDetailedSolution {
119+
pub idsolution: String,
120+
pub leglist: Vec<LFLeg>,
121+
pub extraInfo: Vec<String>,
122+
}
123+
124+
pub fn find_trips(
125+
from: &TrainStation,
126+
to: &TrainStation,
127+
when: &chrono::DateTime<chrono::Local>,
128+
) -> Vec<Vec<TrainTrip>> {
129+
if from.id == to.id || from.lefrecce_name.is_none() || from.lefrecce_name.is_none() {
130+
return vec![];
131+
}
132+
let mut result: Vec<Vec<TrainTrip>> = Vec::new();
133+
let client = ureq::agent();
134+
let url = format!("https://www.lefrecce.it/msite/api/solutions?origin={}&destination={}&arflag=A&adate={}&atime={}&adultno=1&childno=0&direction=A&frecce=false&onlyRegional=false",
135+
from.lefrecce_name.clone().unwrap().replace(" ", "%20"),
136+
to.lefrecce_name.clone().unwrap().replace(" ", "%20"),
137+
when.format("%d/%m/%Y"),
138+
when.format("%H")
139+
);
140+
if cfg!(debug_assertions) {
141+
println!("{}", url);
142+
}
143+
let body: Vec<LFSolution> = serde_json::from_value(
144+
client
145+
.get(url.as_str())
146+
.call()
147+
.unwrap()
148+
.into_json()
149+
.unwrap(),
150+
)
151+
.unwrap();
152+
for solution in &body {
153+
let mut train_trips: Vec<TrainTrip> = Vec::new();
154+
let url_details = format!(
155+
"https://www.lefrecce.it/msite/api/solutions/{}/standardoffers",
156+
solution.idsolution
157+
);
158+
if cfg!(debug_assertions) {
159+
println!("{}", url_details);
160+
}
161+
let body_details: LFDetailedSolution = serde_json::from_value(
162+
client
163+
.get(url_details.as_str())
164+
.call()
165+
.expect("Failed API call")
166+
.into_json()
167+
.unwrap(),
168+
)
169+
.unwrap();
170+
for leg in &body_details.leglist {
171+
for train in &leg.segments {
172+
if train.trainidentifier == String::from("Same") {
173+
continue;
174+
}
175+
let acronym = train
176+
.trainacronym
177+
.as_ref()
178+
.map_or(String::from(""), |x| String::from(x.as_str()));
179+
let train_name_exploded: Vec<&str> = train.trainidentifier.split(' ').collect();
180+
let train_number = train_name_exploded[&train_name_exploded.len() - 1];
181+
unimplemented!();
182+
let from = from;
183+
let to = to;
184+
train_trips.push(TrainTrip {
185+
departure: (
186+
from.clone(),
187+
chrono::Local
188+
.datetime_from_str(train.departuretime.as_str(), "%+")
189+
.expect("Data non valida"),
190+
),
191+
arrival: (
192+
to.clone(),
193+
chrono::Local
194+
.datetime_from_str(train.arrivaltime.as_str(), "%+")
195+
.expect("Data non valida"),
196+
),
197+
train_number: crate::utils::match_train_type(
198+
&acronym,
199+
train_number.parse::<u32>().unwrap_or(
200+
train_number
201+
.chars()
202+
.into_iter()
203+
.map(|x| if x.is_digit(10) { x } else { '0' })
204+
.collect::<String>()
205+
.parse::<u32>()
206+
.unwrap(),
207+
),
208+
),
209+
});
210+
}
211+
}
212+
result.push(train_trips);
213+
}
214+
/*if cfg!(debug_assertions) {
215+
println!("{:?}", result);
216+
}*/
217+
result
218+
}

0 commit comments

Comments
 (0)