Skip to content

Commit

Permalink
editoast: add timetable import endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
flomonster committed Aug 10, 2023
1 parent 711f7ef commit 408960b
Show file tree
Hide file tree
Showing 10 changed files with 340 additions and 29 deletions.
1 change: 1 addition & 0 deletions editoast/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion editoast/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ reqwest = { version = "0.11", features = ["json"] }
osm4routing = "0.5.8"
osmpbfreader = "0.16.0"
itertools = "0.11"
utoipa = { version = "3.4", features = ["actix_extras"] }
utoipa = { version = "3.4", features = ["actix_extras", "chrono", "uuid"] }

[dev-dependencies]
async-std = { version = "1.12", features = ["attributes", "tokio1"] }
Expand Down
115 changes: 115 additions & 0 deletions editoast/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2166,6 +2166,95 @@ components:
required:
- name
- tags
TimetableImportItem:
properties:
path:
items:
$ref: '#/components/schemas/TimetableImportPathStep'
type: array
rolling_stock:
example: 2TGV2N2
type: string
trains:
items:
$ref: '#/components/schemas/TimetableImportTrain'
type: array
required:
- rolling_stock
- path
- trains
type: object
TimetableImportPathLocation:
discriminator:
propertyName: type
oneOf:
- properties:
offset:
format: double
type: number
track_section:
type: string
type:
enum:
- track_offset
type: string
required:
- track_section
- offset
- type
type: object
- properties:
type:
enum:
- operational_point
type: string
uic:
format: int64
type: integer
required:
- uic
- type
type: object
TimetableImportPathSchedule:
properties:
arrival_time:
format: date-time
type: string
departure_time:
format: date-time
type: string
required:
- arrival_time
- departure_time
type: object
TimetableImportPathStep:
properties:
location:
$ref: '#/components/schemas/TimetableImportPathLocation'
schedule:
additionalProperties:
$ref: '#/components/schemas/TimetableImportPathSchedule'
example:
'7015':
arrival_time: 2023-08-17T09:46:00+02:00
departure_time: 2023-08-17T09:56:00+02:00
type: object
required:
- location
type: object
TimetableImportTrain:
properties:
departure_time:
example: 2023-08-17T08:46:00+02:00
format: date-time
type: string
name:
example: '7015'
type: string
required:
- name
- departure_time
type: object
TimetableWithSchedulesDetails:
properties:
id:
Expand Down Expand Up @@ -4624,6 +4713,32 @@ paths:
summary: Retrieve a timetable and its train schedules
tags:
- timetable
post:
description: Import a timetable
parameters:
- description: Timetable id
in: path
name: id
required: true
schema:
format: int64
minimum: 0
type: integer
requestBody:
content:
application/json:
schema:
items:
$ref: '#/components/schemas/TimetableImportItem'
type: array
description: ''
required: true
responses:
'204':
description: Timetable was successfully imported
summary: Import a timetable
tags:
- timetable
/timetable/{id}/conflicts/:
get:
parameters:
Expand Down
9 changes: 5 additions & 4 deletions editoast/src/core/pathfinding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use super::{AsCoreRequest, Json};
pub type PathfindingWaypoints = Vec<Vec<Waypoint>>;

/// A Core pathfinding request, see also [PathfindingResponse]
#[derive(Debug, Serialize)]
#[derive(Debug, Clone, Serialize)]
pub struct PathfindingRequest {
infra: i64,
expected_version: String,
Expand Down Expand Up @@ -71,10 +71,11 @@ impl Waypoint {
}
}

pub fn bidirectional(track_section: String, offset: f64) -> [Self; 2] {
pub fn bidirectional<T: AsRef<str>>(track_section: T, offset: f64) -> [Self; 2] {
let track = track_section.as_ref().to_string();
[
Self::new(track_section.clone(), offset, Direction::StartToStop),
Self::new(track_section, offset, Direction::StopToStart),
Self::new(track.clone(), offset, Direction::StartToStop),
Self::new(track, offset, Direction::StopToStart),
]
}
}
Expand Down
28 changes: 28 additions & 0 deletions editoast/src/models/infra_objects/operational_point.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
//! Provides the [OperationalPointModel] model

use crate::error::Result;
use crate::DbPool;
use crate::{schema::OperationalPoint, tables::osrd_infra_operationalpointmodel};
use actix_web::web::{block, Data};
use derivative::Derivative;
use diesel::sql_query;
use diesel::sql_types::{Array, BigInt, Text};
use diesel::{prelude::*, result::Error as DieselError, ExpressionMethods, QueryDsl};
use editoast_derive::Model;
use serde::{Deserialize, Serialize};
Expand All @@ -18,3 +23,26 @@ pub struct OperationalPointModel {
pub data: diesel_json::Json<OperationalPoint>,
pub infra_id: i64,
}

impl OperationalPointModel {
/// Retrieve a list of operational points from the database
pub async fn retrieve_from_uic(
db_pool: Data<DbPool>,
infra_id: i64,
uic: Vec<i64>,
) -> Result<Vec<Self>> {
block(move || {
let mut conn = db_pool.get()?;
let query = format!("
SELECT * FROM osrd_infra_operationalpointmodel
WHERE infra_id = $1 AND (data->'extensions'->'identifier'->'uic')::integer = ANY($2)
");
Ok(sql_query(query)
.bind::<BigInt, _>(infra_id)
.bind::<Array<BigInt>, _>(uic)
.load(&mut conn)?)
})
.await
.unwrap()
}
}
18 changes: 18 additions & 0 deletions editoast/src/models/rolling_stock/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,24 @@ impl RollingStockModel {
.await
.unwrap()
}

/// Retrieve a rolling stock by its name
pub async fn retrieve_by_name(db_pool: Data<DbPool>, rs_name: String) -> Result<Option<Self>> {
use crate::tables::osrd_infra_rollingstock::dsl::*;
block::<_, Result<_>>(move || {
let mut conn = db_pool.get()?;
match osrd_infra_rollingstock
.filter(name.eq(rs_name))
.get_result::<Self>(&mut conn)
{
Ok(rs) => Ok(Some(rs)),
Err(DieselError::NotFound) => Ok(None),
Err(e) => Err(e.into()),
}
})
.await
.unwrap()
}
}

impl Update for RollingStockModel {
Expand Down
16 changes: 16 additions & 0 deletions editoast/src/models/timetable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use editoast_derive::Model;
use serde::{Deserialize, Serialize};

use super::train_schedule::TrainScheduleValidation;
use super::Scenario;

#[derive(
Debug,
Expand Down Expand Up @@ -149,6 +150,21 @@ impl Timetable {
pub async fn get_train_schedules(&self, db_pool: Data<DbPool>) -> Result<Vec<TrainSchedule>> {
get_timetable_train_schedules(self.id.unwrap(), db_pool).await
}

/// Retrieve the associated scenario
pub fn get_scenario(&self, db_pool: Data<DbPool>) -> Result<Scenario> {
use crate::tables::osrd_infra_scenario::dsl::*;
use diesel::prelude::*;
let self_id = self.id.expect("Timetable should have an id");
match osrd_infra_scenario
.filter(timetable_id.eq(self_id))
.get_result(&mut db_pool.get()?)
{
Ok(scenario) => Ok(scenario),
Err(diesel::result::Error::NotFound) => panic!("Timetables should have a scenario"),
Err(err) => Err(err.into()),
}
}
}

pub async fn get_timetable_train_schedules(
Expand Down
15 changes: 13 additions & 2 deletions editoast/src/views/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,19 @@ pub fn study_routes() -> impl HttpServiceFactory {
#[openapi(
info(description = "My Api description"),
tags(),
paths(health, version),
components(schemas(Version), responses())
paths(health, version, timetable::post_timetable),
components(
schemas(
Version,
// Timetable endpoints
timetable::TimetableImportItem,
timetable::TimetableImportPathStep,
timetable::TimetableImportPathLocation,
timetable::TimetableImportPathSchedule,
timetable::TimetableImportTrain
),
responses()
)
)]
pub struct OpenApiRoot;

Expand Down
Loading

0 comments on commit 408960b

Please sign in to comment.