Added view switcher. Added hard coded metars
This commit is contained in:
@@ -14,3 +14,25 @@ proc format_predictions*(prd: JSONNode): string =
|
||||
"No prediction available"
|
||||
else:
|
||||
prd["prd"].getElems.map(time => time["prdctdn"].getStr).join(", ")
|
||||
|
||||
proc home_predictions*: string =
|
||||
let client = newHttpClient()
|
||||
const home_nl = "51067"
|
||||
const home_12 = "58995"
|
||||
const home_29 = "56557"
|
||||
|
||||
let nl_predictions = client.get_predictions(home_nl, "NL").format_predictions
|
||||
let twelve_predictions = client.get_predictions(home_12, "12").format_predictions
|
||||
let twenty_nine_predictions = client.get_predictions(home_29, "29").format_predictions
|
||||
|
||||
&"Home\nNL: {nl_predictions}\n12: {twelve_predictions}\n29: {twenty_nine_predictions}"
|
||||
|
||||
proc office_predictions*: string =
|
||||
let client = newHttpClient()
|
||||
const office_nl = "56565"
|
||||
const office_12 = "57111"
|
||||
|
||||
let nl_predictions = client.get_predictions(office_nl, "NL").format_predictions
|
||||
let twelve_predictions = client.get_predictions(office_12, "12").format_predictions
|
||||
|
||||
&"Oakland Office\nNL: {nl_predictions}\n12: {twelve_predictions}"
|
||||
|
||||
56
metar.nim
Normal file
56
metar.nim
Normal file
@@ -0,0 +1,56 @@
|
||||
import std/[httpclient, os, sequtils, sugar, strutils, xmlparser, xmltree]
|
||||
import strformat
|
||||
|
||||
proc getMetar(client: HttpClient, code: string): XMLNode =
|
||||
let requestUrl = &"https://aviationweather.gov/adds/dataserver_current/httpparam?dataSource=metars&requestType=retrieve&format=xml&hoursBeforeNow=3&mostRecent=true&stationString={code}"
|
||||
let metarData = client.getContent(requestUrl)
|
||||
parseXml(metarData)
|
||||
|
||||
proc childString(node: XMLnode, name: string): string =
|
||||
let node = node.child(name)
|
||||
if node != nil:
|
||||
result = node.innerText
|
||||
else:
|
||||
result = ""
|
||||
|
||||
type SkyCondition* = object
|
||||
skyCover: string
|
||||
cloudBaseAgl: string
|
||||
|
||||
type MetarData* = object
|
||||
rawText*: string
|
||||
stationId*: string
|
||||
observationTime*: string
|
||||
temperature*: string
|
||||
dewPoint*: string
|
||||
windHeading*: string
|
||||
windSpeedKnots*: string
|
||||
visibility*: string
|
||||
altimiter*: string
|
||||
flightCategory*: string
|
||||
skyConditions*: seq[SkyCondition]
|
||||
|
||||
proc newMetarData*(xmlData: XMLNode): MetarData =
|
||||
let metar = xmlData.child("data").child("METAR")
|
||||
|
||||
result = MetarData(
|
||||
rawText: metar.childString("raw_text"),
|
||||
stationId: metar.childString("station_id"),
|
||||
observationTime: metar.childString("observation_time"),
|
||||
temperature: metar.childString("temp_c"),
|
||||
dewPoint: metar.childString("dewpoint_c"),
|
||||
windHeading: metar.childString("wind_dir_degrees"),
|
||||
visibility: metar.childString("visibility_statute_mi"),
|
||||
altimiter: metar.childString("altim_in_hg"),
|
||||
flightCategory: metar.childString("flight_category")
|
||||
)
|
||||
|
||||
for skyConditionXml in metar.findAll("sky_condition"):
|
||||
result.skyConditions.add(
|
||||
SkyCondition(
|
||||
skyCover: skyConditionXml.attr("sky_cover"),
|
||||
cloudBaseAgl: skyconditionXml.attr("cloud_base_ft_agl")))
|
||||
|
||||
proc getMetars*(airports: seq[string]): seq[MetarData] =
|
||||
let client = newHttpClient()
|
||||
airports.map(airportCode => client.getMetar(airportCode)).map(metarXml => newMetarData(metarXml))
|
||||
99
toolbox.nim
99
toolbox.nim
@@ -1,47 +1,93 @@
|
||||
import gintro/[gtk4, gobject, gio, adw]
|
||||
import std/[httpclient, with]
|
||||
import strformat
|
||||
import std/[with]
|
||||
import actransit
|
||||
import metar
|
||||
|
||||
proc home_predictions: string =
|
||||
let client = newHttpClient()
|
||||
const home_nl = "51067"
|
||||
const home_12 = "58995"
|
||||
const home_29 = "56557"
|
||||
const airports = @["khwd", "koak", "klvk", "khaf"]
|
||||
|
||||
let nl_predictions = client.get_predictions(home_nl, "NL").format_predictions
|
||||
let twelve_predictions = client.get_predictions(home_12, "12").format_predictions
|
||||
let twenty_nine_predictions = client.get_predictions(home_29, "29").format_predictions
|
||||
proc clearMetars(metar_list: gtk4.ListBox) =
|
||||
for i in 1..airports.len:
|
||||
let metar_row = metar_list.get_row_at_index(0)
|
||||
metar_list.remove(metar_row)
|
||||
|
||||
&"Home\nNL: {nl_predictions}\n12: {twelve_predictions}\n29: {twenty_nine_predictions}"
|
||||
proc addMetars(metar_list: gtk4.ListBox) =
|
||||
let metars = getMetars(airports)
|
||||
|
||||
proc office_predictions: string =
|
||||
let client = newHttpClient()
|
||||
const office_nl = "56565"
|
||||
const office_12 = "57111"
|
||||
for metar in metars:
|
||||
let metar_label = newLabel()
|
||||
with metar_label:
|
||||
text = metar.rawText.cstring
|
||||
halign = Align.start
|
||||
wrap = true
|
||||
metar_list.append(metar_label)
|
||||
|
||||
let nl_predictions = client.get_predictions(office_nl, "NL").format_predictions
|
||||
let twelve_predictions = client.get_predictions(office_12, "12").format_predictions
|
||||
|
||||
&"Oakland Office\nNL: {nl_predictions}\n12: {twelve_predictions}"
|
||||
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
|
||||
elif widgets.vs.get_visible_child_name() == "metar_view":
|
||||
clearMetars(widgets.metar_list)
|
||||
addMetars(widgets.metar_list)
|
||||
|
||||
proc activate(app: adw.Application) =
|
||||
let
|
||||
window = adw.newApplicationWindow(app)
|
||||
view_stack = adw.newViewStack()
|
||||
switcher_bar = adw.newViewSwitcherBar()
|
||||
|
||||
bart_box = newBox(Orientation.vertical, 0)
|
||||
|
||||
metar_box = newBox(Orientation.vertical, 0)
|
||||
metar_list = newListBox()
|
||||
|
||||
act_box = newBox(Orientation.vertical, 0)
|
||||
home_label = newLabel()
|
||||
office_label = newLabel()
|
||||
|
||||
refresh_button = newButtonFromIconName("view-refresh")
|
||||
header = adw.newHeaderBar()
|
||||
mainBox = newBox(Orientation.vertical, 0)
|
||||
with mainBox:
|
||||
main_box = newBox(Orientation.vertical, 0)
|
||||
|
||||
|
||||
with main_box:
|
||||
append header
|
||||
append view_stack
|
||||
append switcher_bar
|
||||
|
||||
let
|
||||
act_view_page = view_stack.add_titled(act_box, "act_view", "AC Transit")
|
||||
bart_view_page = view_stack.add_titled(bart_box, "bart_view", "BART")
|
||||
metar_view_page = view_stack.add_titled(metar_box, "metar_view", "Metar")
|
||||
|
||||
act_view_page.set_icon_name("go-home")
|
||||
bart_view_page.set_icon_name("view-grid")
|
||||
metar_view_page.set_icon_name("weather-clear")
|
||||
|
||||
with view_stack:
|
||||
set_visible_child_name "act_view"
|
||||
vexpand = true
|
||||
|
||||
with switcher_bar:
|
||||
reveal = true
|
||||
stack = view_stack
|
||||
valign = Align.end
|
||||
|
||||
with act_box:
|
||||
append home_label
|
||||
append office_label
|
||||
|
||||
with metar_box:
|
||||
append metar_list
|
||||
|
||||
with header:
|
||||
pack_end refresh_button
|
||||
|
||||
with metar_list:
|
||||
selectionMode = SelectionMode.none
|
||||
showSeparators = true
|
||||
addMetars(metar_list)
|
||||
|
||||
with refresh_button:
|
||||
iconName = "view-refresh"
|
||||
|
||||
@@ -51,6 +97,7 @@ proc activate(app: adw.Application) =
|
||||
marginBottom = 10
|
||||
marginStart = 10
|
||||
marginEnd = 10
|
||||
halign = Align.start
|
||||
|
||||
with office_label:
|
||||
text = office_predictions().cstring
|
||||
@@ -58,17 +105,15 @@ proc activate(app: adw.Application) =
|
||||
marginBottom = 10
|
||||
marginStart = 10
|
||||
marginEnd = 10
|
||||
hexpand = true
|
||||
halign = Align.start
|
||||
|
||||
proc button_refresh_signal(b: Button, labels: tuple[home: Label, office: Label]) =
|
||||
labels.home.text = home_predictions().cstring
|
||||
labels.office.text = office_predictions().cstring
|
||||
|
||||
refresh_button.connect("clicked", button_refresh_signal, (home_label, office_label))
|
||||
refresh_button.connect("clicked", button_refresh_signal, (view_stack, home_label, office_label, metar_list))
|
||||
|
||||
with window:
|
||||
title = "Toolbox"
|
||||
defaultSize = (300, 500)
|
||||
content = mainBox
|
||||
content = main_box
|
||||
show()
|
||||
|
||||
proc initAdw(app: adw.Application) =
|
||||
|
||||
Reference in New Issue
Block a user