Skip to content

Commit

Permalink
Merge pull request #541 from woshilapin/operators
Browse files Browse the repository at this point in the history
[feature] Add Operator for NeTEx France
  • Loading branch information
ArnaudOggy authored Feb 21, 2020
2 parents cdc762e + 2c03646 commit 87e7e29
Show file tree
Hide file tree
Showing 8 changed files with 160 additions and 12 deletions.
2 changes: 1 addition & 1 deletion src/documentation/ntfs_to_netex_france_specs.md
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ Example:
<lines><!-- One node Line for each Line of the dataset--></lines>
</ServiceFrame>
<ResourceFrame
id="FR:ResourceFrame:companies:<stop_provider_code>"
id="FR:ResourceFrame:operators:"
version="any">
<organisations><!-- One node Operator for each company of the dataset --></organisations>
</ResourceFrame>
Expand Down
110 changes: 110 additions & 0 deletions src/netex_france/companies.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
// Copyright (C) 2017 Kisio Digital and/or its affiliates.
//
// This program is free software: you can redistribute it and/or modify it
// under the terms of the GNU Affero General Public License as published by the
// Free Software Foundation, version 3.

// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.

// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>

use crate::{
netex_france::exporter::{Exporter, ObjectType},
objects::Company,
Model,
};
use minidom::{Element, Node};

pub struct CompanyExporter<'a> {
model: &'a Model,
}

// Publicly exposed methods
impl<'a> CompanyExporter<'a> {
pub fn new(model: &'a Model) -> Self {
CompanyExporter { model }
}
pub fn export(&self) -> Vec<Element> {
self.model
.companies
.values()
.map(|company| self.export_company(company))
.collect()
}
}

// Internal methods
impl<'a> CompanyExporter<'a> {
fn export_company(&self, company: &'a Company) -> Element {
let element_builder = Element::builder(ObjectType::Operator.to_string())
.attr(
"id",
Exporter::generate_id(&company.id, ObjectType::Operator),
)
.attr("version", "any");
let element_builder = element_builder.append(self.generate_name(company));
let element_builder = element_builder.append(self.generate_contact_details(company));
let element_builder = element_builder.append(Self::generate_organization_type());
element_builder.build()
}

fn generate_name(&self, company: &'a Company) -> Element {
Element::builder("Name")
.append(Node::Text(company.name.to_owned()))
.build()
}

fn generate_contact_details(&self, company: &'a Company) -> Element {
let element_builder = Element::builder("ContactDetails");
let element_builder = if let Some(email_element) = self.generate_email(company) {
element_builder.append(email_element)
} else {
element_builder
};
let element_builder = if let Some(phone_element) = self.generate_phone(company) {
element_builder.append(phone_element)
} else {
element_builder
};
let element_builder = if let Some(url_element) = self.generate_url(company) {
element_builder.append(url_element)
} else {
element_builder
};
element_builder.build()
}

fn generate_email(&self, company: &'a Company) -> Option<Element> {
company.mail.as_ref().map(|email| {
Element::builder("Email")
.append(Node::Text(email.to_owned()))
.build()
})
}

fn generate_phone(&self, company: &'a Company) -> Option<Element> {
company.phone.as_ref().map(|phone| {
Element::builder("Phone")
.append(Node::Text(phone.to_owned()))
.build()
})
}

fn generate_url(&self, company: &'a Company) -> Option<Element> {
company.url.as_ref().map(|url| {
Element::builder("Url")
.append(Node::Text(url.to_owned()))
.build()
})
}

fn generate_organization_type() -> Element {
Element::builder("OrganisationType")
.append(Node::Text(String::from("other")))
.build()
}
}
27 changes: 25 additions & 2 deletions src/netex_france/exporter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@
use crate::{
minidom_utils::ElementWriter,
model::Model,
netex_france::{CalendarExporter, LineExporter, NetworkExporter, StopExporter},
netex_france::{
CalendarExporter, CompanyExporter, LineExporter, NetworkExporter, StopExporter,
},
netex_utils::FrameType,
objects::Date,
Result,
Expand All @@ -39,6 +41,7 @@ pub(in crate::netex_france) enum ObjectType {
DayType,
DayTypeAssignment,
Line,
Operator,
Network,
Quay,
StopPlace,
Expand All @@ -52,6 +55,7 @@ impl Display for ObjectType {
DayType => write!(f, "DayType"),
DayTypeAssignment => write!(f, "DayTypeAssignment"),
Line => write!(f, "Line"),
Operator => write!(f, "Operator"),
Network => write!(f, "Network"),
Quay => write!(f, "Quay"),
StopPlace => write!(f, "StopPlace"),
Expand Down Expand Up @@ -189,7 +193,11 @@ impl Exporter<'_> {
let mut file = File::create(filepath)?;
let network_frames = self.create_networks_frames()?;
let lines_frame = self.create_lines_frame()?;
let frames = network_frames.into_iter().chain(iter::once(lines_frame));
let companies_frame = self.create_companies_frame();
let frames = network_frames
.into_iter()
.chain(iter::once(lines_frame))
.chain(iter::once(companies_frame));
let composite_frame_id = self.generate_frame_id(
FrameType::Composite,
&format!("NETEX_{}", VersionType::Lines),
Expand Down Expand Up @@ -234,6 +242,21 @@ impl Exporter<'_> {
Ok(frame)
}

// Returns a 'ServiceFrame' containing a list of 'Operator' in 'organisations'
fn create_companies_frame(&self) -> Element {
let company_exporter = CompanyExporter::new(&self.model);
let companies = company_exporter.export();
let companies_list = Element::builder("organisations")
.append_all(companies)
.build();
let resource_frame_id = self.generate_frame_id(FrameType::Resource, "operators");
Element::builder(FrameType::Resource.to_string())
.attr("id", resource_frame_id)
.attr("version", "any")
.append(companies_list)
.build()
}

fn write_stops<P>(&self, path: P) -> Result<()>
where
P: AsRef<Path>,
Expand Down
2 changes: 2 additions & 0 deletions src/netex_france/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
mod calendars;
use calendars::CalendarExporter;
mod companies;
use companies::CompanyExporter;
mod exporter;
pub use exporter::Exporter;
mod lines;
Expand Down
2 changes: 1 addition & 1 deletion tests/fixtures/netex_france/input_gtfs/agency.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
agency_id,agency_name,agency_url,agency_timezone,agency_lang,agency_phone,agency_email
TGN,The Great Network,http://www.navitia.io/,Europe/Paris,,,
TGN,The Great Network,https://www.the-great-network.zz,Europe/Paris,,0123456789,[email protected]
4 changes: 2 additions & 2 deletions tests/fixtures/netex_france/input_ntfs/companies.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
company_id,company_name
TGC,The Great Company
company_id,company_name,company_mail,company_phone,company_url
TGN,The Great Network,[email protected],0123456789,https://www.the-great-network.zz
12 changes: 6 additions & 6 deletions tests/fixtures/netex_france/input_ntfs/trips.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
route_id,service_id,trip_id,company_id,physical_mode_id,dataset_id
M1F,Week,M1F1,TGC,Metro,TGDS
M1B,Week,M1B1,TGC,Metro,TGDS
B42F,Week,B42F1,TGC,Bus,TGDS
B42B,Week,B42B1,TGC,Bus,TGDS
RERAF,Week,RERAF1,TGC,RapidTransit,TGDS
RERAB,Week,RERAB1,TGC,Bus,TGDS
M1F,Week,M1F1,TGN,Metro,TGDS
M1B,Week,M1B1,TGN,Metro,TGDS
B42F,Week,B42F1,TGN,Bus,TGDS
B42B,Week,B42B1,TGN,Bus,TGDS
RERAF,Week,RERAF1,TGN,RapidTransit,TGDS
RERAB,Week,RERAB1,TGN,Bus,TGDS
13 changes: 13 additions & 0 deletions tests/fixtures/netex_france/output/lignes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,19 @@
</Line>
</lines>
</ServiceFrame>
<ResourceFrame id="FR:ResourceFrame:operators:" version="any">
<organisations>
<Operator id="FR:Operator:TGN:" version="any">
<Name>The Great Network</Name>
<ContactDetails>
<Email>[email protected]</Email>
<Phone>0123456789</Phone>
<Url>https://www.the-great-network.zz</Url>
</ContactDetails>
<OrganisationType>other</OrganisationType>
</Operator>
</organisations>
</ResourceFrame>
</frames>
</CompositeFrame>
</dataObjects>
Expand Down

0 comments on commit 87e7e29

Please sign in to comment.