Added view switcher. Added hard coded metars

This commit is contained in:
2022-08-10 00:01:56 -07:00
parent 34cb33b4a6
commit eaa47d312f
3 changed files with 150 additions and 27 deletions

View File

@@ -14,3 +14,25 @@ proc format_predictions*(prd: JSONNode): string =
"No prediction available" "No prediction available"
else: else:
prd["prd"].getElems.map(time => time["prdctdn"].getStr).join(", ") 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
View 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))

View File

@@ -1,47 +1,93 @@
import gintro/[gtk4, gobject, gio, adw] import gintro/[gtk4, gobject, gio, adw]
import std/[httpclient, with] import std/[with]
import strformat
import actransit import actransit
import metar
proc home_predictions: string = const airports = @["khwd", "koak", "klvk", "khaf"]
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 proc clearMetars(metar_list: gtk4.ListBox) =
let twelve_predictions = client.get_predictions(home_12, "12").format_predictions for i in 1..airports.len:
let twenty_nine_predictions = client.get_predictions(home_29, "29").format_predictions 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 = for metar in metars:
let client = newHttpClient() let metar_label = newLabel()
const office_nl = "56565" with metar_label:
const office_12 = "57111" 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 proc button_refresh_signal(b: Button,
let twelve_predictions = client.get_predictions(office_12, "12").format_predictions widgets: tuple[vs: adw.ViewStack, home: Label, office: Label, metar_list: gtk4.ListBox]) =
if widgets.vs.get_visible_child_name() == "act_view":
&"Oakland Office\nNL: {nl_predictions}\n12: {twelve_predictions}" 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) = proc activate(app: adw.Application) =
let let
window = adw.newApplicationWindow(app) 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() home_label = newLabel()
office_label = newLabel() office_label = newLabel()
refresh_button = newButtonFromIconName("view-refresh") refresh_button = newButtonFromIconName("view-refresh")
header = adw.newHeaderBar() header = adw.newHeaderBar()
mainBox = newBox(Orientation.vertical, 0) main_box = newBox(Orientation.vertical, 0)
with mainBox:
with main_box:
append header 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 home_label
append office_label append office_label
with metar_box:
append metar_list
with header: with header:
pack_end refresh_button pack_end refresh_button
with metar_list:
selectionMode = SelectionMode.none
showSeparators = true
addMetars(metar_list)
with refresh_button: with refresh_button:
iconName = "view-refresh" iconName = "view-refresh"
@@ -51,6 +97,7 @@ proc activate(app: adw.Application) =
marginBottom = 10 marginBottom = 10
marginStart = 10 marginStart = 10
marginEnd = 10 marginEnd = 10
halign = Align.start
with office_label: with office_label:
text = office_predictions().cstring text = office_predictions().cstring
@@ -58,17 +105,15 @@ proc activate(app: adw.Application) =
marginBottom = 10 marginBottom = 10
marginStart = 10 marginStart = 10
marginEnd = 10 marginEnd = 10
hexpand = true
halign = Align.start
proc button_refresh_signal(b: Button, labels: tuple[home: Label, office: Label]) = refresh_button.connect("clicked", button_refresh_signal, (view_stack, home_label, office_label, metar_list))
labels.home.text = home_predictions().cstring
labels.office.text = office_predictions().cstring
refresh_button.connect("clicked", button_refresh_signal, (home_label, office_label))
with window: with window:
title = "Toolbox" title = "Toolbox"
defaultSize = (300, 500) defaultSize = (300, 500)
content = mainBox content = main_box
show() show()
proc initAdw(app: adw.Application) = proc initAdw(app: adw.Application) =