From 7eb1b2c43e25ea17159092e6d442e82cbc8a038e Mon Sep 17 00:00:00 2001 From: Stream Date: Tue, 21 Apr 2026 01:30:01 +0300 Subject: [PATCH] auto-sync: 2026-04-21 01:30:01 --- tasks/flightradar24/frontend/main.py | 61 +++++++++++++++++-- .../flightradar24/frontend/static/schedule.js | 18 ++++-- 2 files changed, 71 insertions(+), 8 deletions(-) diff --git a/tasks/flightradar24/frontend/main.py b/tasks/flightradar24/frontend/main.py index c60ad3e..2445ba0 100644 --- a/tasks/flightradar24/frontend/main.py +++ b/tasks/flightradar24/frontend/main.py @@ -14,6 +14,57 @@ import psycopg2 import psycopg2.extras from flask import Flask, jsonify, request, send_from_directory, Response +# ── IATA → город маппинг ────────────────────────────────────────────────────── +IATA_CITY = { + "AAQ": "Анапа", "ABA": "Абакан", "ADB": "Измир", "ADD": "Аддис-Абеба", + "AER": "Сочи", "AKX": "Актобе", "ALA": "Алматы", "AMM": "Амман", + "AMS": "Амстердам", "ARH": "Архангельск", "ARN": "Стокгольм", "ASB": "Ашхабад", + "ASF": "Астрахань", "ATH": "Афины", "AUH": "Абу-Даби", "AYT": "Анталья", + "AZN": "Андижан", "BAX": "Барнаул", "BCN": "Барселона", "BEG": "Белград", + "BER": "Берлин", "BEY": "Бейрут", "BJV": "Бодрум", "BKK": "Бангкок", + "BNE": "Брисбен", "BOG": "Богота", "BOM": "Мумбаи", "BQS": "Благовещенск", + "BRU": "Брюссель", "BTK": "Братск", "BUS": "Батуми", "BXK": "Бухара", + "BZK": "Брянск", "CAI": "Каир", "CCJ": "Кожикоде", "CEK": "Челябинск", + "CGK": "Джакарта", "CGN": "Кёльн", "CMN": "Касабланка", "CMB": "Коломбо", + "CSY": "Чебоксары", "CXI": "Кашгар", "CZM": "Косумель", "DEL": "Дели", + "DME": "Домодедово", "DMJ": "Домодедово", "DOH": "Доха", "DSS": "Дакар", + "DXB": "Дубай", "EGO": "Белгород", "EKB": "Екатеринбург", "EVN": "Ереван", + "FRA": "Франкфурт", "FRU": "Бишкек", "GDZ": "Геленджик", "GDX": "Магадан", + "GIF": "Гифу", "GOI": "Гоа", "GOJ": "Нижний Новгород", "GRV": "Грозный", + "GRZ": "Грац", "GYD": "Баку", "HAD": "Ханчжоу", "HAM": "Гамбург", + "HEL": "Хельсинки", "HMA": "Ханты-Мансийск", "HRB": "Харбин", + "HRG": "Хургада", "HKT": "Пхукет", "HYD": "Хайдарабад", "IKT": "Иркутск", + "IKA": "Тегеран", "IST": "Стамбул", "IXC": "Чандигарх", "JED": "Джидда", + "JFK": "Нью-Йорк", "KGD": "Калининград", "KGV": "Когалым", + "KHV": "Хабаровск", "KJA": "Красноярск", "KLO": "Калининград", + "KRR": "Краснодар", "KUF": "Самара", "KUL": "Куала-Лумпур", + "KZN": "Казань", "LAX": "Лос-Анджелес", "LED": "Санкт-Петербург", + "LHR": "Лондон", "LPK": "Липецк", "MIA": "Майами", "MLE": "Мале", + "MMK": "Мурманск", "MRV": "Минеральные Воды", "MSQ": "Минск", + "MUC": "Мюнхен", "NBO": "Найроби", "NJC": "Нижневартовск", + "NNM": "Нарьян-Мар", "NQZ": "Астана", "NSK": "Норильск", "NVR": "Набережные Челны", + "NVT": "Новороссийск", "OVB": "Новосибирск", "OMS": "Омск", + "OSL": "Осло", "OSS": "Ош", "OZH": "Ургенч", "PEE": "Пермь", + "PEK": "Пекин", "PKC": "Петропавловск-Камчатский", "PRG": "Прага", + "PSA": "Пиза", "PUY": "Пула", "PUS": "Пусан", "REN": "Оренбург", + "RGK": "Горно-Алтайск", "RIX": "Рига", "ROV": "Ростов-на-Дону", + "RTW": "Саратов", "SAW": "Стамбул (Сабиха)", "SGB": "Балаково", + "SGC": "Сургут", "SIP": "Симферополь", "SKG": "Салоники", "SLY": "Салехард", + "SIN": "Сингапур", "SJJ": "Сараево", "SKZ": "Сыктывкар", + "SVO": "Шереметьево", "SVX": "Екатеринбург", "SWT": "Стрежевой", + "SYD": "Сидней", "TAS": "Ташкент", "TBS": "Тбилиси", "TJM": "Тюмень", + "TKM": "Туркменбаши", "TLL": "Таллин", "TLS": "Тулуза", "TSE": "Астана", + "TSQ": "Тамбов", "TXL": "Берлин", "ULV": "Ульяновск", "UFA": "Уфа", + "UJD": "Усть-Каменогорск", "VOG": "Волгоград", "VOZ": "Воронеж", + "VNO": "Вильнюс", "VVO": "Владивосток", "VKO": "Внуково", "WAW": "Варшава", + "WLG": "Веллингтон", "XRY": "Херес", "YKS": "Якутск", "YYZ": "Торонто", + "ZIA": "Жуковский", "ZRH": "Цюрих", "ZYR": "Зырянка", +} + +def _city(iata: str) -> str: + """IATA code → human-readable city name.""" + return IATA_CITY.get(iata.strip() if iata else "", iata or "") + logging.basicConfig( level=logging.INFO, format="%(asctime)s [api] %(levelname)s %(message)s", @@ -439,8 +490,10 @@ def schedule_data(): "airline": r["airline_name"], "airport": r["airport_iata"], "direction": r["direction"], - "origin": r["origin_iata"], - "destination": r["destination_iata"], + "origin": _city(r["origin_iata"]) or r["origin_iata"] or "", + "destination": _city(r["destination_iata"]) or r["destination_iata"] or "", + "origin_iata": r["origin_iata"] or "", + "destination_iata": r["destination_iata"] or "", "scheduled_at": sched.isoformat() if sched else None, "actual_at": actual.isoformat() if actual else None, "delay_min": delay_min, @@ -494,8 +547,8 @@ def schedule_export(): r["airline_name"] or "", r["airport_iata"], r["direction"], - r["origin_iata"] or "", - r["destination_iata"] or "", + _city(r["origin_iata"]) or r["origin_iata"] or "", + _city(r["destination_iata"]) or r["destination_iata"] or "", sched.isoformat() if sched else "", actual.isoformat() if actual else "", delay, diff --git a/tasks/flightradar24/frontend/static/schedule.js b/tasks/flightradar24/frontend/static/schedule.js index 5c4e58c..4011a3f 100644 --- a/tasks/flightradar24/frontend/static/schedule.js +++ b/tasks/flightradar24/frontend/static/schedule.js @@ -184,10 +184,20 @@ function exportCsv() { function routeStr(f) { const o = f.origin || ""; const d = f.destination || ""; - if (!o && !d) return "—"; - if (!o) return `→ ${d}`; - if (!d) return `${o} →`; - return `${o} → ${d}`; + const oi = f.origin_iata || ""; + const di = f.destination_iata || ""; + function fmt(city, iata) { + if (!city && !iata) return ""; + if (!city) return iata; + if (city === iata) return city; + return city; + } + const from = fmt(o, oi); + const to = fmt(d, di); + if (!from && !to) return "—"; + if (!from) return `→ ${to}`; + if (!to) return `${from} →`; + return `${from} → ${to}`; } function statusBadge(status) {