Resurrect the OS X El Capitan Dashboard Weather & Stocks widgets
Local proxy server that intercepts legacy Yahoo API calls and serves live data from modern free APIs.
flowchart TB
subgraph "El Capitan Dashboard"
W["Weather Widget"]
S["Stocks Widget"]
end
subgraph "127.0.0.1:80"
P["WidgetLegacy Proxy (Go ~8 MB)"]
end
subgraph "Modern APIs"
OM["Open-Meteo Weather"]
YF["Yahoo Finance v8"]
end
W -->|weather.yahooapis.com| P
S -->|download.finance.yahoo.com| P
P -->|"HTTPS"| OM
P -->|"HTTPS"| YF
style W fill:#1e3a5f,color:#fff
style S fill:#1e3a5f,color:#fff
style P fill:#2d5a27,color:#fff
style OM fill:#ff6b35,color:#fff
style YF fill:#6001d2,color:#fff
flowchart TB
subgraph "Setup Flow"
A["sudo ./setup.sh"] --> B["/etc/hosts: 127.0.0.1 -> yahoo domains"]
B --> C["LaunchDaemon com.legacywidget.proxy"]
C --> D["Proxy listens on port 80"]
D --> E["DNS cache flushed"]
end
Two Dashboard widgets ship broken on El Capitan because Apple hardcoded dead Yahoo API endpoints into parser.js. Instead of patching widget bundles (which breaks code signatures), this project:
- Redirects DNS for the legacy Yahoo domains to
127.0.0.1via/etc/hosts - Intercepts the HTTP requests with a local Go proxy
- Fetches live data from free modern APIs (Open-Meteo, Yahoo Finance v8)
- Transforms the responses back into the exact XML/CSV schemas the widgets expect
All transparently — no widget files are modified.
| Feature | Details |
|---|---|
| Weather | Open-Meteo (free, no API key, 10k req/day) → Yahoo Weather RSS |
| Stocks | Yahoo Finance v8 chart API → CSV (supports any f= format) |
| Day/Night | WMO codes mapped to correct Yahoo day/night icons |
| 2–5 day forecast | Fully populated <yweather:forecast> elements |
| Backward mapping | 75+ cities built-in WOEID→lat/lon, extendable via mapping.json |
| Zero config | One-command install: sudo ./setup.sh |
| Auto-start | LaunchDaemon com.legacywidget.proxy on boot |
| pf(4) support | Optional packet-filter redirect for non-root ports |
| In-memory cache | Configurable TTL, periodic GC, zero external deps |
| Tiny footprint | ~8 MB compiled Go binary, ~0% CPU idle |
# 1. Build (or download a prebuilt binary)
make build
# 2. Run the installer (requires root for port 80 and /etc/hosts)
sudo ./setup.shThat's it. The proxy starts on port 80, /etc/hosts is updated, and the DNS cache is flushed. Restart Dashboard (killall Dock) and the widgets should show live data.
sudo ./setup.sh --port 8080 --pf # use port 8080 with pf redirect from 80
sudo ./setup.sh --uninstall # remove everything# Native (current arch)
make build
# Intel Mac (El Capitan host)
make build-amd64
# Apple Silicon
make build-arm64
# All targets + dist archive
make distBuild requirements: Go 1.21+ (last version supporting macOS 10.11 as deployment target).
# Start the proxy
./proxy/proxy --port 8080 &
# Weather
curl -s "http://127.0.0.1:8080/forecastrss?w=2502265" \
-H "Host: weather.yahooapis.com" | head -30
# Stocks
curl -s "http://127.0.0.1:8080/d/quotes.csv?s=AAPL,MSFT,GOOG" \
-H "Host: download.finance.yahoo.com"Widget (parser.js)
↓ GET /forecastrss?w=2502265&u=f
↓ Host: weather.yahooapis.com
↓ (DNS → /etc/hosts → 127.0.0.1)
↓
WidgetLegacy Proxy
↓ WOEID 2502265 → lat 37.77, lon -122.42 (San Francisco)
↓ GET api.open-meteo.com/v1/forecast?latitude=37.77&longitude=-122.42
↓ ¤t=temperature_2m,relativehumidity_2m,weathercode,windspeed_10m,winddirection_10m,surface_pressure
↓ &daily=temperature_2m_max,temperature_2m_min,weathercode,sunrise,sunset
↓ &temperature_unit=fahrenheit&wind_speed_unit=mph&timezone=auto
↓
Open-Meteo JSON response
↓
Transform: WMO weather codes → Yahoo codes (32=Sunny, 26=Cloudy, 4=T-storms…)
↓ day/night detection via sunrise/sunset
↓ build RSS with yweather:namespace elements
↓
Widget receives Yahoo Weather RSS XML → renders normally
WMO→Yahoo Code Mapping (key entries):
| WMO | Meaning | Yahoo Code | Day Text |
|---|---|---|---|
| 0 | Clear | 32 | Sunny |
| 2 | Partly cloudy | 30 | Partly Cloudy |
| 3 | Overcast | 26 | Cloudy |
| 45 | Fog | 20 | Foggy |
| 61 | Rain slight | 11 | Showers |
| 71 | Snow slight | 14 | Light Snow |
| 95 | T-storm | 4 | Thunderstorms |
Widget (localized.js or Stocks.js)
↓ GET /d/quotes.csv?s=AAPL,MSFT&f=sl1d1t1c1ohgv&e=.csv
↓ Host: download.finance.yahoo.com
↓ (DNS → /etc/hosts → 127.0.0.1)
↓
WidgetLegacy Proxy
↓ Parse format string: s l1 d1 t1 c1 o h g v
↓ GET query1.finance.yahoo.com/v8/finance/chart/AAPL?interval=1d&range=5d
↓ GET query1.finance.yahoo.com/v8/finance/chart/MSFT?interval=1d&range=5d
↓ (concurrent goroutines)
↓
Yahoo Finance v8 JSON response
↓ Extract: meta.regularMarketPrice, indicators.quote[0].close[]
↓ Fallback chain: meta field → indicators array → zero
↓ Format: "AAPL",317.31,"7/14/2026","4:00pm",+1.99,317.02,323.45,315.78,41376714
↓
Widget receives CSV → renders normally
The proxy ships with 75+ built-in WOEID→lat/lon entries covering all US state capitals, major cities, and world capitals. Add your own:
{
"woeid_map": {
"1234567": { "city": "My City", "region": "ST", "country": "US", "lat": 40.71, "lon": -74.01 }
}
}Find your WOEID at woeid.rosselliot.co.nz or extract it from the widget's preferences (~/Library/Preferences/com.apple.dashboard.weather.plist).
sudo ./setup.sh --uninstallThis stops the daemon, removes the binary/plist, and clears pf rules. Your /etc/hosts backup is preserved at /etc/hosts.widgetlegacy.bak.
WidgetLegacy/
├── proxy/
│ └── main.go # Go proxy (1000 lines, stdlib only)
├── setup.sh # Installer script
├── com.legacywidget.proxy.plist # LaunchDaemon template
├── mapping.json # WOEID→lat/lon database
├── Makefile # Build targets
├── .gitignore
├── LICENSE
└── README.md
MIT — do whatever you want.