import std/[httpclient, sequtils, sugar, 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))