fr24 web — tizim hujjati
Jonli reyslar xaritasi + JSON API. Bitta Python servisi
(webapp.py), faqat fr24 paketi va bir nechta yordamchi
kutubxonaga bog‘liq. Barchasi bitta portда (8070): xarita, API,
bu hujjat, /api-docs/, /test/.
0. Ishga tushirish
Lokal (Python 3.12+)
cd standalone python -m venv .venv ./.venv/Scripts/python.exe -m pip install -r requirements.txt $env:FR24_WEB_PORT = "8070" # ixtiyoriy — boshqa vektor karta uslubi (default: OpenFreeMap Positron, kalitsiz): # $env:FR24_BASEMAP_STYLE = "https://tiles.openfreemap.org/styles/liberty" # ixtiyoriy — PostgreSQL (reyslar jurnali + playback + baza bo‘yicha ko‘rish): # $env:FR24_DATABASE_URL = "postgresql://user:pass@host:5432/db" ./.venv/Scripts/python.exe webapp.py
Linux / macOS: python3 -m venv .venv && . .venv/bin/activate
&& pip install -r requirements.txt && FR24_WEB_PORT=8070 python
webapp.py. Ishga tushganда joriy katalog standalone/
bo‘lsin (./fr24/, ./flags/, airports.json
shu yerдан o‘qilади).
Docker
docker build -t fr24-web . docker run --rm -p 8070:8070 fr24-web # web + PostgreSQL birga: cp .env.example .env # va tahrirlang docker compose up -d --build
Tekshirish
curl http://localhost:8070/healthz # {"status":"ok"}
curl http://localhost:8070/api/selftest # 20 ichki tekshiruv (FR24’siz)
curl "http://localhost:8070/api/flights?bbox=41,43,68,71"
Poller birinchi to‘liq dunyo aylanишини ~30–50 s dа tugатади; shundан
so‘ng /api/selftest 200 qaytаради. Xizmatни to‘xtатиш:
Ctrl‑C yoki SIGTERM.
1. Umumiy
Fon jarayoni (poller) butun dunyoni doimiy yig‘ib turadi va
xotirada bitta “surat” saqlaydi. Brauzer so‘rovlari
(/api/flights) faqat shu suratdan o‘qiydi — hech qachon
Flightradar24’ga tegmaydi.
| Yo‘l | Vazifasi |
|---|---|
/ | Jonli xarita (HTML) |
/api/flights?bbox=&limit= | Hudud ichidagi reyslar |
/api/airports?bbox= | Hudud ichidagi aeroportlar |
/api/search?q=&class=&field= | Reys qidiruvi + tur bo‘yicha sanoq (7-bo‘lim) |
/api/meta | Poller holati + tur bo‘yicha sanoq |
/api/selftest | Avtotest natijasi |
/flags/<cc>.svg | Davlat bayrog‘i (lokal, ~260 ta) |
/aircraft_photos/<tip> | Samolyot tipi surati (lokal, Wikimedia) |
/log/ | Reyslar jurnali jadvali (PostgreSQL, 8-bo‘lim) |
/api/log?q=&class=&field= | Jurnal qatorlarini o‘qish (JSON) |
/api/track?id=|reg= | Bitta reys legi / bort raqamining 24 soatlik trayektoriyasi (13-bo‘lim) |
/api/fleet/classes, /api/fleet/aircraft?class= | Bazadagi klasslar → o‘sha klassdagi bortlar (13-bo‘lim) |
/api-docs/, /openapi.json | Interaktiv Swagger UI + OpenAPI 3.1 spetsifikatsiyasi |
/aircraft_types.json | ICAO tип belgisi → nom / harbiy? |
/aircraft_photos.json | Tip → surat muallifi / litsenziyasi |
/countries.json | ISO kod → davlat nomi |
/borders.geojson | Davlat chegaralari (Natural Earth) |
/healthz | Sog‘lomlik (FR24’ga so‘rovsiz) |
2. Arxitektura (poller)
ishga tushganda:
poller thread -- o‘z asyncio loop’i, bitta doimiy HTTP/2 ulanish (FR24)
| har 18 s:
| dunyoni vertikal kesimlarga bo‘ladi (fr24 LNGS_WORLD_PER_HALF_HR,
| yarim soatda o‘zgaradi) × 3 ta kenglik zonasi
| = ~36 ta ketma-ket so‘rov, interval bo‘ylab tarqatilgan
| har javob xotiradagi { flightid: reys } lug‘atiga birlashtiriladi
| 75 s ko‘rinmagan reys o‘chiriladi
v 2° to‘rli indeks bilan “surat” atomik almashtiriladi
brauzer:
GET /api/flights?bbox -- suratdan to‘rli indeks orqali filtrlaydi (~1 ms)
v
interpolyatsiya (track + tezlik) bilan silliq harakat + qisqa izlar
3. Yuk va bloklanish
FR24’ga boradigan so‘rovlar soni foydalanuvchilar soniga bog‘liq emas — faqat poller so‘raydi: sikl uchun ~36 ta so‘rov, 18 soniyaga tarqatilgan (≈ 2.0 so‘rov/soniya), bitta ulanish, jitter bilan. 1 kishi ham, 10 000 kishi ham — bir xil.
- Har kesim
limit=1500(anonim chegara). Kenglik zonalari tufayli gavjum yo‘laklar ham to‘lib ketmaydi. - Xato bo‘lса o‘sha kesim tashlanadi, oxirgi yaxshi surat beriladi; poller qayta ulanadi (eksponensial backoff).
- Brauzer API’si IP bo‘yicha cheklangan (token bucket,
240so‘rov/daqiqa) — kesh chetlab o‘tishning foydasi yo‘q. - HTTP server har ulanишга bitta thread ajratади. Yuzлаб bir vaqtдаги
foydаланувчидан oshса — oldига nginx / Caddy qo‘йинг yoki
webapp.pyни bir necha nusxада ishлатинг (hammаси bitta suratни o‘qийди).
4. Sozlamalar (env)
| O‘zgaruvchi | Default | Ma’no |
|---|---|---|
FR24_WEB_HOST | 127.0.0.1 | Bog‘lanish manzili |
FR24_WEB_PORT | 8070 | Port |
FR24_BASEMAP_STYLE | OpenFreeMap Positron | MapLibre GL uslub URL yoki lokal /static/…/style.json (oflayn .pmtiles uchun) |
FR24_BASEMAP_CSP | — | O‘z tayl serveringiz uchun CSP’ga qo‘shimcha host |
FR24_POLL_INTERVAL | 18 | Bir to‘liq dunyo siklи, soniya |
FR24_POLL_MAXAGE | 7200 | FR24 “maxage” — eski reyslar chiqmaydi |
FR24_FLIGHT_TTL | 75 | Ko‘rinmagan reysni o‘chirish, soniya |
FR24_LAT_BANDS | -85,20,48,85 | Kenglik zonasi chegaralari |
FR24_MAX_FLIGHTS | 2000 | Bitta API javobidagi maks. reys |
FR24_RATE_LIMIT | 240 | /api/* so‘rov/daqiqa (IP) |
FR24_SLICES | dynamic | dynamic (yarim soatlik) yoki static |
FR24_SHOW_GROUND_VEHICLES | 0 | Yer transporti (tortuvchi, «follow-me», muzdan tozalagich — GRND) reys sifatida sanalsinmi. Default: yo‘q |
FR24_SATELLITE_URL | Esri World Imagery | Sun’iy yo‘ldosh rejimi uchun {z}/{y}/{x} raster manba; hosti CSP’ga avtomatik qo‘shiladi |
FR24_SATELLITE_ATTR | © Esri, Maxar… | Tasvir atributsiyasi (xarita burchagida) |
FR24_SATELLITE_MAXZOOM | 19 | Tasvir manbasining maksimal zoomi |
5. GET /api/flights
curl "http://localhost:8070/api/flights?bbox=42,52,-8,10&limit=2000"
{
"flights": [ { "id": 981234567, "latitude": 46.6, "longitude": 6.5,
"track": 169, "altitude": 35000, "ground_speed": 459, "on_ground": false,
"callsign": "BEL4KE", "registration": "OO-SFF", "typecode": "A333",
"origin": "BRU", "destination": "KGL", "cat": "widebody",
"cls": "passenger", "op": "Brussels Airlines", "tn": "A-330-300",
"vertical_speed": 0, "squawk": 0, "source": 0, "ts": 1756351234.1 } ],
"shown": 812, "matched": 812, "world_total": 16044,
"counts": { "military": 118, "government": 25, "passenger": 15100,
"cargo": 340, "helicopter": 210, "other": 250 },
"snapshot_age": 4.3
}
bbox = south,north,west,east (gradus).
west > east — antimeridian kesib o‘tish, qo‘llab-quvvatlanadi.
limit — ixtiyoriy, default 2000. Ko‘p bo‘lsa
javob fazoviy tekis siyraklashtiriladi (shakli saqlanadi).
class — ixtiyoriy: military|government|passenger|cargo|
helicopter|other — faqat shu turdagi reyslar.
ids — ixtiyoriy, vergul bilan (maks 20): shu reys id’lari
limit/bboxdan qat’i nazar javobga kiritiladi
(front-end tanlangan reysни shu bilan “mahkamlaydi”).
cls — reys turi (tasnif), op — operator /
aviakompaniya, tn — samolyot modeli nomi (7-bo‘lim).
6. GET /api/airports
{ "airports": [ [41.2579, 69.2812, "TAS",
"Tashkent International Airport", 1, "uz"] ] }
Element: [lat, lon, IATA, nom, size, cc] — size
1=yirik 0=o‘rta, cc=ISO davlat kodi (kичik harf,
/flags/<cc>.svg ga mos). Yiriklari oldinda, 900 ta bilan
cheklangan.
7. Qidiruv va tasniflash
Har bir reys server tomonida tasniflanadi (cls):
harbiy, hukumat, yo‘lovchi, yuk,
vertolyot yoki boshqa. Belgilar:
- Bort raqami —
plane-alert-db(sdr-enthusiasts, ~12 000 harbiy/hukumat/politsiya bort raqami) bo‘yicha aniq moslik. - Chaqiruv prefiksi — curated harbiy/hukumat prefikslari (RCH, RRR, GAF, CTM, IAM…).
- Samolyot tipi — 224 ta shubhasiz harbiy ICAO tип belgisi (F16, C130, E3TF, AH64…) va vertolyot tiplari.
- Aviakompaniya — OpenFlights ICAO kodi bo‘yicha yo‘lovchi/yuk.
Operator nomi va airline_overrides.json
airlines.json manbasi — OpenFlights, u taxminan
2014-yildan beri yangilanmagan. Buning uchta oqibati bor: yopilgan
aviakompaniyalar hali ro‘yxatda; 2015-yildan keyin tashkil etilganlari umuman
yo‘q; va ba’zi ICAO kodlari boshqa tashkilotga qayta berilgan — bu eng
yomoni, chunki jonli reysga ishonch bilan noto‘g‘ri operator yoziladi.
Haqiqiy misol: USA kodi endi Silk Avia (O‘zbekiston,
ATR-72-600) niki, lekin OpenFlights uni hali US Airways deb biladi —
natijada Toshkent–Buxoro reysi amerika aviakompaniyasi sifatida ko‘rinardi.
airline_overrides.json shu xatolarni airlines.json ga
tegmasdan tuzatadi (u fayl scripts/make_aircraftdb.py tomonidan
qayta generatsiya qilinishi mumkin):
{
"add": { "USA": ["Silk Avia", "Uzbekistan", 0] },
"retired": ["AWE", "COA", "NWA", "TWA", "BER", "AZA", "..."]
}
| Kalit | Ma’no |
|---|---|
add | ICAO kodi → [nom, davlat, yuk_tashuvchimi]. Mavjud qatorni almashtiradi yoki yangisini qo‘shadi. |
retired | Ishlatilmaydigan kodlar butunlay olib tashlanadi — noto‘g‘ri nom ko‘rsatgandan ko‘ra hech nima ko‘rsatmagan afzal. |
Fayl tahrirlangandan keyin webapp.py ni qayta ishga tushiring.
curl "http://localhost:8070/api/search?q=RCH&class=military&field=callsign"
{
"results": [ { ...flight..., "cls": "military", "op": "US Air Mobility Command",
"tn": "C-17 Globemaster III" } ],
"shown": 12,
"counts": { "military": 118, "government": 25, "passenger": 15100, ... },
"world_total": 16044, "snapshot_age": 3.1
}
| Parametr | Ma’no |
|---|---|
q | Qidiruv matni (bo‘sh bo‘lса — faqat filtr) |
class | Tur bo‘yicha filtr (yuqoridagi 6 tadan biri) |
field | any (default) · callsign · reg · type · operator · route |
bbox | Berilса — faqat shu to‘rtburchak ichida qidiradi |
limit | 1–400, default 120 |
Xaritadagi qidiruv paneli (HUD’dagi tugma): 6 ta tur yorlig‘i
(jonli sanoq bilan), maydon tanlagichi va matn qatori. Bir turni tanlash
xaritani ham o‘sha turga filtrlaydi. “harbiy samolyotlar bazasi” — barcha
224 ta harbiy tип nomi katalogи (/aircraft_types.jsonдан).
8. PostgreSQL — reyslar jurnali
Ixtiyoriy. FR24_DATABASE_URL berilса, poller har siklda
uchayotgan / harakatlanayotgan (on_ground=false yoki tezlik
≥ FR24_DB_MIN_SPEED) har bir reysни flight_log
jadvaliga upsert qiladi (har FR24 reys legи — bitta qator, yangilanib
boradi). Berilмаса — servis o‘zgarishsiz ishlaydi.
Yozuv alohida oqimда (thread) navbat orqali amalga oshadi — DB kechiksa
poller hech qачон kutmaydi; navbat to‘lса bir sikl tashlanadi. Yozuvchi
oqim orqада qolса eski (navbatдаги) suratlar tashlanиб, faqat eng yangиси
yozилади. Sxема ishга tushганда avtomatik yaratiladi
(scripts/schema.sql).
Jadval cheksiz o‘smаsлиги uchun yozuvchi oqim soatda bir marta
last_seen FR24_DB_RETENTION_DAYS kundan eski
qatorларни o‘chиради (0 = cheksiz saqlash). /log/ va boshqa
o‘qиш yo‘llаri FR24_DB_POOL ta qайта ishlатилаdиган ulanишни
bo‘lишади — har so‘rovда yangi ulanиш ochилmaydi.
flight_log jadvali
| Ustun | Ma’no |
|---|---|
id | Tartib raqam (BIGSERIAL) |
flight_code | Reys kodi (callsign) |
aircraft_type | Samolyot turi — ICAO belgisi (masalan A333) |
aircraft_model | To‘liq nomi (Airbus A330-300) |
registration | Registr raqami (bort raqami) |
origin_code / origin_name | Qayerdan — IATA / to‘liq (Brussels Airport, Belgium) |
destination_code / destination_name | Qayerga — IATA / to‘liq |
route | “Brussels Airport, Belgium → Kigali International Airport, Rwanda” |
flight_class, operator | Tur (7-bo‘lim) va operator |
first_seen, last_seen, observations | Kuzatuv oynasi |
last_latitude … last_track | Oxirgi pozitsiya / tezlik / kurs |
# docker-compose bilan (db servisi ichida): FR24_DATABASE_URL=postgresql://fr24:fr24@db:5432/fr24 # lokal test: docker run -d --name pg -e POSTGRES_PASSWORD=fr24 -e POSTGRES_DB=fr24 \ -p 5432:5432 postgres:16-alpine export FR24_DATABASE_URL=postgresql://postgres:fr24@localhost:5432/fr24 python webapp.py # ko‘rish: http://localhost:8070/log/
| Env | Default | Ma’no |
|---|---|---|
FR24_DATABASE_URL | — | PostgreSQL DSN. Berilса jurnal yoqiladi |
FR24_DB_MIN_SPEED | 5 | Yerда shundan sekin reys yozilmaydi (kt) |
FR24_DB_QUEUE | 4 | Navbat shundan uzunlashса sikl tashlanadi |
FR24_DB_RETENTION_DAYS | 30 | Shundan eski (ko‘rinmagan) qatorlar o‘chiriladi; 0 = cheksiz |
FR24_DB_POOL | 4 | O‘qish yo‘llari uchun qayta ishlatiladigan PG ulanishlari |
9. Boshqa marshrutlar
/api/meta | {poller, world_flights, counts, db, tracking, snapshot_age, ...} |
/api/selftest | 20 ta tekshiruv; hammasi o‘tса 200, aks holda 503. FR24’ga so‘rov yubormaydi. |
/healthz | {"status":"ok"} |
/flags/<cc>.svg | Lokal SVG bayroq (flag-icons, MIT), Cache-Control: 30 kun |
/aircraft_types.json | ICAO tип belgisi → {nom, ishlab chiqaruvchi, sinf, harbiy?} |
10. Xarita: ikonka, iz, bayroq
Ikki asos rejimi
HUD’dagi segment tugmasi asos xaritani almashtiradi; tanlov
localStorage da saqlanadi va /?basemap=satellite
bilan ulashiladi.
| Rejim | Nima | Manba |
|---|---|---|
| xarita | flightradar24.com uslubidagi vektor | MapLibre GL + OpenFreeMap Positron (kalitsiz) |
| sun’iy yo‘ldosh | orbitadan olingan tasvir | Esri World Imagery (kalitsiz) — FR24_SATELLITE_URL |
Raster qatlam birinchi symbol qatlamining ostiga qo‘yiladi
(map.addLayer(…, firstSymbolId)), shuning uchun tasvir butun
vektor fonini yopadi, lekin joy nomlari, chegaralar va reyslar ustida qoladi.
Almashish — bu visibility o‘zgarishi: style qayta yuklanmaydi,
keshdagi tayllar qayta so‘ralmaydi. Tasvir ustida yorliqlar oq rangga va
qalin qora halo’ga o‘tadi — cho‘lda ham, o‘rmonda ham o‘qiladigan yagona
kombinatsiya.
Chizish: bitta <canvas> (GPU)
Barcha reyslar, izlar va aeroportlar bitta <canvas>
elementига chizилади (Path2D siluetlari, GPU-kompozitsiya). Ilgари har reys
alohida DOM element (marker) edi va har yangilanishda o‘chirilib qayta
yaratilardi — shu “qotib qolish” ga sabab bo‘lardi. Endi DOM umuman
o‘zgarmaydi; har kadrda faqat canvas qayta chiziladi (~1–2 ming siluet, <5 ms).
Canvas doim (0,0)’da turadi va har kadr MapLibre’ning
map.project()’i orqali qayta proyeksiyalanadi. MapLibre o‘z
transformini har render kadrida yangilab turadi, shuning uchun surish, zoom
va inertsiya paytida reyslar plitka bilan 1:1 siljiydi — qotish yoki
sakrash yo‘q (flightradar24.com bilan bir xil yondashuv). Leaflet
tarmog‘ida esa canvas xarita pane’i ichida.
Ikonka — rusumga qarab
Siluet ICAO tип belgisiga qarab tanlanади: keng fyuzelyaj (A380/747), oddiy layner, regional, biznes-jet, turboprop, yengil, harbiy jet (delta), harbiy transport, vertolyot, planer, dron. Rang — balandlik bo‘yicha (legenda). Kursorni ustiga olib borsangiz siluet oqaради va yonида chaqiruv/model/balandlik yorlig‘i chiqади.
Marshrut chizig‘i
Reysни tanlaganда, agar uchgan va boradiган aeroporti ma’lum
bo‘lса, katta doira yoyи bilan avtomatik marshrut chizилади:
o‘tilган qism xira, qolgani yorqin uzuq chiziq; ikki uchида aeroport
kodi (FRA, LHR).
Silliq harakat
Server har 18 s yangilanадi, lekin brauzer reysни track
va ground_speed bo‘yicha har kadrда (60 fps) hisoblab siljitади —
FR24’dagi kabi uzluksiz. Yangi surat kelganда pozitsiya yumshoq
tuzatилади (lerp). Zoom paytида canvas 250 ms yashirилиб, keyin qайта
tekislанади.
Izlar
Har reys uchun oxirgi ~40 nuqta brauzerда saqlanadi. HUD’dagi izlar tugmasi hammasини ko‘rsatadi; aks holда faqat tanlangan (ustiga bosilgan) reysning izi chiziladi. Rang — balandlik bo‘yicha.
Aeroport + bayroq
Aeroport — tomchi-pin + boshqaruv minorasi belgisi (oq disk,
yumshoq soya); uchi aynan aeroport ustida. Rang/o‘lcham: oltin — yirik
xalqaro, moviy — o‘rta, kulrang — kichik (jadvalli). z≥7
dan hamma aeroport ko‘rinadi (~6145 ta: yirik + o‘rta +
jadvalli kichik); undan uzoqroqda faqat yirik/o‘rtalari. IATA kod yorlig‘i
darajama-daraja ochiladi (yirik z≥7, o‘rta z≥8, hammasi z≥10) yoki
kursor ostida. Ustiga bosилганда kartoчka:
davlat bayrog‘i, nomi, IATA / ICAO (MAD / LEMD),
davlat, turi, koordinata, Google Maps. airports.jsonни
python scripts/make_airports.py yangилайди; ICAO qo‘shиш uchun
scripts/add_airport_icao.py.
Samolyot surati — uch bosqichli
Popup eng aniq mos suratni tanlaydi. Faqat tur bo‘yicha bitta rasm ko‘rsatish “Aeroflot A330” ni umumiy A330 sifatida ko‘rsatardi; endi operator va davlat variantlari ham bor:
| Kalit | Qayerdan olinadi | Ma’no | Misol |
|---|---|---|---|
<TIP>__<OPERATOR> | chaqiruvning 1–3-harfi | o‘sha aviakompaniya bo‘yog‘ida | B738__RYR |
<TIP>__<DAVLAT> | registratsiya prefiksi | o‘sha davlat belgilarida | C30J__US |
<TIP> | ICAO tip belgisi | umumiy tur surati | A333 |
Hammasi lokal (/aircraft_photos/<kalit>), bayroqlar kabi
bundlangan. Faqat erkin litsenziya (Public Domain, CC0, CC BY, CC BY-SA),
har biri ≤ 440 px; muallif + litsenziya popup’da ko‘rsatiladi
(/aircraft_photos.json). Mos surat topilmasa popup o‘zgarishsiz.
python scripts/make_aircraft_photos.py # tur suratlari python scripts/make_aircraft_photos.py --variants --from-db # jurnaldagi eng ko‘p juftliklar python scripts/make_aircraft_photos.py --variants --from-api --top 150
Variantlar Wikipedia maqolasining bosh rasmidan emas, Wikimedia Commons fayl qidiruvidan olinadi (“Aeroflot Airbus A330-300” uchun maqola yo‘q, lekin fotosuratlar bor). Nomzodlar baholanadi: kabina, salon, dvigatel, dum yaqin planlari rad etiladi; in flight / takeoff / landing kadrlari ustun turadi.
Bort davlati va bayroq
Registratsiya prefiksi ISO davlat kodiga aylantiriladi
(registration_prefixes.json) va popup’da bayroq bo‘lib chiqadi:
UK-72601 → uz. Har reys /api/flights javobida
cc maydonini oladi.
Eng uzun moslik ustun: VP-B… (Bermuda — u yerda ko‘p
rus operatorlarining samolyotlari ro‘yxatga olingan) VP dan oldin
tekshiriladi, C-F/C-G (Kanada) C dan
oldin. Bir harfli belgilar (F, N,
D, G…) juda ochko‘z, shuning uchun ular faqat qolgan
qism o‘sha davlatning shakliga mos kelganda ishlaydi — F-GKXL →
Fransiya, lekin FAB2019 (Braziliya harbiy seriyasi) →
aniqlanmadi. Noto‘g‘ri bayroq ko‘rsatgandan ko‘ra hech nima ko‘rsatmagan
afzal.
Balandlik → rang
Ranglar ichki hisobda futda: hue = 20 + 320 × (ft / 40000) —
0 to‘q sariq → 3k m yashil → 6k m moviy → 9k m ko‘k → 12k+ m pushti.
O‘lchov birliklari — to‘liq metrik
FR24 feed’i aviatsiya birliklarida keladi (fut, tugun, fut/daqiqa). Ekranda hammasi metrik ko‘rsatiladi:
| Nima | Feed | Ekranda | Formula |
|---|---|---|---|
| Balandlik | fut | metr | altM(ft) = ft × 0.3048 |
| Tezlik | tugun (kt) | km/h | spdKmh(kt) = kt × 1.852 |
| Vertikal tezlik | fut/daq | m/s | vsMs(fpm) = fpm × 0.00508 |
Ichki qiymatlar o‘zgarmaydi — API javobi, PostgreSQL ustunlari, rang formulasi va brauzerdagi dead-reckoning hisobi asl birliklarda qoladi. Faqat ekranga chiqadigan matn konvertatsiya qilinadi, shuning uchun API iste’molchilari uchun hech narsa buzilmaydi.
11. Cheklovlar
- Anonim rejim:
squawk,vertical_speedko‘pincha bo‘sh (0) keladi. - Har kesim 1500 reys — juda kam hollarда gavjum zona to‘lib,
ba’zi reyslar keyingi siklда ko‘rinishi mumkin. Kerak bo‘lsa
FR24_LAT_BANDSni ko‘paytiring. - Asos xarita — MapLibre GL vektor tayllari (default: OpenFreeMap “Positron”, kalitsiz). Faqat tayl hosti CSP’da ochiladi; bayroqlar lokal (
/flags/). - Boshqa ko‘rinish uchun
FR24_BASEMAP_STYLE— istalgan MapLibre uslub URL’i, yoki lokalstyle.json+ bundlangan.pmtiles(to‘liq oflayn). MapLibre vendorlanmasa — kalitsiz Leaflet + OpenStreetMap raster (FR24_TILE_URLbilan almashtiriladi). - Reys tasnifi (
cls) — evristik: bort raqami + chaqiruv + tип bo‘yicha. Anonim feed’da ICAO24 hex yo‘q, shuning uchun ba’zi harbiy/hukumat reyslari “yo‘lovchi” deb belgilanishi (yoki aksincha) mumkin. Bazani yangilash:python scripts/make_aircraftdb.py. - Ma’lumot Flightradar24 mulki — faqat ta’lim maqsadida. Aeroport / chegara / bayroq / tип ma’lumotlari ochiq (public-domain / MIT / ODbL).
12. Nima o‘zgardi (v3) — qadamma-qadam
Quyidagilar oxirgi ish bosqichida qo‘shildi / tuzatildi.
- PostgreSQL drayveri birlashtirildi.
tracking/quyi tizimipsycopg2danwebapp.pybilan bir xilpsycopg3 ga ko‘chirildi — bitta drayver, bitta ulanish pooli uslubi. - Chuqur tarix webapp ичига ulandi.
FR24_TRACKING=1+ DSN berilса, poller o‘z process’ида har sweepdan keyintracking/sxемасига yozadi (alohida thread + navbat — poller kutmaydi) va harFR24_TRACKING_ROLLUP_INTERVALs da kunlik / haftalik / oylik yig‘malарни hisoblaydi. Ikkinchi FR24 poller ishga tushмайди. - Trayektoriya saqlashда klass filtri.
flight_position_log(24 soatlik playback jadvali) endi faqat harbiy, hukumat, yuk, vertolyot klasslаrини saqlaydi. Yo‘lovchi (feed’ning ~90% i) vaboshqa(evristik) yozилмайди — bu bazani keskin kичрайтиради. Sozlash:FR24_TRACK_CLASSES(all= hammаси, yoki vergul bilan ro‘yxat).flight_log(reyslar jurnali) baribir har klassни yozади. - “Baza bo‘yicha ko‘rish” (3 bosqich). Qidiruv panelидаги baza bo‘yicha ko‘rish → havolаси: klasslar ro‘yxати → klassni tanlash → o‘sha klassдаги bortlar (rusumi, nuqtalar soni) → bortni tanlash yangi oynада jonli xaritани ochади va o‘sha samolyotning 24 soatlik harakати playback rejimида chizилади.
/api/track?reg=qo‘shилди — bitta bort raqамининг barcha reys leglаrини bitta 24 soatlik izга birlashtiради (ilgари faqat?id=— bitta leg edi). Javobгаflightmeta-bloki (callsign, model, klass, operator) qo‘shildi, shuning uchun deep-link jonli reyssiz ham ishlaydi.- Interaktiv API sahifasi.
/api-docs/— bundlланган Swagger UI (CDN’siz) + qo‘lда yozilган/openapi.json(OpenAPI 3.1). Har endpointни “Try it out” bilan sinаб ko‘rish mumkin. - Self-test endi 19 ta tekshiruv —
trackingholати vaopenapi + swagger uiqo‘shildi./api/metajavobiгаtrackingbloki kirди.
v3.1 — xarita va ikonkalar
- Ikonka rusumga qarab — ~12 siluet (keng fyuzelyaj, layner,
regional, biznes-jet, turboprop, yengil, harbiy jet, harbiy transport,
vertolyot, planer, dron). Server ICAO tип belgisini tanlаб beради
(
catmaydoni). - Hover — kursor ustида: siluet oqаради + chaqiruv / model / balandlik yorlig‘i.
- Avtomatik marshrut — reys tanlanганда origin↔destination
katta doira yoyи (o‘tilган qism xira, qolgani yorqin, uch kodlаri
bilan). Yangi endpoint:
/api/airports?codes=TAS,IST. - Aeroport markerlari — tomchi-pin + minora belgisi, uchи aynан
aeroport ustида; kartochkада IATA / ICAO.
airports.jsonqайта generatsiya qilинди (6145 aeroport, 3 daraja, 5788 tasida ICAO).scripts/add_airport_icao.pyqo‘shildi. - “Baza bo‘yicha ko‘rish” endi playback’ни shu oynada ochади (yangi tab emas).
- Xarita adapteri — surish/zoom paytida samolyotlar “qotib qolib keyin sakraydigan” xatosi tuzatildi: canvas doim (0,0)’da, har kadr xarita markazidan qayta proyeksiyalanadi.
v3.2 — marshrut chizig‘i, HUD, hujjat
- Marshrut chizig‘i endi samolyot ustidan o‘tади (FR24 uslуби): katta doira origin → hozirgi joy → destination orqали qайта quriladi (har kadr, jonli pozitsiyaдан). Uchgan qism to‘liq, qolgani punktir; ikki uchида aeroport kodi. Faqat bosilganда chiqади — hover holати o‘zgармайди.
- HUD qайта dizayn — soddaроq, aniqроq bloklar. izlar,
API, hujjat tugмалаri olib tashlанди. API va hujjat endi
faqat /api-docs/ va /docs/
manzilидан (bu sahifa
/hujjatbilan ham ochилади). - 0-bo‘lim “Ishga tushirish” — lokal / Docker / tekshiruv ko‘rsатмалаri shu sahifada.
v3.3 — yagona MapLibre xarita (FR24 ko‘rinishi)
- Google va Yandex adapterlari olib tashlandi. Endi bitta xarita: MapLibre GL + flightradar24.com’ga o‘xshash vektor uslub (kalitsiz OpenFreeMap Positron; suv/quruqlik palitrasi FR24 ostiga moslandi).
- Surganda samolyotlar qotmaydi. MapLibre o‘z transformini har render kadrida yangilaydi — reyslar
map.project()orqali har kadr proyeksiyalanib, plitka bilan 1:1 siljiydi (surish, zoom, inertsiya). Bu FR24’ning o‘z yondashuvi. - Reys kartochkasi samolyot ustida emas — o‘ng pastki burchakka biriktirildi (docked); samolyotni to‘smaydi, ichi uzun bo‘lsa skroll bo‘ladi.
- Oflayn yo‘li:
FR24_BASEMAP_STYLEni lokalstyle.jsonga qaratib,.pmtilesfaylini bundlaganda xarita internetsiz ishlaydi (Docker.taruchun).
v3.4 — balandlik metrda, aeroportlar, marshrut nomlari
- Balandlik hamma joyda metrda (FR24 metrik uslubi):
altM(ft)=ft×0.3048. Ichki qiymatlar (API, DB, rang formulasi) futda qoladi. Legenda: Balandlik (m). - Aeroportlar qayta chizildi — yangi pin (oq disk + minora + soya), IATA kodi pill’da. Yiriklar endi z≥5 dan ko‘rinadi (ilgari z7), o‘rta z≥7, kichik z≥9.
- Marshrut nomlari — reysga bosilганда popup’da kod bilan birga
aeroport nomi ham chiqadi (
TAS Toshkent → IST Istanbul), agar/api/airports?codes=dan topilса. - “Baza bo‘yicha ko‘rish” da filtr — bort raqami / rusum / klass bo‘yicha ro‘yxatni tez suzgich.
v3.5 — FR24 palitra, lotin yozuvi, marshrut zoomda qoladi
- Xarita rangi flightradar24.com uslubida —
fr24Palette()Positron uslubini qayta bo‘yaydi: tiniq ko‘k suv (#a3ccec), oq-issiq quruqlik, jimgina yo‘llar, kulrang chegaralar. - Joy nomlari lotin yozuvida — har bir yorliq
coalesce(name:uz, name:latin, name): O‘zbekiston ichida o‘zbekcha, tashqarida lotin transliteratsiya (kirill / arab / ieroglif emas). Eslatma: bepul OpenMapTiles ma’lumotidaname:uzmaydoni yo‘q — to‘liq o‘zbekcha (chet el shaharlari) uchun alohida lug‘at yoki pullik multitil plitka kerak. - Tanlangan reys va marshrut zoomda yo‘qolmaydi —
/api/flights?ids=tanlangan reysни reys-cheklovi/bbox’dan qat’i nazar javobga qo‘shadi; marshrutherebo‘lmasa ham origin→dest to‘liq katta doira sifatida chiziladi.
13. Baza bo‘yicha ko‘rish + API test
3 bosqich
1) /api/fleet/classes → klass · samolyot soni · nuqta soni (oxirgi 24 soat)
2) /api/fleet/aircraft?class=military
→ bort · rusum · nuqta soni · leg soni (≥ 2 nuqta)
3) /?track=reg:<REG> → jonli xarita: faqat o‘sha samolyot, DB
koordinatalari bo‘yicha yo‘nalish; pastdagi
shkala bilan vaqtni orqaga surasiz (teskari iz)
Xaritada Qidiruv → baza bo‘yicha ko‘rish → shu oqimни UI orqали
beради. Bortni tanlaganда /?track=reg:<REG> yangi tabда
ochилади: barcha jonli reyslar yashirилади, faqat tanlangan bort
qolади, uning bazага yozилган nuqталаri chizилади. Shkалани surсангиз —
o‘sha vaqтга qайтади va iz teskari qisqаради; strelkалаr haqiqiy uchish
tarafини ko‘rsатади. “Jonli xaritaga qaytish” tugмаси playback’ни yopади.
/api/track parametrlari
| Param | Ma’no |
|---|---|
id | Bitta FR24 reys legi id’si (/api/flights dan) |
reg | Bort raqami — 24 soатдаги barcha leglar bitta izга |
Ikkalasi ham FR24_DATABASE_URL ni talab qiladi; aks holда
503. Faqat FR24_TRACK_CLASSES ga kirган klasslar
uchun ma’lumot bo‘lади.
API test sahifasi
/api-docs/ — barcha
/api/* endpointлаri Swagger UI’да. Har birини brauzerдан
to‘g‘ridan-to‘g‘ri chaqirib, javоbни ko‘rish mumkin (“Try it out”).
Spetsifikatsiya: /openapi.json.
14. Testlash tartibi
To‘liq to‘plamni ishga tushirish
pip install -r requirements-dev.txt
pytest # hammasi
pytest -q -k gzip # bitta mavzu
pytest --collect-only -q # nima qamralganini ko‘rish
Testlar tarmoqqa chiqmaydi va pollerni ishga tushirmaydi:
STATE soxta surat bilan almashtiriladi, HTTP server esa tasodifiy
portda ko‘tariladi. Shuning uchun ular FR24 holatiga bog‘liq emas.
Baza kerak bo‘lgan testlar
Bir nechta test PostgreSQL talab qiladi va usiz skip bo‘ladi — yiqilmaydi. Yoqish uchun bir martalik bazani ko‘rsating:
docker run -d --name pg -e POSTGRES_PASSWORD=fr24 -e POSTGRES_DB=fr24 -p 5432:5432 postgres:16-alpine
FR24_TEST_DATABASE_URL=postgresql://postgres:fr24@localhost:5432/fr24 TRACKING_TEST_DATABASE_URL=postgresql://postgres:fr24@localhost:5432/fr24 pytest
Diqqat: bu bazaga sxema qo‘llanadi va jadvallar TRUNCATE
qilinadi — faqat bir martalik bazani bering.
Qism-tizimlarni qo‘lda tekshirish
| Nima | Qanday | Kutilgan natija |
|---|---|---|
| Poller tirikmi | curl -s localhost:8070/api/meta |
snapshot_age kichik, sweeps o‘smoqda |
| 20 ta ichki tekshiruv | curl -s localhost:8070/api/selftest |
200 va ok:true; aks holda 503 |
| Metrikalar | curl -s localhost:8070/metrics |
Prometheus matni; bazaga so‘rov yubormaydi |
| Siqish | curl -sH "Accept-Encoding: gzip" -o /dev/null -w "%{size_download}" localhost:8070/api/flights |
siqilmaganidan ~6–7× kichik |
| Kesh | curl -sI localhost:8070/ dagi ETag bilan If-None-Match |
ikkinchi so‘rovda 304 |
| Rate limit | ketma-ket 240 dan ortiq /api/meta |
chegaradan keyin 429 |
| Xavfsizlik sarlavhalari | curl -sI localhost:8070/ |
Server: fr24web, CSP, COOP/CORP, Permissions-Policy |
| Yo‘l bo‘ylab chiqish | curl -s localhost:8070/static/../webapp.py |
404 — statik fayllar xotiradagi lug‘atdan beriladi |
| Replika feed’i | curl -si localhost:8070/api/snapshot |
token yo‘q — 404; noto‘g‘ri token — 401 |
Yetakchi + replikani sinash
# 1-terminal — yetakchi
FR24_REPLICA_TOKEN=$(python -c "import secrets;print(secrets.token_hex(32))") python webapp.py
# 2-terminal — replika (FR24 ga tegmaydi)
FR24_POLLER=0 FR24_UPSTREAM=http://127.0.0.1:8070 FR24_REPLICA_TOKEN=<o‘sha token> FR24_WEB_PORT=8071 python webapp.py
Ikkalasi bir xil world_flights berishi, replikada esa
sweeps 0 bo‘lib qolishi kerak — u FR24 ga umuman
bormaydi.
Linter va CI
ruff check webapp.py scripts tests tracking
.github/workflows/ci.yml har push’da: ruff,
pytest (PostgreSQL servisi bilan), tracking uchun
uchdan-uchgacha CLI sinovi, so‘ng Docker образни qurib konteynerni ko‘taradi
va /api/selftest ni talab qiladi.
15. Xavfsizlik (OWASP Top 10 — 2021)
Har bir band tests/ dagi test_a0* nomli test bilan
mustahkamlangan.
| OWASP | Nima qilingan |
|---|---|
| A01 Kirish nazorati | /api/snapshot — butun ma’lumot to‘plami — token sozlanmagan bo‘lsa 404, ya’ni mavjudligini ham bildirmaydi. Statik fayllar xotiradagi lug‘atdan beriladi, ya’ni yo‘l bo‘ylab chiqish imkonsiz. |
| A02 Kriptografiya | Token hmac.compare_digest bilan doimiy vaqtda solishtiriladi. DSN loglarda niqoblanadi (://***@); token hech qachon loglanmaydi. |
| A03 Inyeksiya | Butun SQL parametrlangan; identifikatorlar psycopg.sql.Identifier orqali. Brauzerda barcha maydonlar htmlesc dan o‘tadi. Mijoz satri logga yozilishdan oldin _log_safe bilan tozalanadi — aks holda so‘rov qatoridagi boshqaruv baytlari soxta log qatori yasashi yoki terminal escape yuborishi mumkin edi. |
| A04 Xavfsiz bo‘lmagan dizayn | IP bo‘yicha token-bucket, bir vaqtdagi so‘rovlar chegarasi va undan oshsa yukni tashlash, javob hajmi chegarasi. |
| A05 Noto‘g‘ri sozlash | Server sarlavhasi Python versiyasini oshkor qilmaydi. CSP, X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Permissions-Policy, Cross-Origin-Opener-Policy, Cross-Origin-Resource-Policy. HSTS — FR24_HSTS_MAX_AGE bilan ixtiyoriy. |
| A06 Eskirgan komponentlar | Bog‘liqliklar beshta; fr24/ vendorlangan (yangilash: fr24/UPDATING.md). Ochiq kamchilik: vendorlangan nusxa uchun avtomatik CVE kuzatuvi yo‘q. |
| A07 Autentifikatsiya | Yagona sir — replika tokeni; 24 belgidan qisqa bo‘lsa process ishga tushmaydi. Qolgan hamma narsa ataylab ochiq (bu ommaviy xarita). |
| A08 Ta’minot zanjiri | Uchinchi tomon skripti/uslubi umuman yuklanmaydi: MapLibre, Leaflet, Swagger UI — hammasi static/ da. Ilgari ikkala xarita ham topilmasa unpkg.com dan SRI’siz skript yuklanardi; endi bu holda servis aniq xato bilan to‘xtaydi. |
| A09 Jurnal va monitoring | /metrics — poller, HTTP, DB va tracking sanoqlari. Rad etilgan replika urinishi WARNING bilan yoziladi va sanaladi. Poller xato darajasi oynali hisoblanadi, umr bo‘yi emas. |
| A10 SSRF | Yagona chiquvchi manzil — FR24_UPSTREAM (operator sozlamasi). Sxema http(s) ekani tekshiriladi, qayta yo‘naltirish rad etiladi — aks holda buzilgan yetakchi tokenni ichki manzilga yo‘naltirishi mumkin — va javob hajmi cheklangan. |
Eslatma: servis TLS’ni o‘zi tugatmaydi. Ochiq internetda oldiga
reverse-proxy qo‘ying va FR24_TRUSTED_PROXY=1 bering, aks holda
rate limiter hamma foydalanuvchini bitta IP deb sanaydi.
16. Funksiyalar ma’lumotnomasi
Jami 188 ta funksiya/klass; 0 tasining nomi tests/ da uchraydi (0%). Bu jadval kodning o‘zidan (ast bilan) har ishga tushganda qayta quriladi — qo‘lda yozilgan ro‘yxat ertasiga eskirardi.
webapp.py · 111 ta
Butun servis: poller, surat, API, HTTP qatlami
| qator | nomi | test | vazifasi |
|---|---|---|---|
| 87 | _env_float | · | — |
| 94 | _env_int | · | — |
| 101 | _env_bool | · | — |
| 108 | _env_str | · | Read a string setting; an empty / whitespace value means "unset". |
| 311 | _load_json | · | — |
| 333 | airport_full | · | 'BRU' -> 'Brussels Airport, Belgium' ('???' -> '???'). |
| 411 | _bucket_cls | · | Fold a flight's stored class into one of the six CLASS_LABELS buckets. |
| 420 | _class_set | · | Parse a `FR24_*_CLASSES` value ("all" | "*" | comma list) into a set. |
| 434 | _track_class_ok | · | True if this flight's class is one we keep a position history for. |
| 439 | _tracking_class_ok | · | True if this flight belongs in the deep-history store. |
| 444 | _norm_reg | · | — |
| 467 | reg_country | · | 'UK72601' -> 'uz'. Empty string when the mark is unknown. |
| 486 | _prefix_lookup | · | Longest-prefix match of a callsign against a {prefix: label} table. |
| 500 | classify | · | -> (class, operator, type_name). class in CLASS_LABELS. |
| 543 | _airline_name | · | — |
| 625 | airports_in | · | Airports inside the viewport, large ones first, capped. |
| 714 | shape_category | · | Map an ICAO type designator (+ FR24 icon + class) to a silhouette bucket. |
| 827 | Snapshot | · | — |
| 862 | _current_slices | · | — |
| 869 | _slice_plan | · | — |
| 878 | _ingest | · | — |
| 919 | _publish_flights | · | Index a flight list and publish it as the snapshot readers see. |
| 935 | _publish | · | — |
| 944 | _fetch_box | · | — |
| 963 | _poller_main | · | — |
| 1004 | _start_poller | · | — |
| 1029 | _NoRedirect | · | Refuse redirects when following the leader. |
| 1038 | _NoRedirect.redirect_request | · | — |
| 1046 | _fetch_upstream_snapshot | · | Pull the leader's whole world. Returns the flight list. |
| 1065 | _replica_once | · | One pull from the leader, published locally. Raises if the pull fails. |
| 1078 | _replica_main | · | — |
| 1096 | _start_replica | · | — |
| 1167 | _PgPool | · | Tiny thread-safe connection pool for the read paths (/log/, /api/meta). |
| 1181 | _PgPool._connect | · | — |
| 1186 | _PgPool.connection | · | — |
| 1220 | _PgPool.close | · | — |
| 1234 | _pool | · | — |
| 1294 | _flight_row | · | — |
| 1322 | _position_row | · | One timestamped observation for the 24-hour playback timeline. |
| 1337 | _DbBatch | · | One sweep, fully materialised by the poller thread before it is queued. |
| 1344 | _moving | · | Skip parked aircraft: on the ground and not taxiing is not an observation. |
| 1349 | _db_enqueue | · | Build a sweep's rows *in the poller thread* and hand them to the writer. |
| 1374 | _position_retention_hours | · | Hours of `flight_position_log` to keep. 0 = keep forever. |
| 1381 | _db_prune | · | Drop rows past their retention window; runs at most hourly. |
| 1419 | _db_writer | · | — |
| 1484 | _start_db | · | — |
| 1496 | db_query_log | · | Read recent rows from flight_log (returns [] if DB unavailable). |
| 1545 | _db_totals | · | `flight_log` aggregates, memoised — they are full sequential scans. |
| 1577 | _set_db_totals | · | — |
| 1582 | db_summary | · | Writer counters (always live) plus the cached table aggregates. |
| 1600 | _track_rows | · | — |
| 1606 | db_flight_track | · | Timestamped observations for one FR24 flight leg, latest 24 hours. |
| 1625 | db_track_by_reg | · | Every logged position for one airframe (all its legs), latest 24 hours. |
| 1645 | db_flight_meta | · | Identity fields for a leg (by id) or an airframe (by registration). |
| 1675 | db_fleet_classes | · | Per-class rollup over the airframes that have a logged position history. |
| 1703 | db_fleet_aircraft | · | Airframes in one class that have >= 2 logged positions in the last 24 h. |
| 1765 | _tracking_enqueue | · | Queue one sweep for the deep-history writer (poller thread only). |
| 1779 | _tracking_writer | · | — |
| 1853 | _start_tracking | · | — |
| 1865 | tracking_summary | · | In-memory status of the deep-history writer (no DB round trip). |
| 1881 | _lon_ranges | · | — |
| 1887 | _subsample | · | Even-ish spatial thinning so a wide view keeps its shape. |
| 1896 | query_flights | · | Return (flights, matched_total, world_total). Optional class filter. |
| 1949 | search_flights | · | Free-text search over the world snapshot. |
| 1999 | rate_ok | · | Token bucket, one bucket per client address. |
| 3537 | _build_hud | · | — |
| 4238 | _render | · | Single-pass %TOKEN% substitution. |
| 4254 | _js_literal | · | Make already-serialised JSON safe to paste inside an inline <script>. |
| 4264 | _js | · | `value` as a JS literal for an inline <script>. |
| 4269 | build_index | · | — |
| 4336 | _check | · | — |
| 4346 | run_selftest | · | — |
| 4621 | _collect_functions | · | (line, qualified name, first docstring line) for one module. |
| 4648 | _tested_names | · | Every bare identifier that appears anywhere under tests/. |
| 4662 | _favicon_credit_html | · | Attribution for the site icon. |
| 4688 | _build_reference | · | Render the whole-project function reference as HTML. |
| 5638 | _build_openapi | · | — |
| 5969 | _count | · | — |
| 5979 | _etag | · | Strong ETag for a body that never changes while the process lives. |
| 6003 | _gzippable | · | — |
| 6010 | _log_safe | · | Make a client-supplied string safe to write into the log. |
| 6020 | _gz | · | — |
| 6056 | _metric | · | One metric in the Prometheus text exposition format. |
| 6063 | render_metrics | · | Prometheus scrape of the counters this process already keeps. |
| 6179 | Handler | · | — |
| 6189 | Handler.version_string | · | — |
| 6196 | Handler.log_message | · | — |
| 6203 | Handler._client_ip | · | The address the rate limiter buckets on. |
| 6235 | Handler._accepts_gzip | · | Whether the client asked for gzip, honouring an explicit `q=0` veto. |
| 6254 | Handler._send | · | Write one response. |
| 6317 | Handler._json | · | — |
| 6321 | Handler.do_HEAD | · | — |
| 6324 | Handler.do_GET | · | — |
| 6339 | Handler._route | · | — |
| 6463 | Handler._serve_static | · | — |
| 6479 | Handler._serve_flag | · | — |
| 6492 | Handler._serve_photo | · | — |
| 6504 | Handler._meta | · | — |
| 6530 | Handler._api_log | · | — |
| 6549 | Handler._api_search | · | — |
| 6576 | Handler._api_track | · | 24-hour coordinate history: ?id=<fr24 leg id> or ?reg=<registration>. |
| 6607 | Handler._api_fleet_classes | · | Class rollup for airframes with a logged 24-hour position history. |
| 6616 | Handler._api_fleet_aircraft | · | Airframes in one class that have >= 2 logged positions (last 24 h). |
| 6636 | Handler._api_airports | · | — |
| 6659 | Handler._api_snapshot | · | The entire world, uncapped — what a replica follows. |
| 6687 | Handler._api_flights | · | — |
| 6725 | parse_bbox | · | — |
| 6741 | Server | · | — |
| 6746 | Server.handle_error | · | A client dropping a connection is not a server error. |
| 6763 | drain_writers | · | Give the DB and tracking writers a moment to flush before we exit. |
| 6783 | main | · | — |
tracking/config.py · 3 ta
Chuqur tarix: sozlama
| qator | nomi | test | vazifasi |
|---|---|---|---|
| 9 | _env_int | · | — |
| 17 | TrackingConfig | · | Everything the tracking package needs to talk to PostgreSQL. |
| 44 | TrackingConfig.from_env | · | Build a config from ``TRACKING_*`` env vars. |
tracking/db.py · 20 ta
Chuqur tarix: ulanish hovuzi va so'rov yordamchilari
| qator | nomi | test | vazifasi |
|---|---|---|---|
| 39 | _Pool | · | Tiny thread-safe LIFO connection pool. |
| 55 | _Pool._connect | · | — |
| 62 | _Pool.lease | · | — |
| 101 | _Pool.closeall | · | — |
| 111 | _batched | · | — |
| 117 | _split_values_query | · | Split a ``... VALUES %s ...`` template around its single placeholder. |
| 125 | _values_clause | · | — |
| 130 | Database | · | Connection pool + query helpers for the tracking store. |
| 144 | Database.close | · | Close every pooled connection. |
| 149 | Database.connection | · | Lease a connection; commit on success, roll back on error. |
| 161 | Database.autocommit | · | Yield a connection in autocommit mode (VACUUM, CREATE DATABASE …). |
| 171 | Database._retry | · | Run ``fn`` with exponential-backoff retries on transient failures. |
| 188 | Database.execute | · | Run a statement; return the affected row count. |
| 197 | Database.query | · | Run a SELECT (or ``SELECT some_function(...)``); return rows as dicts. |
| 212 | Database.query_one | · | Run a SELECT; return the first row as a dict, or ``None``. |
| 219 | Database.scalar | · | Run a SELECT (or function call); return column one of row one. |
| 235 | Database.insert_returning | · | Batched ``INSERT ... VALUES %s ... RETURNING`` in pages. |
| 261 | Database.copy_values | · | Batched ``INSERT ... VALUES %s ...`` (no RETURNING). Returns rows written. |
| 286 | Database.execute_batch | · | Batched write via ``cursor.executemany`` (no RETURNING). |
| 307 | Database.run_script | · | Execute a whole ``.sql`` file in one transaction. |
tracking/models.py · 10 ta
Chuqur tarix: yozuv tiplari va validatsiya
| qator | nomi | test | vazifasi |
|---|---|---|---|
| 25 | derive_aircraft_type | · | Fold the webapp class + type code into the schema's aircraft_type enum. |
| 45 | _clean | · | — |
| 49 | _int_or_none | · | — |
| 59 | AircraftRecord | · | One airframe. Identified by registration when present, else icao_hex. |
| 73 | AircraftRecord.natural_key | · | ('reg', 'UK12345') or ('hex', '424242') — the ON CONFLICT arbiter. |
| 82 | FlightRecord | · | One FlightRadar24 flight leg. |
| 102 | PositionRecord | · | One trajectory sample. |
| 117 | ValidationError | · | A snapshot row that cannot be turned into records. |
| 121 | _valid_latlon | · | — |
| 133 | parse_snapshot_flight | · | Turn one webapp flight dict into (aircraft, flight, position) records. |
tracking/ingest.py · 10 ta
Chuqur tarix: suratni bazaga yozish
| qator | nomi | test | vazifasi |
|---|---|---|---|
| 36 | IngestStats | · | What :func:`ingest_snapshot` did. |
| 47 | IngestStats.as_dict | · | — |
| 132 | _seen_at | · | — |
| 140 | ensure_partitions_for | · | Create the monthly ``flight_positions`` partitions covering ``moments``. |
| 153 | ingest_snapshot | · | Persist one FR24 world snapshot. Returns an :class:`IngestStats`. |
| 193 | _upsert_aircraft | · | — |
| 214 | _upsert_flights | · | — |
| 242 | _position_rows | · | — |
| 258 | _insert_positions | · | — |
| 276 | _enqueue_summaries | · | — |
tracking/aggregate.py · 8 ta
Chuqur tarix: kunlik/haftalik/oylik yig'malar
| qator | nomi | test | vazifasi |
|---|---|---|---|
| 21 | _ids_param | · | — |
| 25 | refresh_daily | · | Recompute ``daily_flight_summary`` for ``day``. Returns rows written. |
| 32 | refresh_weekly | · | Recompute ``weekly_flight_summary`` for the week containing ``week_start``. |
| 39 | refresh_monthly | · | Recompute ``monthly_flight_summary`` for ``year_month`` ('YYYY-MM'). |
| 46 | process_summary_queue | · | Drain the dirty queue written by the ``flight_positions`` trigger. |
| 58 | run_rollups | · | Full rollup pass — safe to run hourly or nightly from cron. |
| 89 | daily_summary_frame | · | Return ``daily_flight_summary`` rows in ``[start, end]`` as a DataFrame. |
| 106 | fleet_activity_frame | · | One row per airframe active on ``day`` — handy for notebooks/plots. |
tracking/maintenance.py · 7 ta
Chuqur tarix: partisiya, arxiv, VACUUM
| qator | nomi | test | vazifasi |
|---|---|---|---|
| 29 | _month_floor | · | — |
| 33 | _add_months | · | — |
| 38 | ensure_partitions | · | Create every monthly ``flight_positions`` partition in the working window. |
| 58 | archive_old | · | Detach position partitions (and copy flight legs) older than the window. |
| 74 | drop_archived_before | · | Permanently drop archived partitions whose range ends before ``cutoff``. |
| 94 | vacuum_analyze | · | ``VACUUM (ANALYZE)`` the core tables plus every live position partition. |
| 115 | full_maintenance | · | Everything a nightly cron should do: partitions, archive, queue, vacuum. |
tracking/queries.py · 6 ta
Chuqur tarix: tayyor tahliliy so'rovlar
| qator | nomi | test | vazifasi |
|---|---|---|---|
| 17 | resolve_aircraft_id | · | Look up an aircraft_id from an id, a registration, or an icao_hex. |
| 34 | aircraft_track_last_24h | · | Every trajectory point for one airframe in the last 24 hours, oldest first. |
| 55 | aircraft_stats_last_7d | · | Rolled-up 7-day activity for one airframe (from ``daily_flight_summary``). |
| 82 | aircraft_stats_last_30d | · | Rolled-up 30-day activity for one airframe. |
| 109 | military_activity_today | · | Every military airframe with a flight leg today, busiest first. |
| 134 | top_busiest_aircraft | · | Top N airframes by flight count over the last ``days`` days. |
tracking/reference.py · 1 ta
Chuqur tarix: aeroport ma'lumotnomasi
| qator | nomi | test | vazifasi |
|---|---|---|---|
| 32 | load_airports | · | Load / refresh ``airports_ref``. Returns the number of rows upserted. |
tracking/cli.py · 12 ta
Chuqur tarix: buyruq qatori
| qator | nomi | test | vazifasi |
|---|---|---|---|
| 35 | _json_default | · | — |
| 41 | _print | · | — |
| 47 | cmd_init | · | — |
| 55 | cmd_load_airports | · | — |
| 63 | cmd_ingest | · | — |
| 111 | cmd_rollup | · | — |
| 116 | cmd_partitions | · | — |
| 122 | cmd_archive | · | — |
| 127 | cmd_maintain | · | — |
| 132 | cmd_query | · | — |
| 162 | build_parser | · | — |
| 210 | main | · | — |
17. Belgi va manbalar
Sayt belgisi — Airbus A330 suratining qirqimi (A333 turi). Muallif: 4300streetcar, litsenziya: CC BY 4.0.
To‘liq ro‘yxat: README.md §14, har fayl bo‘yicha
aircraft_photos/credits.json, litsenziyalar
aircraft_photos/LICENSE va flags/LICENSE da.