The DuckDuckGo weather extractor (sites/duckduckgo/weather.go, added in #25) returns a WeatherData struct that is missing several fields that mort's weather2 module currently extracts via inline browser scraping:
Missing Fields
Hourly forecast - mort extracts hourly temperature/condition data for a ~10-hour window. The extractor's WeatherData only has Forecast []DayForecast (daily), no hourly data.
Precipitation percentage - mort extracts the chance of precipitation (e.g., "30% chance of rain") for each day and hour. DayForecast currently only has Day, HighTemp, LowTemp, Condition - no precipitation field.
Weather icons / icon hints - mort extracts aria-label, title, and alt attributes from weather icon elements to determine the icon type (sunny, cloudy, rain, etc.). The extractor only provides a Condition string, which works but the icon attributes are more reliable since they come directly from DuckDuckGo's categorization.
Proposed Changes
typeWeatherDatastruct{LocationstringCurrentTempfloat64ConditionstringHighTempfloat64LowTempfloat64HumiditystringWindstringForecast[]DayForecastHourly[]HourlyForecast// NEW}typeDayForecaststruct{DaystringHighTempfloat64LowTempfloat64ConditionstringPrecipitationint// NEW: percentage 0-100, -1 if unavailable}typeHourlyForecaststruct{// NEWTimestringTempfloat64ConditionstringPrecipitationint// percentage 0-100, -1 if unavailable}
Context
Mort's pkg/logic/weather2/weather2.go has ~500 lines of inline DuckDuckGo scraping + regex parsing to extract this data. Once the extractor is complete, mort can replace all of that with a single duckduckgo.GetWeather() call. Until then, the inline scraping must remain.
## Description
The DuckDuckGo weather extractor (`sites/duckduckgo/weather.go`, added in #25) returns a `WeatherData` struct that is missing several fields that mort's `weather2` module currently extracts via inline browser scraping:
### Missing Fields
1. **Hourly forecast** - mort extracts hourly temperature/condition data for a ~10-hour window. The extractor's `WeatherData` only has `Forecast []DayForecast` (daily), no hourly data.
2. **Precipitation percentage** - mort extracts the chance of precipitation (e.g., "30% chance of rain") for each day and hour. `DayForecast` currently only has `Day`, `HighTemp`, `LowTemp`, `Condition` - no precipitation field.
3. **Weather icons / icon hints** - mort extracts `aria-label`, `title`, and `alt` attributes from weather icon elements to determine the icon type (sunny, cloudy, rain, etc.). The extractor only provides a `Condition` string, which works but the icon attributes are more reliable since they come directly from DuckDuckGo's categorization.
### Proposed Changes
```go
type WeatherData struct {
Location string
CurrentTemp float64
Condition string
HighTemp float64
LowTemp float64
Humidity string
Wind string
Forecast []DayForecast
Hourly []HourlyForecast // NEW
}
type DayForecast struct {
Day string
HighTemp float64
LowTemp float64
Condition string
Precipitation int // NEW: percentage 0-100, -1 if unavailable
}
type HourlyForecast struct { // NEW
Time string
Temp float64
Condition string
Precipitation int // percentage 0-100, -1 if unavailable
}
```
### Context
Mort's `pkg/logic/weather2/weather2.go` has ~500 lines of inline DuckDuckGo scraping + regex parsing to extract this data. Once the extractor is complete, mort can replace all of that with a single `duckduckgo.GetWeather()` call. Until then, the inline scraping must remain.
**Related:** go-extractor #25, mort #573
Add HourlyForecast struct and Hourly field to WeatherData
Add Precipitation field to DayForecast
Add IconHint field to DayForecast and HourlyForecast for icon attribute extraction
Update extractWeather() to scrape hourly data, precipitation percentages, and icon hints from the weather widget
Update existing tests and add new test cases for the new fields
Update the CLI tool to display the new data
Starting work on this. Plan of approach:
1. Add `HourlyForecast` struct and `Hourly` field to `WeatherData`
2. Add `Precipitation` field to `DayForecast`
3. Add `IconHint` field to `DayForecast` and `HourlyForecast` for icon attribute extraction
4. Update `extractWeather()` to scrape hourly data, precipitation percentages, and icon hints from the weather widget
5. Update existing tests and add new test cases for the new fields
6. Update the CLI tool to display the new data
HourlyForecast struct with Time, Temp, Condition, Precipitation, IconHint
Precipitation int field on DayForecast (-1 if unavailable, matching mort's convention)
IconHint string field on both DayForecast and HourlyForecast (reads aria-label > title > alt from icon elements)
extractIconHint() helper with attribute priority fallback
5 test cases covering all new fields, edge cases (no precipitation, empty doc), and icon hint priority
I cross-referenced mort's weather2 structs — the field types and -1 sentinel convention align. Mort uses Icon string on DayForecast; this PR uses IconHint since the raw value comes from DOM attributes (e.g., "PartlyCloudy") rather than a normalized icon name.
Work finished. PR #52 adds:
- `HourlyForecast` struct with `Time`, `Temp`, `Condition`, `Precipitation`, `IconHint`
- `Precipitation int` field on `DayForecast` (-1 if unavailable, matching mort's convention)
- `IconHint string` field on both `DayForecast` and `HourlyForecast` (reads aria-label > title > alt from icon elements)
- `extractIconHint()` helper with attribute priority fallback
- 5 test cases covering all new fields, edge cases (no precipitation, empty doc), and icon hint priority
I cross-referenced mort's `weather2` structs — the field types and -1 sentinel convention align. Mort uses `Icon string` on `DayForecast`; this PR uses `IconHint` since the raw value comes from DOM attributes (e.g., "PartlyCloudy") rather than a normalized icon name.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Description
The DuckDuckGo weather extractor (
sites/duckduckgo/weather.go, added in #25) returns aWeatherDatastruct that is missing several fields that mort'sweather2module currently extracts via inline browser scraping:Missing Fields
Hourly forecast - mort extracts hourly temperature/condition data for a ~10-hour window. The extractor's
WeatherDataonly hasForecast []DayForecast(daily), no hourly data.Precipitation percentage - mort extracts the chance of precipitation (e.g., "30% chance of rain") for each day and hour.
DayForecastcurrently only hasDay,HighTemp,LowTemp,Condition- no precipitation field.Weather icons / icon hints - mort extracts
aria-label,title, andaltattributes from weather icon elements to determine the icon type (sunny, cloudy, rain, etc.). The extractor only provides aConditionstring, which works but the icon attributes are more reliable since they come directly from DuckDuckGo's categorization.Proposed Changes
Context
Mort's
pkg/logic/weather2/weather2.gohas ~500 lines of inline DuckDuckGo scraping + regex parsing to extract this data. Once the extractor is complete, mort can replace all of that with a singleduckduckgo.GetWeather()call. Until then, the inline scraping must remain.Related: go-extractor #25, mort #573
Starting work on this. Plan of approach:
HourlyForecaststruct andHourlyfield toWeatherDataPrecipitationfield toDayForecastIconHintfield toDayForecastandHourlyForecastfor icon attribute extractionextractWeather()to scrape hourly data, precipitation percentages, and icon hints from the weather widgetWork finished. PR #52 adds:
HourlyForecaststruct withTime,Temp,Condition,Precipitation,IconHintPrecipitation intfield onDayForecast(-1 if unavailable, matching mort's convention)IconHint stringfield on bothDayForecastandHourlyForecast(reads aria-label > title > alt from icon elements)extractIconHint()helper with attribute priority fallbackI cross-referenced mort's
weather2structs — the field types and -1 sentinel convention align. Mort usesIcon stringonDayForecast; this PR usesIconHintsince the raw value comes from DOM attributes (e.g., "PartlyCloudy") rather than a normalized icon name.