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 }