diff options
| author | Danilo M. <danix@danix.xyz> | 2026-07-17 10:26:48 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-07-17 10:26:48 +0200 |
| commit | fc4b8ae587fa5a26648c2bb94e61141d2954f9aa (patch) | |
| tree | 775bd28ab376dcb819df31a164f268093c4bb1e3 | |
| parent | 1b949b536dee4039625218ed7de0634a94e7fa86 (diff) | |
| download | hyprsunset-qt-fc4b8ae587fa5a26648c2bb94e61141d2954f9aa.tar.gz hyprsunset-qt-fc4b8ae587fa5a26648c2bb94e61141d2954f9aa.zip | |
feat: geolocate and sunrise-sunset fetch
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
| -rw-r--r-- | hyprsunset_qt/sun.py | 22 | ||||
| -rw-r--r-- | tests/test_sun.py | 24 |
2 files changed, 45 insertions, 1 deletions
diff --git a/hyprsunset_qt/sun.py b/hyprsunset_qt/sun.py index bc611f9..254fa38 100644 --- a/hyprsunset_qt/sun.py +++ b/hyprsunset_qt/sun.py @@ -3,6 +3,7 @@ from __future__ import annotations import json +import urllib.request from datetime import datetime, tzinfo from pathlib import Path from typing import Optional @@ -29,3 +30,24 @@ def write_cache(payload: dict, path: Path) -> None: path = Path(path) path.parent.mkdir(parents=True, exist_ok=True) path.write_text(json.dumps(payload, indent=2)) + + +GEO_URL = "http://ip-api.com/json" +SUN_URL = "https://api.sunrise-sunset.org/json?lat={lat}&lng={lon}&formatted=0" + + +def _http_get(url: str, timeout: float = 10.0) -> str: + with urllib.request.urlopen(url, timeout=timeout) as resp: + return resp.read().decode() + + +def geolocate() -> tuple[str, str]: + """Return (lat, lon) as strings from IP geolocation.""" + data = json.loads(_http_get(GEO_URL)) + return str(data["lat"]), str(data["lon"]) + + +def fetch_sun(lat: str, lon: str) -> dict: + """Fetch sunrise/sunset JSON for coords. Caller handles caching.""" + url = SUN_URL.format(lat=lat, lon=lon) + return json.loads(_http_get(url)) diff --git a/tests/test_sun.py b/tests/test_sun.py index 2a64632..4e15cb2 100644 --- a/tests/test_sun.py +++ b/tests/test_sun.py @@ -1,7 +1,8 @@ import json from datetime import timezone from zoneinfo import ZoneInfo -from hyprsunset_qt.sun import to_local_hm, read_cache, write_cache +from unittest.mock import patch +from hyprsunset_qt.sun import to_local_hm, read_cache, write_cache, geolocate, fetch_sun def test_utc_to_local_hm(): @@ -19,3 +20,24 @@ def test_cache_roundtrip(tmp_path): def test_read_cache_missing(tmp_path): assert read_cache(tmp_path / "nope.json") is None + + +def test_geolocate_parses_latlon(): + body = json.dumps({"status": "success", "lat": 45.07, "lon": 7.68}) + with patch("hyprsunset_qt.sun._http_get", return_value=body): + assert geolocate() == ("45.07", "7.68") + + +def test_fetch_sun_returns_results_dict(): + body = json.dumps({ + "status": "OK", + "results": { + "sunrise": "2026-07-17T03:12:00+00:00", + "sunset": "2026-07-17T17:40:00+00:00", + }, + }) + with patch("hyprsunset_qt.sun._http_get", return_value=body) as g: + out = fetch_sun("45.07", "7.68") + assert out["results"]["sunset"] == "2026-07-17T17:40:00+00:00" + url = g.call_args[0][0] + assert "lat=45.07" in url and "lng=7.68" in url and "formatted=0" in url |
