chore: cleanup
041f62de
1 file(s) · +23 −10
| 5 | 5 | "fmt" |
|
| 6 | 6 | "html/template" |
|
| 7 | 7 | "net/http" |
|
| 8 | + | "regexp" |
|
| 8 | 9 | "strconv" |
|
| 9 | 10 | "strings" |
|
| 10 | 11 | "time" |
|
| 11 | - | "regexp" |
|
| 12 | 12 | ) |
|
| 13 | 13 | ||
| 14 | 14 | type parsedAttributes struct { |
|
| 357 | 357 | return strings.ToUpper(cleaned[:1]) + cleaned[1:] |
|
| 358 | 358 | } |
|
| 359 | 359 | ||
| 360 | + | var weatherClient = &http.Client{Timeout: 10 * time.Second} |
|
| 361 | + | ||
| 362 | + | var qualifierRE = regexp.MustCompile(`(?i)^(slight chance|chance|isolated|scattered|patchy|areas)\s+(of\s+)?`) |
|
| 363 | + | ||
| 360 | 364 | func getWeather(location string) string { |
|
| 361 | 365 | if location == "" { |
|
| 362 | 366 | return "" |
|
| 363 | 367 | } |
|
| 364 | 368 | // Fetch Points data using lat,long |
|
| 365 | 369 | pointURL := fmt.Sprintf("https://api.weather.gov/points/%s", location) |
|
| 366 | - | resp, err := http.Get(pointURL) |
|
| 370 | + | resp, err := weatherClient.Get(pointURL) |
|
| 367 | 371 | if err != nil { |
|
| 368 | 372 | fmt.Printf("Error fetching pointUrl: %s", err.Error()) |
|
| 369 | 373 | return "" |
|
| 370 | 374 | } |
|
| 371 | 375 | defer resp.Body.Close() |
|
| 372 | 376 | var weatherPoint WeatherPointResponse |
|
| 373 | - | json.NewDecoder(resp.Body).Decode(&weatherPoint) |
|
| 377 | + | if err := json.NewDecoder(resp.Body).Decode(&weatherPoint); err != nil { |
|
| 378 | + | fmt.Printf("Error decoding pointUrl: %s", err.Error()) |
|
| 379 | + | return "" |
|
| 380 | + | } |
|
| 374 | 381 | forecastURL := weatherPoint.Properties.ForecastHourly |
|
| 375 | 382 | city := weatherPoint.Properties.RelativeLocation.Properties.City |
|
| 376 | 383 | state := weatherPoint.Properties.RelativeLocation.Properties.State |
|
| 377 | 384 | ||
| 378 | 385 | // Forcast using points data |
|
| 379 | - | forecastResp, err := http.Get(forecastURL) |
|
| 386 | + | forecastResp, err := weatherClient.Get(forecastURL) |
|
| 380 | 387 | if err != nil { |
|
| 381 | 388 | fmt.Printf("Error fetching forecast: %s", err.Error()) |
|
| 382 | 389 | return "" |
|
| 383 | 390 | } |
|
| 384 | - | defer resp.Body.Close() |
|
| 391 | + | defer forecastResp.Body.Close() |
|
| 385 | 392 | var weatherForecast WeatherForecastResponse |
|
| 386 | - | json.NewDecoder(forecastResp.Body).Decode(&weatherForecast) |
|
| 387 | - | temp := strconv.Itoa(weatherForecast.Properties.Periods[0].Temperature) |
|
| 388 | - | conditions := weatherForecast.Properties.Periods[0].ShortForecast |
|
| 389 | - | var qualifierRE = regexp.MustCompile(`(?i)^(slight chance|chance|isolated|scattered|patchy|areas)\s+(of\s+)?`) |
|
| 390 | - | formattedConditions := strings.TrimSpace(qualifierRE.ReplaceAllString(conditions, "")) |
|
| 393 | + | if err := json.NewDecoder(forecastResp.Body).Decode(&weatherForecast); err != nil { |
|
| 394 | + | fmt.Printf("Error decoding forecast: %s", err.Error()) |
|
| 395 | + | return "" |
|
| 396 | + | } |
|
| 397 | + | if len(weatherForecast.Properties.Periods) == 0 { |
|
| 398 | + | fmt.Printf("Error: no forecast periods returned for %q", location) |
|
| 399 | + | return "" |
|
| 400 | + | } |
|
| 401 | + | period := weatherForecast.Properties.Periods[0] |
|
| 402 | + | temp := strconv.Itoa(period.Temperature) |
|
| 403 | + | formattedConditions := strings.TrimSpace(qualifierRE.ReplaceAllString(period.ShortForecast, "")) |
|
| 391 | 404 | weather := fmt.Sprintf("%s,%s,%s,%s", formattedConditions, temp, city, state) |
|
| 392 | 405 | return weather |
|
| 393 | 406 | } |
|