Really rough bart implementation

This commit is contained in:
2022-10-16 00:21:28 -07:00
parent ac9f37487e
commit e85241c998
3 changed files with 140 additions and 9 deletions

View File

@@ -15,8 +15,7 @@ proc format_predictions*(prd: JSONNode): string =
else:
prd["prd"].getElems.map(time => time["prdctdn"].getStr).join(", ")
proc home_predictions*: string =
let client = newHttpClient()
proc home_predictions*(client: HTTPClient): string =
const home_nl = "51067"
const home_12 = "58995"
const home_29 = "56557"
@@ -27,7 +26,7 @@ proc home_predictions*: string =
&"Home\nNL: {nl_predictions}\n12: {twelve_predictions}\n29: {twenty_nine_predictions}"
proc office_predictions*: string =
proc office_predictions*(client: HTTPClient): string =
let client = newHttpClient()
const office_nl = "56565"
const office_12 = "57111"

109
bart.nim Normal file
View File

@@ -0,0 +1,109 @@
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()

View File

@@ -1,9 +1,12 @@
import gintro/[gtk4, gobject, gio, adw]
import std/[with]
import std/[with, httpclient]
import actransit
import metar
import bart
const airports = @["khwd", "koak", "klvk", "khaf"]
const airports = @["khwd", "koak", "klvk", "khaf", "kmry", "ksac"]
let client = newHttpClient()
proc clearMetars(metar_list: gtk4.ListBox) =
for i in 1..airports.len:
@@ -24,12 +27,16 @@ proc addMetars(metar_list: gtk4.ListBox) =
proc button_refresh_signal(b: Button,
widgets: tuple[vs: adw.ViewStack, home: Label, office: Label, metar_list: gtk4.ListBox]) =
if widgets.vs.get_visible_child_name() == "act_view":
widgets.home.text = home_predictions().cstring
widgets.office.text = office_predictions().cstring
widgets.home.text = client.home_predictions().cstring
widgets.office.text = client.office_predictions().cstring
elif widgets.vs.get_visible_child_name() == "metar_view":
clearMetars(widgets.metar_list)
addMetars(widgets.metar_list)
proc bart_departures_signal(b: Button, widgets: tuple[dropdown: DropDown, label: Label]) =
let prediction = client.prediction_for_station_idx(widgets.dropdown.getSelected())
widgets.label.text = prediction.cstring
proc activate(app: adw.Application) =
let
window = adw.newApplicationWindow(app)
@@ -37,6 +44,9 @@ proc activate(app: adw.Application) =
switcher_bar = adw.newViewSwitcherBar()
bart_box = newBox(Orientation.vertical, 0)
bart_station_dropdown = newDropDownFromStrings(bart_station_names())
bart_get_departures_button = newButton()
bart_label = newLabel()
metar_box = newBox(Orientation.vertical, 0)
metar_list = newListBox()
@@ -77,6 +87,19 @@ proc activate(app: adw.Application) =
append home_label
append office_label
with bart_box:
marginTop = 10
marginEnd = 10
marginStart = 10
append bart_station_dropdown
append bart_get_departures_button
append bart_label
with bart_get_departures_button:
marginTop = 10
label = "Get departures".cstring
connect("clicked", bart_departures_signal, (bart_station_dropdown, bart_label))
with metar_box:
append metar_list
@@ -92,7 +115,7 @@ proc activate(app: adw.Application) =
iconName = "view-refresh"
with home_label:
text = home_predictions().cstring
text = client.home_predictions().cstring
marginTop = 10
marginBottom = 10
marginStart = 10
@@ -100,7 +123,7 @@ proc activate(app: adw.Application) =
halign = Align.start
with office_label:
text = office_predictions().cstring
text = client.office_predictions().cstring
marginTop = 10
marginBottom = 10
marginStart = 10