auto-sync: 2026-04-21 19:00:01

This commit is contained in:
Stream
2026-04-21 19:00:01 +03:00
parent 1c7fdc4c8b
commit 863bdba7d2
3 changed files with 62 additions and 5 deletions

View File

@@ -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:

View File

@@ -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

View File

@@ -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