modified: app.py
modified: static/css/style.css modified: templates/base.html modified: templates/index.html modified: templates/weather.html new file: translations.py
This commit is contained in:
@@ -23,7 +23,7 @@
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/></svg>
|
||||
{{ display_name.split(',')[0] }}
|
||||
<span class="hero-meta-sub">{{ display_name.split(',')[1:3]|join(',') if ',' in display_name else '' }}</span>
|
||||
<span class="hero-meta-time" id="hero-time">{{ now_local }} Uhr</span>
|
||||
<span class="hero-meta-time" id="hero-time">{{ now_local }}{% if T.clock_suffix %} {{ T.clock_suffix }}{% endif %}</span>
|
||||
</div>
|
||||
|
||||
<div class="hero-main">
|
||||
@@ -39,7 +39,7 @@
|
||||
<span>{{ current.wind_kmh }} km/h {{ wind_dir_name(current.wind_dir) }}</span>
|
||||
{% endif %}
|
||||
{% if current.cloud_pct is not none %}
|
||||
<span>{{ current.cloud_pct }}% Bedeckung</span>
|
||||
<span>{{ current.cloud_pct }}% {{ T.cloud_cover }}</span>
|
||||
{% endif %}
|
||||
{% if current.pressure_hpa is not none %}
|
||||
<span>{{ current.pressure_hpa }} hPa</span>
|
||||
@@ -56,11 +56,11 @@
|
||||
{% set uv_curr_str = "–" %}
|
||||
{% endif %}
|
||||
{% set items = [
|
||||
("Gefühlt wie", (current.feels_like|string + " °C") if current.feels_like is not none else "–"),
|
||||
("Böen", (current.gust_kmh|string + " km/h") if current.gust_kmh is not none else "–"),
|
||||
("Niederschlag", (current.precip_mm|string + " mm") if (current.precip_mm is not none and current.precip_mm > 0) else ((current.rain_prob|string + " %") if (current.rain_prob is not none and current.rain_prob > 0) else "0 mm")),
|
||||
("Sonne", (current.sun_min|string + " min/h") if (current.sun_min is not none and current.sun_min > 0) else "–"),
|
||||
("UV-Index", uv_curr_str),
|
||||
(T.feels_like, (current.feels_like|string + " °C") if current.feels_like is not none else "–"),
|
||||
(T.gusts, (current.gust_kmh|string + " km/h") if current.gust_kmh is not none else "–"),
|
||||
(T.precipitation, (current.precip_mm|string + " mm") if (current.precip_mm is not none and current.precip_mm > 0) else ((current.rain_prob|string + " %") if (current.rain_prob is not none and current.rain_prob > 0) else "0 mm")),
|
||||
(T.sun, (current.sun_min|string + " min/h") if (current.sun_min is not none and current.sun_min > 0) else "–"),
|
||||
(T.uv_index, uv_curr_str),
|
||||
] %}
|
||||
{% for label, val in items %}
|
||||
<div class="hero-metric">
|
||||
@@ -72,7 +72,7 @@
|
||||
</div>
|
||||
|
||||
<div class="hero-station">
|
||||
📡 Station <strong>{{ station_name }}</strong> ({{ station_dist }} km)
|
||||
📡 {{ T.station }} <strong>{{ station_name }}</strong> ({{ station_dist }} km)
|
||||
{% if sunrise %}
|
||||
· 🌅 {{ sunrise }} · 🌇 {{ sunset }}
|
||||
{% endif %}
|
||||
@@ -101,7 +101,7 @@
|
||||
<p class="warn-desc">{{ short_desc }}{% if short_desc|length < w.description|length %}.{% endif %}</p>
|
||||
{% if short_desc|length < w.description|length %}
|
||||
<details class="warn-more">
|
||||
<summary>Details</summary>
|
||||
<summary>{{ T.warn_details }}</summary>
|
||||
<p>{{ w.description }}</p>
|
||||
</details>
|
||||
{% endif %}
|
||||
@@ -113,33 +113,33 @@
|
||||
{% endif %}
|
||||
|
||||
<section class="section insights">
|
||||
<h2 class="section-title">Kurzfazit</h2>
|
||||
<h2 class="section-title">{{ T.section_summary }}</h2>
|
||||
<div class="insight-grid">
|
||||
<div class="insight-card">
|
||||
<span class="insight-label">Temperaturtrend (6h)</span>
|
||||
<span class="insight-label">{{ T.temp_trend_label }}</span>
|
||||
<strong class="insight-value">
|
||||
{% if temp_delta_6h is not none %}
|
||||
{% if temp_delta_6h > 0 %}+{% endif %}{{ temp_delta_6h }}° · {{ temp_trend_6h }}
|
||||
{% if temp_delta_6h > 0 %}+{% endif %}{{ temp_delta_6h }}° · {{ T.get(temp_trend_6h, temp_trend_6h) }}
|
||||
{% else %}
|
||||
–
|
||||
{% endif %}
|
||||
</strong>
|
||||
</div>
|
||||
<div class="insight-card">
|
||||
<span class="insight-label">Drucktrend (6h)</span>
|
||||
<span class="insight-label">{{ T.pressure_trend_label }}</span>
|
||||
<strong class="insight-value">
|
||||
{% if pressure_delta is not none %}
|
||||
{% if pressure_delta > 0 %}+{% endif %}{{ pressure_delta }} hPa · {{ pressure_trend }}
|
||||
{% if pressure_delta > 0 %}+{% endif %}{{ pressure_delta }} hPa · {{ T.get(pressure_trend, pressure_trend) }}
|
||||
{% else %}
|
||||
–
|
||||
{% endif %}
|
||||
</strong>
|
||||
</div>
|
||||
<div class="insight-card">
|
||||
<span class="insight-label">Bestes Aktivitätsfenster</span>
|
||||
<span class="insight-label">{{ T.best_window_label }}</span>
|
||||
<strong class="insight-value">
|
||||
{% if best_window %}
|
||||
{{ best_window.start.strftime('%H:%M') }}–{{ best_window.end.strftime('%H:%M') }} · Score {{ best_window.score }}
|
||||
{{ best_window.start.strftime('%H:%M') }}–{{ best_window.end.strftime('%H:%M') }} · {{ T.score }} {{ best_window.score }}
|
||||
{% else %}
|
||||
–
|
||||
{% endif %}
|
||||
@@ -150,23 +150,23 @@
|
||||
|
||||
<!-- STÜNDLICH -->
|
||||
<section class="section">
|
||||
<h2 class="section-title">Stundenweise</h2>
|
||||
<h2 class="section-title">{{ T.section_hourly }}</h2>
|
||||
<div class="hourly-legend">
|
||||
<span class="hl-label">Legende:</span>
|
||||
<span class="hl-badge hl-conf hl-conf--hoch">Konfidenz hoch</span>
|
||||
<span class="hl-badge hl-conf hl-conf--mittel">mittel</span>
|
||||
<span class="hl-badge hl-conf hl-conf--niedrig">niedrig</span>
|
||||
<span class="hl-label">{{ T.legend }}</span>
|
||||
<span class="hl-badge hl-conf hl-conf--hoch">{{ T.conf_high }}</span>
|
||||
<span class="hl-badge hl-conf hl-conf--mittel">{{ T.conf_mid }}</span>
|
||||
<span class="hl-badge hl-conf hl-conf--niedrig">{{ T.conf_low }}</span>
|
||||
<span class="hl-sep">·</span>
|
||||
<span class="hl-badge hl-act">Aktivität 0–100</span>
|
||||
<span class="hl-badge hl-act">{{ T.activity_legend }}</span>
|
||||
<span class="hl-sep">·</span>
|
||||
<span class="hl-badge hl-uv">UV-Index</span>
|
||||
<span class="hl-badge hl-uv">{{ T.uv_index }}</span>
|
||||
</div>
|
||||
<div class="hourly-strip-wrap">
|
||||
<div class="hourly-strip">
|
||||
{% for h in forecast %}
|
||||
<div class="hcard {% if loop.first %}hcard--now{% endif %}">
|
||||
<div class="hcard-time">
|
||||
{% if loop.first %}Jetzt
|
||||
{% if loop.first %}{{ T.now }}
|
||||
{% elif h.datetime is string %}{{ h.datetime[11:16] }}
|
||||
{% else %}{{ h.datetime.strftime('%H:%M') }}{% endif %}
|
||||
</div>
|
||||
@@ -193,9 +193,9 @@
|
||||
<div class="hcard-wind">{{ h.wind_kmh }}<small>km/h</small></div>
|
||||
{% endif %}
|
||||
<div class="hcard-confidence hcard-confidence--{{ h.confidence_label }}">{{ h.confidence }}%</div>
|
||||
<div class="hcard-activity">Aktiv {{ h.activity_score }}</div>
|
||||
<div class="hcard-activity">{{ T.active }} {{ h.activity_score }}</div>
|
||||
{% if h.uv_index is not none and h.uv_index > 0 %}
|
||||
<div class="hcard-uv hcard-uv--{{ h.uv_level }}">UV {{ h.uv_index }} {{ h.uv_label }}</div>
|
||||
<div class="hcard-uv hcard-uv--{{ h.uv_level }}">UV {{ h.uv_index }} {{ T.get(h.uv_label, h.uv_label) }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
@@ -206,8 +206,8 @@
|
||||
<!-- CHART -->
|
||||
<section class="section">
|
||||
<div class="chart-head">
|
||||
<h2 class="section-title">Temperatur, Gefühlt & Niederschlag</h2>
|
||||
<span class="chart-range">72 Stunden</span>
|
||||
<h2 class="section-title">{{ T.section_chart }}</h2>
|
||||
<span class="chart-range">{{ T.chart_range }}</span>
|
||||
</div>
|
||||
<div class="chart-box">
|
||||
<canvas id="wxChart"></canvas>
|
||||
@@ -216,11 +216,11 @@
|
||||
|
||||
<!-- TAGESÜBERSICHT -->
|
||||
<section class="section">
|
||||
<h2 class="section-title">Tagesübersicht</h2>
|
||||
<h2 class="section-title">{{ T.section_daily }}</h2>
|
||||
<div class="daily-header">
|
||||
<span>Tag</span>
|
||||
<span>Temperaturbereich</span>
|
||||
<span>Min · Max · Nieder. · UV</span>
|
||||
<span>{{ T.daily_hdr_day }}</span>
|
||||
<span>{{ T.daily_hdr_range }}</span>
|
||||
<span>{{ T.daily_hdr_details }}</span>
|
||||
</div>
|
||||
<div class="daily-list">
|
||||
{# calc global min/max for bar scaling – do it in a loop to stay Jinja2-safe #}
|
||||
@@ -282,7 +282,7 @@
|
||||
</section>
|
||||
|
||||
<p class="data-note">
|
||||
Wetterdaten: <a href="https://opendata.dwd.de" target="_blank" rel="noopener noreferrer">Deutscher Wetterdienst – Open Data (MOSMIX)</a>
|
||||
{{ T.data_source }} <a href="https://opendata.dwd.de" target="_blank" rel="noopener noreferrer">Deutscher Wetterdienst – Open Data (MOSMIX)</a>
|
||||
</p>
|
||||
{% endblock %}
|
||||
|
||||
@@ -308,7 +308,7 @@
|
||||
// Prüfen ob echte Niederschlagsmengen vorhanden sind
|
||||
const hasRealPrecip = precip.some(v => v > 0);
|
||||
const barData = hasRealPrecip ? precip : rainProb;
|
||||
const barLabel = hasRealPrecip ? "Niederschlag (mm)" : "Regenwahrsch. (%)";
|
||||
const barLabel = hasRealPrecip ? {{ T.chart_precip | tojson }} : {{ T.chart_rainprob | tojson }};
|
||||
const barMax = hasRealPrecip ? undefined : 100;
|
||||
|
||||
// Nur jeden 3. Label anzeigen, Rest leer lassen
|
||||
@@ -327,7 +327,7 @@
|
||||
datasets: [
|
||||
{
|
||||
type: "line",
|
||||
label: "Temperatur (°C)",
|
||||
label: {{ T.chart_temp | tojson }},
|
||||
data: temps,
|
||||
borderColor: "#ff8c32",
|
||||
backgroundColor: grad,
|
||||
@@ -341,7 +341,7 @@
|
||||
},
|
||||
{
|
||||
type: "line",
|
||||
label: "Gefühlt (°C)",
|
||||
label: {{ T.chart_feels | tojson }},
|
||||
data: feels,
|
||||
borderColor: "#ffd4a8",
|
||||
borderDash: [5, 4],
|
||||
|
||||
Reference in New Issue
Block a user