phase 0-2 complete

This commit is contained in:
Blake Ridgway
2026-04-25 20:31:55 -05:00
parent c1d8b17147
commit 778c52fc69
8 changed files with 1447 additions and 132 deletions

51
internal/radar/fetch.go Normal file
View File

@@ -0,0 +1,51 @@
package radar
import (
"context"
"fmt"
"io"
"net/http"
"strings"
"time"
)
// nwsRadarBase is the NWS public product distribution server.
// No credentials required; sn.last always holds the most recent scan.
const nwsRadarBase = "https://tgftp.nws.noaa.gov/SL.us008001/DF.of/DC.radar"
// Fetcher downloads NEXRAD Level 3 products from the NWS public server.
type Fetcher struct {
client *http.Client
}
func NewFetcher(_ context.Context) (*Fetcher, error) {
return &Fetcher{client: &http.Client{Timeout: 30 * time.Second}}, nil
}
// FetchLatest downloads the latest Level 3 base reflectivity (0.5°) for site.
func (f *Fetcher) FetchLatest(ctx context.Context, site string) ([]byte, error) {
return f.fetchDS(ctx, site, "p94r0")
}
// FetchVelocity downloads the latest Level 3 base velocity (0.5°) for site.
func (f *Fetcher) FetchVelocity(ctx context.Context, site string) ([]byte, error) {
return f.fetchDS(ctx, site, "p99r0")
}
func (f *Fetcher) fetchDS(ctx context.Context, site, ds string) ([]byte, error) {
url := fmt.Sprintf("%s/DS.%s/SI.%s/sn.last", nwsRadarBase, ds, strings.ToLower(site))
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
if err != nil {
return nil, err
}
resp, err := f.client.Do(req)
if err != nil {
return nil, fmt.Errorf("NWS fetch: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("NWS returned %s for %s", resp.Status, url)
}
return io.ReadAll(resp.Body)
}