chore: cleanup - remove CGI/old scripts/TASK/copilot files; update README + in-app docs
Some checks failed
Build & Push Docker / build (push) Has been cancelled
Some checks failed
Build & Push Docker / build (push) Has been cancelled
This commit is contained in:
350
README.md
350
README.md
@@ -1,258 +1,162 @@
|
||||
# Scenar Creator
|
||||
# Scenár Creator
|
||||
|
||||
> Moderní CGI aplikace pro vytváření časových plánů (timetablů) z Excelu nebo přímé editace v prohlížeči.
|
||||
Webový nástroj pro tvorbu časových scénářů zážitkových kurzů a výjezdů.
|
||||
|
||||
## Co to dělá
|
||||
**Live:** https://scenar.apps.sukany.cz
|
||||
|
||||
**Scenar Creator** je webová aplikace, která vám pomáhá vytvářet a spravovat timetably (časové plány) pro konference, školení a další akce. Aplikace podporuje:
|
||||
---
|
||||
|
||||
- ✅ **Import z Excelu** — načtení seznamu programů/přednášek a automatické vytvoření timetablu
|
||||
- ✅ **Inline editor** — přímá editace programu v prohlížeči bez Excelu (JavaScript row management)
|
||||
- ✅ **Validace dat** — kontrola překryvů, chybějících polí, neplatných časů
|
||||
- ✅ **Export do Excelu** — vygenerovaný timetable se stáhne v profesionálním formátu
|
||||
- ✅ **Barevné rozlišení** — jednotlivé typy programu s vlastními barvami
|
||||
- ✅ **Plná test coverage** — 10 testů jednotek + integrace s Docker/Podman
|
||||
## Funkce
|
||||
|
||||
## Instalace a spuštění
|
||||
- **Grafický editor** — bloky na časové ose, přetahování myší, změna délky tažením pravého okraje, snap na 15 minut
|
||||
- **Vícedenní scénář** — nastavíš rozsah Od/Do, každý den = jeden řádek
|
||||
- **JSON import/export** — uložíš scénář, kdykoli ho znovu načteš
|
||||
- **Vzorový JSON** — `GET /api/sample`
|
||||
- **PDF výstup** — A4 na šířku, vždy 1 stránka, barevné bloky dle typů, legenda
|
||||
- Garant viditelný přímo v bloku
|
||||
- Bloky s poznámkou mají horní index (¹ ² ³...)
|
||||
- Stránka 2 (pokud jsou poznámky): výpis všech poznámek ke scénáři
|
||||
- **Dokumentace na webu** — záložka "Dokumentace" přímo v aplikaci
|
||||
- **Swagger UI** — `GET /docs`
|
||||
|
||||
### Lokálně (bez Dockeru)
|
||||
---
|
||||
|
||||
1) **Klonuj a připrav prostředí:**
|
||||
## Tech stack
|
||||
|
||||
| Vrstva | Technologie |
|
||||
|---|---|
|
||||
| Backend | FastAPI + Uvicorn (Python 3.12) |
|
||||
| Frontend | Vanilla JS + [interact.js](https://interactjs.io/) (drag & drop) |
|
||||
| PDF | ReportLab Canvas API + LiberationSans (česká diakritika) |
|
||||
| Data | JSON (bez databáze, bez Excelu) |
|
||||
| Container | Docker / Podman, python:3.12-slim |
|
||||
| Deployment | Kubernetes (RKE2), namespace `scenar` |
|
||||
|
||||
---
|
||||
|
||||
## Rychlý start (lokální vývoj)
|
||||
|
||||
```bash
|
||||
git clone <repo>
|
||||
# Klonování
|
||||
git clone https://git.apps.sukany.cz/martin/scenar-creator.git
|
||||
cd scenar-creator
|
||||
python -m venv .venv
|
||||
source .venv/bin/activate # na Windows: .venv\Scripts\activate
|
||||
|
||||
# Virtuální prostředí
|
||||
python3 -m venv .venv && source .venv/bin/activate
|
||||
pip install -r requirements.txt
|
||||
|
||||
# Spuštění
|
||||
uvicorn app.main:app --reload --port 8080
|
||||
|
||||
# Otevři v prohlížeči
|
||||
open http://localhost:8080
|
||||
```
|
||||
|
||||
2) **Spusť s jednoduchým CGI serverem:**
|
||||
---
|
||||
|
||||
## Testy
|
||||
|
||||
```bash
|
||||
python -m http.server --cgi 8000
|
||||
# Otevři v prohlížeči: http://localhost:8000/cgi-bin/scenar.py
|
||||
python3 -m pytest tests/ -v
|
||||
```
|
||||
|
||||
3) **Spusť testy:**
|
||||
35 testů pokrývá API endpointy, PDF generátor a validaci dat.
|
||||
|
||||
---
|
||||
|
||||
## Build a deploy
|
||||
|
||||
### Manuální postup
|
||||
|
||||
```bash
|
||||
pytest -q
|
||||
# Bez integračních testů (Docker):
|
||||
pytest -q -m "not integration"
|
||||
# 1. Build image
|
||||
podman build --format docker -t git.apps.sukany.cz/martin/scenar-creator:latest .
|
||||
|
||||
# 2. Push do Gitea registry
|
||||
podman login git.apps.sukany.cz -u <user>
|
||||
podman push git.apps.sukany.cz/martin/scenar-creator:latest
|
||||
|
||||
# 3. Restart deploymentu na clusteru
|
||||
ssh root@infra01.sukany.cz \
|
||||
"kubectl -n scenar rollout restart deployment/scenar && \
|
||||
kubectl -n scenar rollout status deployment/scenar"
|
||||
|
||||
# 4. Ověření
|
||||
curl https://scenar.apps.sukany.cz/api/health
|
||||
```
|
||||
|
||||
### Podman/Docker (produkční)
|
||||
### Automatický build (Gitea CI/CD)
|
||||
|
||||
1) **Postav image:**
|
||||
Push na `main` spustí `.gitea/workflows/build-and-push.yaml`, který automaticky builduje a pushuje image do Gitea registry.
|
||||
Deployment na cluster je stále manuální (rollout restart).
|
||||
|
||||
```bash
|
||||
./scripts/build_image.sh
|
||||
# nebo ručně:
|
||||
podman build -t scenar-creator:latest .
|
||||
Kubernetes manifest: `sukany-org/rke2-deployments` → `scenar/scenar.yaml`
|
||||
|
||||
---
|
||||
|
||||
## Formát JSON
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "1.0",
|
||||
"event": {
|
||||
"title": "Název akce",
|
||||
"subtitle": "Volitelný podtitul",
|
||||
"date_from": "YYYY-MM-DD",
|
||||
"date_to": "YYYY-MM-DD",
|
||||
"location": "Místo konání"
|
||||
},
|
||||
"program_types": [
|
||||
{ "id": "main", "name": "Hlavní program", "color": "#3B82F6" }
|
||||
],
|
||||
"blocks": [
|
||||
{
|
||||
"id": "b1",
|
||||
"date": "YYYY-MM-DD",
|
||||
"start": "HH:MM",
|
||||
"end": "HH:MM",
|
||||
"title": "Název bloku",
|
||||
"type_id": "main",
|
||||
"responsible": "Garant (volitelné)",
|
||||
"notes": "Poznámka → horní index v PDF (volitelné)"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
2) **Spusť kontejner:**
|
||||
**Overnight bloky:** `end < start` → blok přechází přes půlnoc (validní).
|
||||
|
||||
```bash
|
||||
./scripts/start_scenar.sh
|
||||
# Aplikace bude dostupná na http://127.0.0.1:8080/
|
||||
```
|
||||
**Zpětná kompatibilita:** pole `date` (jednodnevní starý formát) je stále akceptováno.
|
||||
|
||||
3) **Zastavit kontejner:**
|
||||
---
|
||||
|
||||
```bash
|
||||
./scripts/stop_scenar.sh
|
||||
```
|
||||
## API endpointy
|
||||
|
||||
## Git Hooks (pre-commit)
|
||||
| Metoda | URL | Popis |
|
||||
|---|---|---|
|
||||
| GET | `/` | Hlavní UI |
|
||||
| GET | `/api/health` | Health check (verze) |
|
||||
| GET | `/api/sample` | Vzorový JSON ke stažení |
|
||||
| POST | `/api/validate` | Validace ScenarioDocument |
|
||||
| POST | `/api/generate-pdf` | Generování PDF |
|
||||
| GET | `/docs` | Swagger UI |
|
||||
|
||||
Aplikace obsahuje git hooks, které spouští testy před commitem.
|
||||
|
||||
**Jednorazová instalace hooků:**
|
||||
|
||||
```bash
|
||||
chmod +x scripts/install_hooks.sh
|
||||
./scripts/install_hooks.sh
|
||||
# nebo ručně:
|
||||
git config core.hooksPath .githooks
|
||||
```
|
||||
|
||||
**Použití:**
|
||||
|
||||
- Běžný commit — spustí se rychlé testy (bez Dockeru):
|
||||
```bash
|
||||
git commit -m "..." # Spustí: pytest -q -m "not integration"
|
||||
```
|
||||
|
||||
- Commit s integračními testy (Podman):
|
||||
```bash
|
||||
RUN_INTEGRATION=1 git commit -m "..."
|
||||
```
|
||||
|
||||
## Workflow — Jak používat aplikaci
|
||||
|
||||
### 1️⃣ Import z Excelu (klasicky)
|
||||
|
||||
```
|
||||
1. Otevři http://localhost:8000/cgi-bin/scenar.py
|
||||
2. Klikni na tab "Importovat Excel"
|
||||
3. Stáhni šablonu (scenar_template.xlsx)
|
||||
4. Vyplň tabulku:
|
||||
- Datum (YYYY-MM-DD)
|
||||
- Začátek (HH:MM)
|
||||
- Konec (HH:MM)
|
||||
- Program (název přednášky)
|
||||
- Typ (kategorie: WORKSHOP, LECTURE, atd.)
|
||||
- Garant (vedoucí, autor)
|
||||
- Poznámka (dodatečné info)
|
||||
5. Uploaduj soubor
|
||||
6. Zadej popis typů a barvy
|
||||
7. Stáhni Excel timetable
|
||||
```
|
||||
|
||||
### 2️⃣ Inline Editor (bez Excelu)
|
||||
|
||||
```
|
||||
1. Otevři http://localhost:8000/cgi-bin/scenar.py
|
||||
2. Klikni na tab "Vytvořit inline"
|
||||
3. Vyplň název a detail akce
|
||||
4. V tabulce "Program (řádky)":
|
||||
- Přidej řádky tlačítkem "+ Přidat řádek"
|
||||
- Vyplň Datum, Začátek, Konec, Program, Typ, Garant, Poznámka
|
||||
- Smažování řádku: klikni "Smazat"
|
||||
5. V sekci "Typy programu":
|
||||
- Přidej typy tlačítkem "+ Přidat typ"
|
||||
- Vyplň název typu, popis a zvolíkona barvu
|
||||
- Barvy se aplikují na timetable
|
||||
6. Generuj scénář a stáhni Excel
|
||||
```
|
||||
|
||||
## Workflow — Jak používat aplikaci
|
||||
|
||||
### Import z Excelu (nejčastěji)
|
||||
|
||||
```
|
||||
1. Otevři http://localhost:8000/cgi-bin/scenar.py
|
||||
2. Stáhni šablonu (scenar_template.xlsx)
|
||||
3. Vyplň tabulku:
|
||||
- Datum: 2025-11-14
|
||||
- Začátek: 09:00
|
||||
- Konec: 10:00
|
||||
- Program: Úvodní přednáška
|
||||
- Typ: PŘEDNÁŠKA
|
||||
- Garant: Jméno lektora
|
||||
- Poznámka: Volitelně
|
||||
4. Nahraj upravený Excel
|
||||
5. Vyplň název a detail akce
|
||||
6. Přiřaď barvy jednotlivým typům programu
|
||||
7. Stáhni vygenerovaný timetable (Excel)
|
||||
```
|
||||
---
|
||||
|
||||
## Struktura projektu
|
||||
|
||||
```
|
||||
.
|
||||
├── .github/copilot-instructions.md # AI instrukce pro agenty
|
||||
├── .githooks/
|
||||
│ └── pre-commit # Git hook se spuštěním testů
|
||||
├── cgi-bin/
|
||||
│ └── scenar.py # Hlavní CGI aplikace (UI)
|
||||
├── scenar/
|
||||
│ ├── __init__.py
|
||||
│ └── core.py # Jádro logiky (bez CGI)
|
||||
├── scripts/
|
||||
│ ├── build_image.sh # Postav Podman image
|
||||
│ ├── start_scenar.sh # Spusť kontejner
|
||||
│ ├── stop_scenar.sh # Zastavit kontejner
|
||||
│ └── install_hooks.sh # Instaluj git hooks
|
||||
├── templates/
|
||||
│ └── scenar_template.xlsx # Excel šablona
|
||||
├── tests/
|
||||
│ ├── test_read_excel.py # Testy parsování
|
||||
│ └── test_docker_integration.py # Docker build test
|
||||
├── tmp/ # Výstupní soubory (gitignored)
|
||||
├── Dockerfile # Runtime pro produkci
|
||||
├── requirements.txt # Python balíčky (verze)
|
||||
└── pytest.ini # Pytest konfigurace
|
||||
app/
|
||||
api/ REST endpointy (scenario.py, pdf.py, router.py)
|
||||
core/ Business logika (pdf_generator.py, validator.py)
|
||||
models/ Pydantic modely (event.py, responses.py)
|
||||
static/ Frontend (index.html, css/, js/)
|
||||
js/
|
||||
app.js State management, modal logika
|
||||
canvas.js Horizontální canvas editor (interact.js)
|
||||
api.js Fetch wrapper
|
||||
export.js JSON import/export
|
||||
tests/ 35 pytest testů
|
||||
Dockerfile python:3.12-slim + fonts-liberation
|
||||
requirements.txt
|
||||
```
|
||||
|
||||
## Architektura
|
||||
|
||||
### Core logika (`scenar/core.py`)
|
||||
|
||||
Obsahuje importovatelné funkce bez CGI závislostí:
|
||||
|
||||
- `read_excel(file_content)` — Parsování Excelu (pandas), detekce překryvů, validace
|
||||
- `create_timetable(...)` — Tvorba OpenPyXL sešitu s timetablem
|
||||
- `validate_inputs(title, detail, file_size)` — Bezpečnostní validace vstupů
|
||||
|
||||
Chybové typy:
|
||||
- `ScenarsError` — obecná chyba
|
||||
- `ValidationError` — vstupní validace
|
||||
- `TemplateError` — problém s Excel šablonou
|
||||
|
||||
### CGI wrapper (`cgi-bin/scenar.py`)
|
||||
|
||||
Komunikace s webem:
|
||||
|
||||
- `step=1`: Domovská stránka s formulářem
|
||||
- `step=2`: Načtení Excelu, extrakce typů
|
||||
- `step=3`: Generování timetablu a stažení
|
||||
|
||||
### Podman/Docker
|
||||
|
||||
- **Obraz:** Python 3.12-slim + Apache2 + CGI
|
||||
- **Port:** 8080
|
||||
- **DocumentRoot:** `/var/www/htdocs`
|
||||
|
||||
## Vývoj
|
||||
|
||||
### Editace
|
||||
|
||||
- UI formuláře (HTML): `cgi-bin/scenar.py`
|
||||
- Logika (bez CGI): `scenar/core.py`
|
||||
- Šablona: `templates/scenar_template.xlsx`
|
||||
|
||||
### Konvence
|
||||
|
||||
- Časy: `%H:%M` nebo `%H:%M:%S`
|
||||
- Excel sloupce: `Datum, Zacatek, Konec, Program, Typ, Garant, Poznamka`
|
||||
- Barvy: CSS hex → OpenPyXL AARRGGBB
|
||||
- Bezpečnost: všechny vstupy validovány a escaped
|
||||
|
||||
## Testování
|
||||
|
||||
```bash
|
||||
# Unit testy
|
||||
pytest tests/test_read_excel.py -v
|
||||
|
||||
# Integrační (Podman build):
|
||||
pytest tests/test_docker_integration.py -v
|
||||
|
||||
# Všechno:
|
||||
pytest -v
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**Podman machine (macOS):**
|
||||
```bash
|
||||
podman machine start
|
||||
```
|
||||
|
||||
**ImportError scenar.core:**
|
||||
```bash
|
||||
export PYTHONPATH="/path/to/repo:$PYTHONPATH"
|
||||
```
|
||||
|
||||
**Testy selhávají:**
|
||||
```bash
|
||||
source .venv/bin/activate
|
||||
pip install -r requirements.txt
|
||||
pytest -q
|
||||
```
|
||||
|
||||
## Kontakt
|
||||
|
||||
Autor: **Martin Sukaný** — martin@sukany.cz
|
||||
|
||||
Reference in New Issue
Block a user