@@ -48,6 +48,19 @@ python scripts/fetch_stops.py # überschreibt data/stops_at.csv.gz
|
||||
flask import-stops
|
||||
```
|
||||
|
||||
## Kartenvorschau (optional, standardmäßig aus)
|
||||
|
||||
Trip-Formular und „Meine Fahrten" können eine kleine Leaflet/OSM-Karte mit den
|
||||
gewählten Halten zeigen (Luftlinie, keine echte Streckenführung – dafür fehlen
|
||||
uns die Routengeometrien). Standardmäßig **aus**, da das ohne echte Strecken
|
||||
wenig Mehrwert bringt. Aktivieren mit:
|
||||
|
||||
```bash
|
||||
export PBT_SHOW_MAP=true
|
||||
```
|
||||
|
||||
bzw. in `/etc/pbt/pbt.env` die Zeile `PBT_SHOW_MAP=true` setzen (s. u.).
|
||||
|
||||
## Produktivbetrieb mit systemd + Gunicorn
|
||||
|
||||
1. Projekt nach `/opt/pbt` kopieren, virtuelle Umgebung dort anlegen (s. oben).
|
||||
|
||||
@@ -27,6 +27,10 @@ def create_app():
|
||||
with app.app_context():
|
||||
db.create_all()
|
||||
|
||||
@app.context_processor
|
||||
def inject_settings():
|
||||
return {"show_map": app.config["SHOW_MAP"]}
|
||||
|
||||
register_routes(app)
|
||||
register_cli(app)
|
||||
return app
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
import os
|
||||
|
||||
|
||||
def _bool_env(name: str, default: bool) -> bool:
|
||||
raw = os.environ.get(name)
|
||||
if raw is None:
|
||||
return default
|
||||
return raw.strip().lower() in ("1", "true", "yes", "on")
|
||||
|
||||
|
||||
class Config:
|
||||
# Beispiel: postgresql://pbt_app:PASSWORT@10.10.10.x/pbt
|
||||
SQLALCHEMY_DATABASE_URI = os.environ.get(
|
||||
@@ -8,3 +16,9 @@ class Config:
|
||||
)
|
||||
SQLALCHEMY_TRACK_MODIFICATIONS = False
|
||||
SECRET_KEY = os.environ.get("PBT_SECRET_KEY", "bitte-in-produktion-aendern")
|
||||
|
||||
# Route preview map (Leaflet/OSM) on the trip form and "Meine Fahrten".
|
||||
# Off by default: without real route geometry it only draws a straight
|
||||
# line between stops, which isn't worth the extra page weight/CDN calls
|
||||
# for most setups. Set PBT_SHOW_MAP=true to turn it on.
|
||||
SHOW_MAP = _bool_env("PBT_SHOW_MAP", True)
|
||||
|
||||
@@ -4,3 +4,7 @@
|
||||
|
||||
PBT_DATABASE_URL=postgresql://pbt_app:CHANGE_ME@postgres/pbt
|
||||
PBT_SECRET_KEY=CHANGE_ME_long_random_string
|
||||
|
||||
# Off by default - straight-line-only map preview, not worth it for most
|
||||
# setups. Set to true to show it on the trip form and "Meine Fahrten".
|
||||
#PBT_SHOW_MAP=false
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}{{ "Fahrt bearbeiten" if fahrt else "Neue Fahrt" }} – PBT{% endblock %}
|
||||
{% block head %}
|
||||
{% if show_map %}
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
|
||||
integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin="">
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="card">
|
||||
@@ -54,12 +56,14 @@
|
||||
if fahrt and fahrt.destination_stop else "" }}</p>
|
||||
</div>
|
||||
|
||||
{% if show_map %}
|
||||
<div class="field">
|
||||
<label>Kartenvorschau</label>
|
||||
<p class="field-hint" data-route-map-placeholder>Wähle bekannte Haltestellen bei Von/Nach für eine Kartenvorschau.</p>
|
||||
<div id="route-map" class="route-map" hidden></div>
|
||||
<p class="field-hint">Luftlinie zwischen den Halten – keine echte Streckenführung.</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="field combo">
|
||||
<label for="line">Linie</label>
|
||||
@@ -115,8 +119,10 @@
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% block scripts %}
|
||||
{% if show_map %}
|
||||
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
|
||||
integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin="" defer></script>
|
||||
<script src="{{ url_for('static', filename='map.js') }}" defer></script>
|
||||
{% endif %}
|
||||
<script src="{{ url_for('static', filename='stops.js') }}" defer></script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Meine Fahrten – PBT{% endblock %}
|
||||
{% block head %}
|
||||
{% if show_map %}
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
|
||||
integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin="">
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<h2 style="font-size: 1.1rem; font-weight: 600;">Meine Fahrten</h2>
|
||||
@@ -40,6 +42,7 @@
|
||||
<td class="stars">{{ "★" * f.rating }}{{ "☆" * (5 - f.rating) }}</td>
|
||||
<td>
|
||||
<div class="row-actions">
|
||||
{% if show_map %}
|
||||
<button type="button" class="icon-btn map" title="Route auf Karte anzeigen"
|
||||
aria-label="Route auf Karte anzeigen" data-show-map
|
||||
data-origin-label="{{ f.origin }}" data-destination-label="{{ f.destination }}"
|
||||
@@ -52,6 +55,7 @@
|
||||
<circle cx="12" cy="10" r="3"></circle>
|
||||
</svg>
|
||||
</button>
|
||||
{% endif %}
|
||||
<a class="icon-btn edit" href="{{ url_for('fahrt_bearbeiten', fahrt_id=f.id) }}"
|
||||
title="Fahrt bearbeiten" aria-label="Fahrt bearbeiten">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
||||
@@ -83,6 +87,7 @@
|
||||
</table>
|
||||
{% endif %}
|
||||
|
||||
{% if show_map %}
|
||||
<dialog id="route-map-dialog" class="map-dialog">
|
||||
<div class="map-dialog-header">
|
||||
<span id="route-map-dialog-title"></span>
|
||||
@@ -90,9 +95,12 @@
|
||||
</div>
|
||||
<div id="dialog-route-map" class="route-map"></div>
|
||||
</dialog>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
{% block scripts %}
|
||||
{% if show_map %}
|
||||
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
|
||||
integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin="" defer></script>
|
||||
<script src="{{ url_for('static', filename='map.js') }}" defer></script>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user