110 lines
3.7 KiB
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()
|