Skip to content

Commit 7df202d

Browse files
committed
editoast: add train import command for train schedule v2
1 parent a65a503 commit 7df202d

File tree

3 files changed

+146
-3
lines changed

3 files changed

+146
-3
lines changed

editoast/src/client/mod.rs

+16
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,22 @@ pub enum Commands {
5050
Search(SearchCommands),
5151
#[command(subcommand, about, long_about = "Infrastructure related commands")]
5252
Infra(InfraCommands),
53+
#[command(subcommand, about, long_about = "Trains related commands")]
54+
Trains(TrainsCommands),
55+
}
56+
57+
#[derive(Subcommand, Debug)]
58+
pub enum TrainsCommands {
59+
Import(ImportTrainArgs),
60+
}
61+
62+
#[derive(Args, Debug, Derivative)]
63+
#[derivative(Default)]
64+
#[command(about, long_about = "Import a train given a file")]
65+
pub struct ImportTrainArgs {
66+
#[arg(long)]
67+
pub timetable: Option<String>,
68+
pub path: String,
5369
}
5470

5571
#[derive(Subcommand, Debug)]

editoast/src/main.rs

+53-3
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,11 @@ use crate::core::CoreClient;
2121
use crate::error::InternalError;
2222
use crate::map::redis_utils::RedisClient;
2323
use crate::models::{Create, Delete, Infra};
24+
use crate::modelsv2::timetable::Timetable;
25+
use crate::modelsv2::Retrieve as RetrieveV2;
26+
use crate::modelsv2::{Create as CreateV2, Model};
2427
use crate::schema::electrical_profiles::ElectricalProfileSetData;
28+
use crate::schema::v2::trainschedule::TrainScheduleBase;
2529
use crate::schema::RailJson;
2630
use crate::views::infra::InfraForm;
2731
use crate::views::OpenApiRoot;
@@ -34,10 +38,13 @@ use chashmap::CHashMap;
3438
use clap::Parser;
3539
use client::{
3640
ClearArgs, Client, Color, Commands, DeleteProfileSetArgs, ElectricalProfilesCommands,
37-
GenerateArgs, ImportProfileSetArgs, ImportRailjsonArgs, ImportRollingStockArgs, InfraCloneArgs,
38-
InfraCommands, ListProfileSetArgs, MakeMigrationArgs, RedisConfig, RefreshArgs, RunserverArgs,
39-
SearchCommands,
41+
GenerateArgs, ImportProfileSetArgs, ImportRailjsonArgs, ImportRollingStockArgs,
42+
ImportTrainArgs, InfraCloneArgs, InfraCommands, ListProfileSetArgs, MakeMigrationArgs,
43+
RedisConfig, RefreshArgs, RunserverArgs, SearchCommands, TrainsCommands,
4044
};
45+
use modelsv2::train_schedule::TrainScheduleChangeset;
46+
use views::v2::train_schedule::TrainScheduleForm;
47+
4148
use colored::*;
4249
use diesel::{sql_query, ConnectionError, ConnectionResult};
4350
use diesel_async::pooled_connection::deadpool::Pool;
@@ -184,7 +191,50 @@ async fn run() -> Result<(), Box<dyn Error + Send + Sync>> {
184191
}
185192
InfraCommands::ImportRailjson(args) => import_railjson(args, create_db_pool()?).await,
186193
},
194+
Commands::Trains(subcommand) => match subcommand {
195+
TrainsCommands::Import(args) => trains_import(args, create_db_pool()?).await,
196+
},
197+
}
198+
}
199+
200+
async fn trains_import(
201+
args: ImportTrainArgs,
202+
db_pool: Data<DbPool>,
203+
) -> Result<(), Box<dyn Error + Send + Sync>> {
204+
let conn = &mut db_pool.get().await?;
205+
let timetable = match args.timetable {
206+
Some(timetable) => match Timetable::retrieve(conn, timetable.parse::<i64>()?).await? {
207+
Some(timetable) => timetable,
208+
None => {
209+
let error = CliError::new(1, format!("❌ Timetable not found, id: {timetable}"));
210+
return Err(Box::new(error));
211+
}
212+
},
213+
None => {
214+
let changeset = Timetable::changeset();
215+
changeset.create(conn).await?
216+
}
217+
};
218+
219+
let train_file = File::open(args.path)?;
220+
let train_schedules: Vec<TrainScheduleBase> =
221+
serde_json::from_reader(BufReader::new(train_file))?;
222+
let ts_length = train_schedules.len();
223+
224+
for train_schedule in train_schedules {
225+
let form = TrainScheduleForm {
226+
timetable_id: timetable.id,
227+
train_schedule,
228+
};
229+
let changeset: TrainScheduleChangeset = form.into();
230+
changeset.create(conn).await?;
187231
}
232+
233+
println!(
234+
"✅ {} train schedules created for timetable with id {}", ts_length, timetable.id
235+
);
236+
237+
Ok(())
188238
}
189239

190240
fn init_sentry(args: &RunserverArgs) -> Option<ClientInitGuard> {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
[
2+
{
3+
"train_name": "ABC3615",
4+
"rolling_stock_name": "R2D2",
5+
"labels": [
6+
"choo-choo",
7+
"tchou-tchou"
8+
],
9+
"speed_limit_tag": "MA100",
10+
"start_time": "2023-12-21T08:51:30+00:00",
11+
"path": [
12+
{
13+
"id": "a",
14+
"uic": 87210
15+
},
16+
{
17+
"id": "b",
18+
"track": "foo",
19+
"offset": 10
20+
},
21+
{
22+
"id": "c",
23+
"deleted": true,
24+
"trigram": "ABC"
25+
},
26+
{
27+
"id": "d",
28+
"operational_point": "X"
29+
}
30+
],
31+
"constraint_distribution": "MARECO",
32+
"schedule": [
33+
{
34+
"at": "a",
35+
"stop_for": "PT5M",
36+
"locked": true
37+
},
38+
{
39+
"at": "b",
40+
"arrival": "PT10M",
41+
"stop_for": "PT5M"
42+
},
43+
{
44+
"at": "c",
45+
"stop_for": "PT5M"
46+
},
47+
{
48+
"at": "d",
49+
"arrival": "PT50M",
50+
"locked": true
51+
}
52+
],
53+
"margins": {
54+
"boundaries": [
55+
"b",
56+
"c"
57+
],
58+
"values": [
59+
"5%",
60+
"3min/km",
61+
"none"
62+
]
63+
},
64+
"initial_speed": 2.5,
65+
"power_restrictions": [
66+
{
67+
"from": "b",
68+
"to": "c",
69+
"value": "M1C1"
70+
}
71+
],
72+
"comfort": "AIR_CONDITIONING",
73+
"options": {
74+
"use_electrical_profiles": true
75+
}
76+
}
77+
]

0 commit comments

Comments
 (0)