Files
toolbox/bart.nim

110 lines
3.7 KiB
Nim

import std/[json, httpclient, sequtils, strformat, strutils]
type Station = object
id: string
name: string
type Departure = ref object
destination: string
color: string
estimates: seq[uint]
proc newStation(id: string, name: string): Station =
Station(id: id, name: name)
const bart_stations = @[
newStation("12th", "12th St. Oakland City Center"),
newStation("16th", "16th St. Mission (SF)"),
newStation("19th", "19th St. Oakland"),
newStation("24th", "24th St. Mission (SF)"),
newStation("ashb", "Ashby (Berkeley)"),
newStation("antc", "Antioch"),
newStation("balb", "Balboa Park (SF)"),
newStation("bayf", "Bay Fair (San Leandro)"),
newStation("bery", "Berryessa / North San Jose"),
newStation("cast", "Castro Valley"),
newStation("civc", "Civic Center (SF)"),
newStation("cols", "Coliseum"),
newStation("colm", "Colma"),
newStation("conc", "Concord"),
newStation("daly", "Daly City"),
newStation("dbrk", "Downtown Berkeley"),
newStation("dubl", "Dublin/Pleasanton"),
newStation("deln", "El Cerrito del Norte"),
newStation("plza", "El Cerrito Plaza"),
newStation("embr", "Embarcadero (SF)"),
newStation("frmt", "Fremont"),
newStation("ftvl", "Fruitvale (Oakland)"),
newStation("glen", "Glen Park (SF)"),
newStation("hayw", "Hayward"),
newStation("lafy", "Lafayette"),
newStation("lake", "Lake Merritt (Oakland)"),
newStation("mcar", "MacArthur (Oakland)"),
newStation("mlbr", "Millbrae"),
newStation("mlpt", "Milpitas"),
newStation("mont", "Montgomery St. (SF)"),
newStation("nbrk", "North Berkeley"),
newStation("ncon", "North Concord/Martinez"),
newStation("oakl", "Oakland Int'l Airport"),
newStation("orin", "Orinda"),
newStation("pitt", "Pittsburg/Bay Point"),
newStation("pctr", "Pittsburg Center"),
newStation("phil", "Pleasant Hill"),
newStation("powl", "Powell St. (SF)"),
newStation("rich", "Richmond"),
newStation("rock", "Rockridge (Oakland)"),
newStation("sbrn", "San Bruno"),
newStation("sfia", "San Francisco Int'l Airport"),
newStation("sanl", "San Leandro"),
newStation("shay", "South Hayward"),
newStation("ssan", "South San Francisco"),
newStation("ucty", "Union City"),
newStation("warm", "Warm Springs/South Fremont"),
newStation("wcrk", "Walnut Creek"),
newStation("wdub", "West Dublin"),
newStation("woak", "West Oakland"),
]
proc bart_station_names*(): seq[string] =
bart_stations.map(proc(s: Station): string = s.name)
proc get_departures(client: HTTPClient, station: Station): JSONNode =
let id = station.id
let response = client.get(&"http://api.bart.gov/api/etd.aspx?cmd=etd&orig={id}&key=MW9S-E7SL-26DU-VV8V&json=y")
parseJSON(response.body)
proc format_estimate_minutes(minutes: string): uint =
case minutes:
of "Leaving":
return 0.uint
else:
return parseUInt(minutes)
proc parse_departures(etd: JSONNode): seq[Departure] =
if not etd["root"].hasKey("station"):
return @[]
let lines = etd["root"]["station"][0]["etd"].getElems
lines.map(proc (line: JSONNode): Departure =
let dest = line["destination"].getStr
let color = line["estimate"][0]["color"].getStr
let estimates = line["estimate"].getElems.map(proc(estimate: JSONNode): uint =
format_estimate_minutes(estimate["minutes"].getStr)
)
Departure(destination: dest, color: color, estimates: estimates)
)
proc format_departures(departures: seq[Departure]): string =
departures.map(proc (d: Departure): string =
let estimates = d.estimates.join(", ")
&"{d.destination}\t{estimates}"
).join("\n")
proc prediction_for_station_idx*(client: HTTPClient, idx: int): string =
let station = bart_stations[idx]
client.get_departures(station).parse_departures().format_departures()