Update projektu

This commit is contained in:
lachtan
2026-07-22 12:32:02 +02:00
parent 19014ed3d9
commit 8e66d6b92a
22 changed files with 1995 additions and 503 deletions

View File

@@ -0,0 +1,163 @@
# flight-search
Vyhledávání letenek přes KAYAK s ukládáním výsledků do SQLite.
## Kdy aktivovat
- "hledej letenky", "flight search", "letenky do X", "vyhledej let", "letenky PRG→PTY"
- Když uživatel zadá trasu, datumy a počet osob
## Přehled
Skill orchestruje hledání letenek:
1. Vytvoří definici hledání v DB přes CLI skript
2. Fetchnout KAYAK URL přes `web_fetch`
3. Parsuje výsledky z markdown
4. Uloží nalezené lety do DB
5. Prezentuje top výsledky uživateli
## Postup
### 1. Získat parametry od uživatele
Vyžadované:
- **origin** — IATA kód (např. PRG)
- **destination** — IATA kód (např. PTY)
- **dep_date** — datum odletu (YYYY-MM-DD)
- **ret_date** — datum návratu (YYYY-MM-DD)
- **adults** — počet dospělých (default 1)
Volitelné:
- **flex_days** — ±dny pro flexibilní hledání (default 0, max 3)
- **min_stay_days** — minimální doba pobytu v destinaci (default 1)
- **max_layovers** — max přestupy (default 1, pevně nastaveno)
- **currency** — CZK (default)
### 2. Vytvořit hledání
```bash
uv run skills/flight-search/scripts/flight_search.py create-search \
--origin PRG --destination PTY \
--dep-date 2026-12-21 --ret-date 2027-01-04 \
--adults 3 --flex-days 3 --min-stay-days 14 --max-layovers 1
```
Vrátí JSON s `search_id` a seznamem `urls`.
### 3. Fetch KAYAK stránky
Pro každou URL z `urls` použij `web_fetch` s `extractMode="text"`.
**Důležité**: Používej **cz.kayak.com** doménu (české UI, ceny v CZK). URL formát:
```
https://www.cz.kayak.com/flights/{origin}-{destination}/{dep}/{ret}/{adults}adults?sort=price_a&fs=stops=-2
```
KAYAK URL parametry:
- `sort=price_a` — seřadit podle ceny vzestupně
- `fs=stops=-2` — max 1 přestup (KAYAK počítá "additional stops", -2 = max 1)
- `curr=CZK` — ceny v CZK (na cz.kayak.com je CZK default)
### 4. Parsování výsledků
KAYAK vrací markdown s lety. Hledej vzory:
**Cena** (na cz.kayak.com v CZK):
- `34 484 Kč` nebo `32 232 Kč/osobu` nebo `Celkem 96 695 Kč`
- Pozor: mezera jako oddělovač tisíců, ne čárka
**Aerolinka**:
- `Air France`, `KLM`, `Turkish Airlines`, `SWISS`, `Copa Airlines`, `United Airlines`, atd.
- Může být kombinace: `KLM, Air France`
**Trasa a přestupy**:
- `1 přest.` nebo `2 přest.`
- `CDG Mezipřistání 3hod 05min, Paříž Letiště Charlese de Gaulla`
- `AMS Mezipřistání 16hod 55min, Amsterdam Letiště Schiphol`
**Časy**:
- Odlet: `09:50 20:20` nebo `09:50`
- Přílet: `20:20` nebo `20:20+1` (+1 = další den)
- Doba letu: `16hod 30min` nebo `16h 30m`
**Typický blok výsledku** (cz.kayak.com s fs=stops=-2):
```
1. 09:50 20:20
PRG Letiště Václav Havel - PTY Tocumen Intl 1 přest.
CDG Mezipřistání 3hod 05min, Paříž Letiště Charlese de Gaulla 16hod 30min
2. 22:30 22:40+1
PTY Tocumen Intl - PRG Letiště Václav Havel 1 přest.
CDG Mezipřistání 6hod 25min, Paříž Letiště Charlese de Gaulla 18hod 10min
Air France
1
0
34 484 Kč
/osobu
Celkem 103 452 Kč
Light
```
### 5. Uložit výsledky
Pro každý nalezený let:
```bash
uv run skills/flight-search/scripts/flight_search.py add-result \
--search-id <ID> \
--airline "Air France" \
--route "PRG→CDG→PTY / PTY→CDG→PRG" \
--dep-date 2026-12-21 --ret-date 2027-01-04 \
--dep-time "09:50" --arr-time "20:20" \
--layovers 1 --layover-info "CDG 3h05m" \
--duration "16h30m" \
--price 34484 --price-czk 34484
```
Nebo batch přes stdin:
```bash
echo '[{"search_id":1,"airline":"Air France",...}]' | \
uv run skills/flight-search/scripts/flight_search.py add-results
```
### 6. Prezentovat výsledky
```bash
uv run skills/flight-search/scripts/flight_search.py results <search_id> --top 5
```
Výstup formátuj pro uživatele v češtině s přehlednou tabulkou.
### 7. Historie a správa
```bash
# Seznam hledání
uv run skills/flight-search/scripts/flight_search.py list-searches
# Smazat hledání
uv run skills/flight-search/scripts/flight_search.py delete-search <id>
```
## Poznámky k parsování
- KAYAK stránka může obsahovat reklamy (JustFly, Expedia, FlightHub) — ignoruj
- Některé výsledky mají "Vlastní transfer" (self-transfer) — označ, ale nefiltruj
- Ceny jsou per osoba, celková cena je vždy uvedena jako "Celkem X Kč"
- Na cz.kayak.com jsou ceny automaticky v CZK
- Pokud web_fetch selže nebo vrátí jen navigaci bez výsledků, informuj uživatele a navrhni manuální kontrolu na KAYAKu
- KAYAK může vyžadovat více fetchů pro flex data — každá URL je jedna kombinace datumů
## CLI reference
| Příkaz | Popis |
|--------|-------|
| `create-search` | Vytvoří hledání, vrátí search_id + URL |
| `add-result` | Přidá jeden výsledek |
| `add-results` | Přidá víc výsledků z JSON (stdin nebo --json-file) |
| `results <id>` | Top N výsledků seřazených podle ceny |
| `list-searches` | Seznam všech hledání |
| `delete-search <id>` | Smaže hledání + výsledky |
## DB
Auto-vytvořeno v `db/flight_search.sqlite`. Tabulky:
- `searches` — definice hledání (trasa, datumy, flex, osoby)
- `results` — nalezené lety (aerolinka, trasa, časy, cena, přestupy)