2023-08-21 23:56:17 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
2023-08-26 03:22:16 +00:00
|
|
|
"io"
|
|
|
|
"net/http"
|
2023-08-21 23:56:17 +00:00
|
|
|
"os"
|
2023-08-26 03:22:16 +00:00
|
|
|
"strings"
|
2023-08-21 23:56:17 +00:00
|
|
|
|
|
|
|
"github.com/alecthomas/repr"
|
|
|
|
"github.com/spf13/pflag"
|
|
|
|
"go.elara.ws/logger"
|
|
|
|
"go.elara.ws/logger/log"
|
|
|
|
"go.elara.ws/taf"
|
|
|
|
"go.elara.ws/taf/units"
|
|
|
|
)
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
log.Logger = logger.NewPretty(os.Stderr)
|
|
|
|
}
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
pretty := pflag.BoolP("pretty", "p", true, "Pretty-print the JSON output")
|
|
|
|
printGo := pflag.BoolP("print-go", "G", false, "Print Go code instead of JSON")
|
2023-08-23 02:52:41 +00:00
|
|
|
convertDist := pflag.StringP("convert-distance", "d", "", "Convert all the distances to the given unit. (valid units: mi, m, km)")
|
|
|
|
convertSpd := pflag.StringP("convert-speed", "s", "", "Convert all the speeds to the given unit. (valid units: m/s, kph, kts, mph)")
|
2023-08-26 03:22:16 +00:00
|
|
|
identifier := pflag.StringP("identifier", "i", "", "Automatically fetch the TAF report for the specified ICAO identifier")
|
2023-08-21 23:56:17 +00:00
|
|
|
pflag.Parse()
|
|
|
|
|
|
|
|
var opts taf.Options
|
|
|
|
|
|
|
|
if *convertDist != "" {
|
|
|
|
d, ok := units.ParseDistance(*convertDist)
|
|
|
|
if !ok {
|
|
|
|
log.Fatal("Invalid distance unit").Send()
|
|
|
|
}
|
|
|
|
opts.DistanceUnit = d
|
|
|
|
}
|
|
|
|
|
|
|
|
if *convertSpd != "" {
|
|
|
|
s, ok := units.ParseSpeed(*convertSpd)
|
|
|
|
if !ok {
|
|
|
|
log.Fatal("Invalid speed unit").Send()
|
|
|
|
}
|
|
|
|
opts.SpeedUnit = s
|
|
|
|
}
|
|
|
|
|
2023-08-26 03:22:16 +00:00
|
|
|
var r io.Reader
|
2023-08-21 23:56:17 +00:00
|
|
|
var err error
|
|
|
|
if pflag.NArg() > 0 {
|
2023-08-26 03:22:16 +00:00
|
|
|
fl, err := os.Open(pflag.Arg(0))
|
2023-08-21 23:56:17 +00:00
|
|
|
if err != nil {
|
|
|
|
log.Fatal("Error opening file").Err(err).Send()
|
|
|
|
}
|
2023-08-26 03:22:16 +00:00
|
|
|
defer fl.Close()
|
|
|
|
r = fl
|
|
|
|
} else if *identifier != "" {
|
|
|
|
// Identifiers must be uppercase
|
|
|
|
*identifier = strings.ToUpper(*identifier)
|
|
|
|
// Get the TAF report from aviationweather.gov's beta endpoint
|
|
|
|
res, err := http.Get("https://beta.aviationweather.gov/cgi-bin/data/taf.php?ids=" + *identifier)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal("Error getting TAF report").Err(err).Send()
|
|
|
|
}
|
|
|
|
// The backend doesn't return an error for non-existent reports, so check the content length instead
|
|
|
|
if res.ContentLength == 0 {
|
|
|
|
log.Fatal("Could not find a TAF report for the specified airport").Str("id", *identifier).Send()
|
|
|
|
}
|
|
|
|
defer res.Body.Close()
|
|
|
|
r = res.Body
|
2023-08-21 23:56:17 +00:00
|
|
|
} else {
|
2023-08-26 03:22:16 +00:00
|
|
|
r = os.Stdin
|
2023-08-21 23:56:17 +00:00
|
|
|
}
|
|
|
|
|
2023-08-26 03:22:16 +00:00
|
|
|
fc, err := taf.DecodeWithOptions(r, opts)
|
2023-08-21 23:56:17 +00:00
|
|
|
if err != nil {
|
|
|
|
log.Fatal("Error parsing TAF data").Err(err).Send()
|
|
|
|
}
|
|
|
|
|
|
|
|
if *printGo {
|
2023-08-23 04:08:50 +00:00
|
|
|
repr.New(os.Stdout, repr.ScalarLiterals()).Println(fc)
|
2023-08-21 23:56:17 +00:00
|
|
|
} else {
|
|
|
|
enc := json.NewEncoder(os.Stdout)
|
|
|
|
if *pretty {
|
|
|
|
enc.SetIndent("", " ")
|
|
|
|
}
|
|
|
|
err = enc.Encode(fc)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal("Error encoding forecast").Err(err).Send()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|