HexaWetter v1.2.0: Security, Admin, Radar, UI
This commit is contained in:
59
api/app/services/radar_sync.py
Normal file
59
api/app/services/radar_sync.py
Normal file
@@ -0,0 +1,59 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from datetime import datetime, timedelta, timezone
|
||||
|
||||
from app.config import RADAR_PRODUCT, RADAR_RETENTION_HOURS, RAW_RADAR_DIR
|
||||
from app.database import upsert_radar_meta
|
||||
from app.http_client import get_client
|
||||
from app.services.dwd_radar import RADAR_FILE_RE, fetch_radar_index
|
||||
|
||||
_FILENAME_RE = re.compile(r"^[a-z0-9_-]+$", re.IGNORECASE)
|
||||
|
||||
|
||||
def utc_now() -> datetime:
|
||||
return datetime.now(timezone.utc)
|
||||
|
||||
|
||||
def cleanup_old_radar_files() -> None:
|
||||
cutoff = utc_now() - timedelta(hours=RADAR_RETENTION_HOURS)
|
||||
if not RAW_RADAR_DIR.exists():
|
||||
return
|
||||
for path in RAW_RADAR_DIR.rglob("*"):
|
||||
if not path.is_file() or not RADAR_FILE_RE.fullmatch(path.name):
|
||||
continue
|
||||
modified = datetime.fromtimestamp(path.stat().st_mtime, timezone.utc)
|
||||
if modified < cutoff:
|
||||
path.unlink(missing_ok=True)
|
||||
|
||||
|
||||
async def sync_radar_files(product: str = RADAR_PRODUCT, limit: int = 6) -> dict:
|
||||
if not _FILENAME_RE.fullmatch(product):
|
||||
raise ValueError("Invalid product")
|
||||
|
||||
latest = await fetch_radar_index(product=product, limit=limit)
|
||||
target_dir = RAW_RADAR_DIR / "composite" / product
|
||||
target_dir.mkdir(parents=True, exist_ok=True)
|
||||
downloaded: list[str] = []
|
||||
skipped: list[str] = []
|
||||
|
||||
client = get_client()
|
||||
for item in latest["files"]:
|
||||
out = target_dir / item["name"]
|
||||
if out.exists() and out.stat().st_size > 0:
|
||||
skipped.append(item["name"])
|
||||
continue
|
||||
response = await client.get(item["url"], timeout=90.0)
|
||||
response.raise_for_status()
|
||||
out.write_bytes(response.content)
|
||||
downloaded.append(item["name"])
|
||||
modified = datetime.fromtimestamp(out.stat().st_mtime, timezone.utc)
|
||||
await upsert_radar_meta(product, item["name"], out.stat().st_size, modified, "pending")
|
||||
|
||||
cleanup_old_radar_files()
|
||||
return {
|
||||
"product": product,
|
||||
"target_dir": str(target_dir),
|
||||
"downloaded": downloaded,
|
||||
"skipped": skipped,
|
||||
}
|
||||
Reference in New Issue
Block a user