gotransit support
This commit is contained in:
parent
09f78647d5
commit
5763f5f705
1
.gitignore
vendored
1
.gitignore
vendored
@ -16,3 +16,4 @@ Cargo.lock
|
||||
|
||||
/target
|
||||
#Cargo.lock
|
||||
/test.xml
|
||||
|
20
.vscode/tasks.json
vendored
20
.vscode/tasks.json
vendored
@ -20,9 +20,25 @@
|
||||
"args": [
|
||||
"--",
|
||||
"-c",
|
||||
"VA3UJF-1",
|
||||
"TRAINS",
|
||||
"-p",
|
||||
"23728"
|
||||
"10410"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "cargo",
|
||||
"command": "run",
|
||||
"problemMatcher": [
|
||||
"$rustc"
|
||||
],
|
||||
"label": "rust: cargo run (dry run)",
|
||||
"args": [
|
||||
"--",
|
||||
"-c",
|
||||
"N0CALL",
|
||||
"-p",
|
||||
"12345",
|
||||
"--dry-run"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
@ -17,6 +17,7 @@ reqwest = { version = "^0.11.13", features = ["json"] }
|
||||
serde = { version = "^1.0.126", features = ["derive"] }
|
||||
tokio = { version = "^1.23.0", features = ["macros", "rt-multi-thread"] }
|
||||
clap = { version = "^4.0.29", features = ["derive"] }
|
||||
# chrono = "^0.4.23"
|
||||
aprs-encode = "^0.1.2"
|
||||
arrayvec = "^0.7"
|
||||
serde-xml-rs = "^0.6.0"
|
||||
regex = "^1.7.0"
|
@ -11,4 +11,8 @@ pub struct Args {
|
||||
/// The password to use for the callsign
|
||||
#[clap(short, long)]
|
||||
pub password: String,
|
||||
|
||||
/// Do a dry run (no publishing)
|
||||
#[clap(short, long)]
|
||||
pub dry_run: bool,
|
||||
}
|
@ -32,6 +32,7 @@ pub async fn main() {
|
||||
println!("{}", packet);
|
||||
|
||||
// Push the packet to the server
|
||||
if !args.dry_run {
|
||||
let response = client
|
||||
.post("http://rotate.aprs.net:8080/")
|
||||
.header("Accept-Type", "text/plain")
|
||||
@ -55,4 +56,5 @@ pub async fn main() {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
75
src/sources/gotransit.rs
Normal file
75
src/sources/gotransit.rs
Normal file
@ -0,0 +1,75 @@
|
||||
//! Data source: http://gotracker.ca/gotracker/web/
|
||||
|
||||
use regex::Regex;
|
||||
|
||||
use crate::train::TrainInfo;
|
||||
|
||||
const CORRIDOR_IDS: [u8; 7] = [
|
||||
65, // Barrie
|
||||
31, // Kitchener
|
||||
09, // Lakeshore East
|
||||
01, // Lakeshore West
|
||||
21, // Milton
|
||||
61, // Richmond Hill
|
||||
71, // Stouffville
|
||||
];
|
||||
|
||||
#[derive(Debug, serde::Deserialize)]
|
||||
struct InServiceTripPublic {
|
||||
#[serde(rename = "EquipmentCode")]
|
||||
equipment_code: String,
|
||||
#[serde(rename = "Latitude")]
|
||||
latitude: f32,
|
||||
#[serde(rename = "Longitude")]
|
||||
longitude: f32,
|
||||
#[serde(rename = "StartStation")]
|
||||
start_station: String,
|
||||
#[serde(rename = "EndStation")]
|
||||
end_station: String,
|
||||
#[serde(rename = "TripNumber")]
|
||||
trip_number: String,
|
||||
#[serde(rename = "TripName")]
|
||||
trip_name: String,
|
||||
#[serde(rename = "CorridorCode")]
|
||||
corridor_code: String,
|
||||
}
|
||||
|
||||
/// Get all trains from GO Transit
|
||||
pub async fn get_trains() -> Result<Vec<TrainInfo>, reqwest::Error> {
|
||||
// Allocate output
|
||||
let mut output = Vec::new();
|
||||
|
||||
// Handle each corridor
|
||||
for corridor_id in CORRIDOR_IDS.iter() {
|
||||
// Make a request to the gotracker API
|
||||
println!("Requesting data for GO transit corridor {}", corridor_id);
|
||||
let response = reqwest::get(&format!("http://gotracker.ca/GOTracker/web/GODataAPIProxy.svc/TripLocation/Service/Lang/{:02}/en", corridor_id)).await?;
|
||||
let response_text = response.text().await?;
|
||||
|
||||
// Get only the data portion
|
||||
if let Some(data_xml) = Regex::new(r"<Data>(.*)</Data>")
|
||||
.unwrap()
|
||||
.captures(&response_text)
|
||||
{
|
||||
let data_xml = data_xml.get(1).unwrap().as_str();
|
||||
|
||||
// Convert to something workable
|
||||
let parsed_data: Vec<InServiceTripPublic> = serde_xml_rs::from_str(data_xml).unwrap();
|
||||
|
||||
// Convert to TrainInfo format
|
||||
for train in parsed_data {
|
||||
output.push(TrainInfo {
|
||||
identifier: format!("GO-{}{}", train.corridor_code, train.equipment_code),
|
||||
speed: 0.0,
|
||||
latitude: train.latitude,
|
||||
longitude: train.longitude,
|
||||
course: None,
|
||||
status: format!("{} to {}", train.start_station, train.end_station),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return output
|
||||
Ok(output)
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
use crate::train::TrainInfo;
|
||||
|
||||
mod viarail;
|
||||
mod gotransit;
|
||||
|
||||
pub async fn get_trains() -> Result<Vec<TrainInfo>, reqwest::Error> {
|
||||
// Build output
|
||||
@ -8,6 +9,7 @@ pub async fn get_trains() -> Result<Vec<TrainInfo>, reqwest::Error> {
|
||||
|
||||
// Collect data
|
||||
output.extend(viarail::get_trains().await?);
|
||||
output.extend(gotransit::get_trains().await?);
|
||||
|
||||
// Return output
|
||||
Ok(output)
|
||||
|
@ -1,3 +1,5 @@
|
||||
//! Data source: https://tsimobile.viarail.ca
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::train::TrainInfo;
|
||||
|
Reference in New Issue
Block a user