From 863bdba7d233c0b139d1077916209ecedc0b7809 Mon Sep 17 00:00:00 2001 From: Stream Date: Tue, 21 Apr 2026 19:00:01 +0300 Subject: [PATCH] auto-sync: 2026-04-21 19:00:01 --- tasks/flightradar24/frontend/main.py | 52 +++++++++++++++++++ .../ingest/tracks_fr24/fr24_worker.py | 13 +++-- .../flightradar24/ingest/tracks_fr24/main.py | 2 +- 3 files changed, 62 insertions(+), 5 deletions(-) diff --git a/tasks/flightradar24/frontend/main.py b/tasks/flightradar24/frontend/main.py index 23a3013..e09d746 100644 --- a/tasks/flightradar24/frontend/main.py +++ b/tasks/flightradar24/frontend/main.py @@ -527,6 +527,58 @@ def schedule_data(): return err(str(e)) +# ── actual flight data API ────────────────────────────────────────────────── + +@app.get("/api/flight-actual") +def flight_actual(): + """Query fr24_ext.flight_actual table directly.""" + try: + limit = min(int(request.args.get("limit", 200)), 2000) + offset = max(int(request.args.get("offset", 0)), 0) + date_from = request.args.get("date_from") + date_to = request.args.get("date_to") + category = request.args.get("category") + airport = request.args.get("airport") # ICAO filter + + clauses = [] + params = [] + if date_from: + clauses.append("flight_date >= %s"); params.append(date_from) + if date_to: + clauses.append("flight_date <= %s"); params.append(date_to) + if category: + clauses.append("category = %s"); params.append(category) + if airport: + clauses.append("(origin_icao = %s OR dest_icao = %s)"); params.extend([airport, airport]) + + where = " AND ".join(clauses) if clauses else "1=1" + + rows = query( + f""" + SELECT fr24_id, flight, callsign, operated_as, + origin_icao, dest_icao, + datetime_takeoff, datetime_landed, flight_time, + runway_takeoff, runway_landed, actual_distance, + category, flight_ended, first_seen, last_seen, flight_date + FROM fr24_ext.flight_actual + WHERE {where} + ORDER BY flight_date DESC, datetime_takeoff DESC NULLS LAST + LIMIT %s OFFSET %s + """, + params + [limit, offset], + ) + + total_row = query_one( + f"SELECT COUNT(*) AS cnt FROM fr24_ext.flight_actual WHERE {where}", + params, + ) + + return ok({"total": total_row["cnt"] if total_row else 0, "flights": rows}) + except Exception as e: + log.exception("flight_actual error") + return err(str(e)) + + @app.get("/api/schedule/export") def schedule_export(): try: diff --git a/tasks/flightradar24/ingest/tracks_fr24/fr24_worker.py b/tasks/flightradar24/ingest/tracks_fr24/fr24_worker.py index a7ca09d..f21498b 100644 --- a/tasks/flightradar24/ingest/tracks_fr24/fr24_worker.py +++ b/tasks/flightradar24/ingest/tracks_fr24/fr24_worker.py @@ -244,8 +244,9 @@ def enrich_schedule(conn, target_date: date) -> int: """ with conn.cursor() as cur: # Match by normalized flight number + flight_date - # For departures: match on origin_icao → airport is origin - # For arrivals: match on dest_icao → airport is destination + # IATA → ICAO mapping for Moscow airports + # For departures: schedule airport is origin → fa.origin_icao must be Moscow ICAO + # For arrivals: schedule airport is destination → fa.dest_icao must be Moscow ICAO cur.execute( """ WITH matches AS ( @@ -256,12 +257,16 @@ def enrich_schedule(conn, target_date: date) -> int: fa.datetime_landed AS actual_landed, fa.category AS flight_category, CASE - WHEN fa.datetime_takeoff IS NOT NULL AND s.scheduled_at IS NOT NULL + WHEN s.direction = 'departure' AND fa.datetime_takeoff IS NOT NULL THEN EXTRACT(EPOCH FROM (fa.datetime_takeoff - s.scheduled_at))::int / 60 + WHEN s.direction = 'arrival' AND fa.datetime_landed IS NOT NULL + THEN EXTRACT(EPOCH FROM (fa.datetime_landed - s.scheduled_at))::int / 60 END AS delay_takeoff_min, CASE - WHEN fa.datetime_landed IS NOT NULL AND s.scheduled_at IS NOT NULL + WHEN s.direction = 'arrival' AND fa.datetime_landed IS NOT NULL AND s.scheduled_at IS NOT NULL THEN EXTRACT(EPOCH FROM (fa.datetime_landed - s.scheduled_at))::int / 60 + WHEN s.direction = 'departure' AND fa.datetime_takeoff IS NOT NULL AND s.scheduled_at IS NOT NULL + THEN EXTRACT(EPOCH FROM (fa.datetime_takeoff - s.scheduled_at))::int / 60 END AS delay_landed_min FROM fr24_ext.schedule s JOIN fr24_ext.flight_actual fa diff --git a/tasks/flightradar24/ingest/tracks_fr24/main.py b/tasks/flightradar24/ingest/tracks_fr24/main.py index 6f30eb4..bb3d88f 100644 --- a/tasks/flightradar24/ingest/tracks_fr24/main.py +++ b/tasks/flightradar24/ingest/tracks_fr24/main.py @@ -25,7 +25,7 @@ log = logging.getLogger("tracks_fr24") app = Flask(__name__) -_last_run: dict = {"at": None, "status": "never", "stats": {}} +_last_run: dict = {"at": None, "status": "never", "stats": {}, "fetch_tracks": config.FETCH_TRACKS} _conn = None