weather/main.go

153 lines
2.8 KiB
Go

package main
import (
"context"
"fmt"
"os"
"time"
)
const (
defaultForecastTTL = 10 * time.Minute
)
func main() {
if err := run(); err != nil {
fmt.Fprintln(os.Stderr, err.Error())
os.Exit(1)
}
}
func run() error {
opts, err := parseArgs(os.Args[1:])
if err != nil {
return err
}
ua, err := buildUserAgent()
if err != nil {
return err
}
cacheDir, err := cacheRoot()
if err != nil {
return err
}
cache := NewCache(cacheDir)
ctx := context.Background()
if opts.iconTest {
printIconTest()
return nil
}
if opts.wayland && opts.searchSet {
if err := requireRofi(); err != nil {
return err
}
}
if opts.radarMode {
if err := requireMPV(); err != nil {
return err
}
}
if opts.clearCache {
if err := cache.Clear(); err != nil {
return err
}
return nil
}
var loc Location
if opts.wayland && opts.searchSet {
if opts.searchValue == "" {
var err error
loc, err = interactiveSearch(ctx, cache, ua)
if err != nil {
return err
}
} else {
var err error
loc, err = interactiveSearch(ctx, cache, ua)
if err != nil {
return err
}
}
} else if opts.searchSet {
if opts.searchValue == "" {
return fmt.Errorf("--search requires a value unless --wayland is set")
}
results, err := SearchLocations(ctx, opts.searchValue, ua)
if err != nil {
return err
}
loc, err = SelectLocation(results)
if err != nil {
return err
}
if err := cache.SaveLocation(opts.searchValue, loc); err != nil {
return err
}
} else {
var ok bool
loc, ok, err = cache.LoadLocation()
if err != nil {
return err
}
if !ok {
return fmt.Errorf("no cached location found; use -s to set a location")
}
}
if opts.radarMode {
return runRadar(ctx, cache, loc, opts.searchValue, ua)
}
if opts.discussion {
text, err := runDiscussion(ctx, cache, loc, opts.searchValue, ua)
if err != nil {
return err
}
if opts.wayland {
return runDiscussionWayland(ctx, formatAFDMarkdown(text))
}
fmt.Println(text)
return nil
}
client := NewNWSClient(ua)
var period ForecastPeriod
if opts.refresh {
var err error
period, err = client.FetchForecast(ctx, loc, opts.temperatureU)
if err != nil {
return err
}
if err := cache.SaveForecast(loc, opts.temperatureU, period); err != nil {
return err
}
} else {
var err error
var fromCache bool
period, fromCache, err = cache.LoadForecast(loc, opts.temperatureU, defaultForecastTTL)
if err != nil {
return err
}
if !fromCache {
period, err = client.FetchForecast(ctx, loc, opts.temperatureU)
if err != nil {
return err
}
if err := cache.SaveForecast(loc, opts.temperatureU, period); err != nil {
return err
}
}
}
line := FormatOutput(loc, period, opts.includeDesc, opts.prettyOutput)
fmt.Println(line)
return nil
}