diff --git a/backend/main.py b/backend/main.py index 51df399..14099f3 100644 --- a/backend/main.py +++ b/backend/main.py @@ -8140,6 +8140,7 @@ _CCTV_PROXY_ALLOWED_HOSTS = { "tripcheck.com", # Oregon DOT / TripCheck "www.tripcheck.com", "infocar.dgt.es", # Spain DGT + "etraffic.dgt.es", # Spain DGT (etrafficWEB cameras host, 2026) "informo.madrid.es", # Madrid "webcams2.asfinag.at", # Austria ASFINAG motorway cameras "odo.asfinag.at", # ASFINAG catalog API host @@ -8336,14 +8337,14 @@ def _cctv_proxy_profile_for_url(target_url: str) -> _CCTVProxyProfile: cache_seconds=30, headers={"Accept": "image/avif,image/webp,image/apng,image/*,*/*;q=0.8"}, ) - if host == "infocar.dgt.es": + if host in {"infocar.dgt.es", "etraffic.dgt.es"}: return _CCTVProxyProfile( name="dgt-spain", timeout=(5.0, 8.0), cache_seconds=60, headers={ "Accept": "image/avif,image/webp,image/apng,image/*,*/*;q=0.8", - "Referer": "https://infocar.dgt.es/", + "Referer": "https://etraffic.dgt.es/", }, ) if host == "informo.madrid.es": diff --git a/backend/routers/cctv.py b/backend/routers/cctv.py index 644cc79..bf3d021 100644 --- a/backend/routers/cctv.py +++ b/backend/routers/cctv.py @@ -46,6 +46,7 @@ _CCTV_PROXY_ALLOWED_HOSTS = { "tripcheck.com", "www.tripcheck.com", "infocar.dgt.es", + "etraffic.dgt.es", "informo.madrid.es", "webcams2.asfinag.at", "odo.asfinag.at", @@ -158,10 +159,10 @@ def _cctv_proxy_profile_for_url(target_url: str) -> _CCTVProxyProfile: if host in {"tripcheck.com", "www.tripcheck.com"}: return _CCTVProxyProfile(name="odot-tripcheck", timeout=(_CCTV_PROXY_CONNECT_TIMEOUT_S, 12.0), cache_seconds=30, headers={"Accept": "image/avif,image/webp,image/apng,image/*,*/*;q=0.8"}) - if host == "infocar.dgt.es": + if host in {"infocar.dgt.es", "etraffic.dgt.es"}: return _CCTVProxyProfile(name="dgt-spain", timeout=(_CCTV_PROXY_CONNECT_TIMEOUT_S, 8.0), cache_seconds=60, headers={"Accept": "image/avif,image/webp,image/apng,image/*,*/*;q=0.8", - "Referer": "https://infocar.dgt.es/"}) + "Referer": "https://etraffic.dgt.es/"}) if host == "informo.madrid.es": return _CCTVProxyProfile(name="madrid-city", timeout=(_CCTV_PROXY_CONNECT_TIMEOUT_S, 12.0), cache_seconds=30, headers={"Accept": "image/avif,image/webp,image/apng,image/*,*/*;q=0.8", diff --git a/backend/services/cctv_pipeline.py b/backend/services/cctv_pipeline.py index 3f2d352..f659722 100644 --- a/backend/services/cctv_pipeline.py +++ b/backend/services/cctv_pipeline.py @@ -1031,7 +1031,8 @@ out body; # --------------------------------------------------------------------------- # DGT Spain — National Road Cameras # --------------------------------------------------------------------------- -# Image URL pattern confirmed working: infocar.dgt.es/etraffic/data/camaras/{id}.jpg +# Image URL pattern confirmed working: etraffic.dgt.es/camarasEtraffic/{id}.jpg +# (DGT migrated 2026: old infocar.dgt.es/etraffic/data/camaras path now 302->etrafficWEB) # Source: DGT (Dirección General de Tráfico) — public open data (Ley 37/2007). # Author credit: Alborz Nazari (github.com/AlborzNazari) — PR #91 @@ -1065,10 +1066,10 @@ class DGTNationalIngestor(BaseCCTVIngestor): cameras = [] probe_headers = { "Accept": "image/avif,image/webp,image/apng,image/*,*/*;q=0.8", - "Referer": "https://infocar.dgt.es/", + "Referer": "https://etraffic.dgt.es/", } for cam_id, lat, lon, description in self.KNOWN_CAMERAS: - media_url = f"https://infocar.dgt.es/etraffic/data/camaras/{cam_id}.jpg" + media_url = f"https://etraffic.dgt.es/camarasEtraffic/{cam_id}.jpg" if not _media_url_reachable(media_url, timeout=6, headers=probe_headers): continue cameras.append({ diff --git a/backend/tests/test_sigint_cctv_accuracy.py b/backend/tests/test_sigint_cctv_accuracy.py index 12ad8cc..85e028c 100644 --- a/backend/tests/test_sigint_cctv_accuracy.py +++ b/backend/tests/test_sigint_cctv_accuracy.py @@ -314,7 +314,7 @@ def test_cctv_proxy_profiles_are_source_specific(): tfl = main._cctv_proxy_profile_for_url("https://s3-eu-west-1.amazonaws.com/jamcams.tfl.gov.uk/00001.mp4") austin = main._cctv_proxy_profile_for_url("https://cctv.austinmobility.io/image/316.jpg") georgia = main._cctv_proxy_profile_for_url("https://511ga.org/map/Cctv/22378") - spain = main._cctv_proxy_profile_for_url("https://infocar.dgt.es/etraffic/data/camaras/1050.jpg") + spain = main._cctv_proxy_profile_for_url("https://etraffic.dgt.es/camarasEtraffic/1050.jpg") assert tfl.name == "tfl-jamcam" assert tfl.headers["Accept"].startswith("video/mp4") @@ -324,7 +324,7 @@ def test_cctv_proxy_profiles_are_source_specific(): assert georgia.timeout == (5.0, 12.0) assert georgia.headers["Referer"] == "https://511ga.org/cctv" assert spain.name == "dgt-spain" - assert spain.headers["Referer"] == "https://infocar.dgt.es/" + assert spain.headers["Referer"] == "https://etraffic.dgt.es/" def test_cctv_proxy_preserves_upstream_http_status(monkeypatch):