Feature: Wetter-Tapferkeits-, Jahreszeiten- und Schnee-Badges (SW by-v693)
Drei neue Badge-Kategorien in achievements.py: - wetter_tapfer: Diary-Einträge bei Regen/Kälte/Wind (precip>60, temp<2, wind>50) - jahreszeiten: Anzahl Jahreszeiten mit mind. 5 Diary-Einträgen (max 4) - schnee_held: Diary-Einträge bei Schnee (weathercode 71-77) Beide Funktionen check_and_award und my_achievements erweitert.
This commit is contained in:
parent
6bf088df56
commit
d081029618
1 changed files with 119 additions and 10 deletions
|
|
@ -92,6 +92,45 @@ CATEGORIES = [
|
|||
("gold", 10, "Wiki-Fotograf"),
|
||||
],
|
||||
},
|
||||
{
|
||||
"id": "wetter_tapfer",
|
||||
"name": "Wetter-Tapferkeit",
|
||||
"emoji": "⛈️",
|
||||
"metrik": "wetter_tapfer_score",
|
||||
"einheit": " Eintrag/Einträge",
|
||||
"stufen": [
|
||||
("bronze", 1, "Regentrotzdem"),
|
||||
("silber", 5, "Wettertrotzer"),
|
||||
("gold", 15, "Allwetter-Held"),
|
||||
("platin", 30, "Hunde-Wetterheld"),
|
||||
],
|
||||
},
|
||||
{
|
||||
"id": "jahreszeiten",
|
||||
"name": "Jahreszeiten-Erkunder",
|
||||
"emoji": "🍃",
|
||||
"metrik": "jahreszeiten_score",
|
||||
"einheit": " Jahreszeit(en)",
|
||||
"stufen": [
|
||||
("bronze", 1, "Frühlings-Erkunder"),
|
||||
("silber", 2, "Sommer-Genießer"),
|
||||
("gold", 3, "Herbst-Schnüffler"),
|
||||
("platin", 4, "Alle-Jahreszeiten"),
|
||||
],
|
||||
},
|
||||
{
|
||||
"id": "schnee_held",
|
||||
"name": "Schneeheld",
|
||||
"emoji": "❄️",
|
||||
"metrik": "schnee_eintraege",
|
||||
"einheit": " Eintrag/Einträge",
|
||||
"stufen": [
|
||||
("bronze", 1, "Erster Schnee"),
|
||||
("silber", 5, "Schneehund"),
|
||||
("gold", 15, "Schneeheld"),
|
||||
("platin", 30, "Schneewolf"),
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
# Flat-Liste aller Badge-IDs für DB-Kompatibilität
|
||||
|
|
@ -150,12 +189,47 @@ def check_and_award(user_id: int, conn):
|
|||
"SELECT current_streak FROM users WHERE id=?", (user_id,)
|
||||
).fetchone()
|
||||
|
||||
# Wetter-Tapferkeit: Diary-Einträge bei schlechtem Wetter
|
||||
wetter_row = conn.execute("""
|
||||
SELECT COUNT(*) AS cnt FROM diary d
|
||||
LEFT JOIN diary_dogs dd ON dd.diary_id = d.id
|
||||
WHERE d.user_id = ?
|
||||
AND d.weather_json IS NOT NULL
|
||||
AND (
|
||||
CAST(json_extract(d.weather_json, '$.precip_prob') AS INTEGER) > 60
|
||||
OR CAST(json_extract(d.weather_json, '$.temp_c') AS REAL) < 2
|
||||
OR CAST(json_extract(d.weather_json, '$.wind_kmh') AS REAL) > 50
|
||||
)
|
||||
""", (user_id,)).fetchone()
|
||||
|
||||
# Jahreszeiten: Anzahl Jahreszeiten mit mind. 5 Diary-Einträgen
|
||||
jahreszeiten_row = conn.execute("""
|
||||
SELECT
|
||||
(CASE WHEN (SELECT COUNT(*) FROM diary WHERE user_id=? AND CAST(strftime('%m', datum) AS INTEGER) IN (3,4,5)) >= 5 THEN 1 ELSE 0 END) +
|
||||
(CASE WHEN (SELECT COUNT(*) FROM diary WHERE user_id=? AND CAST(strftime('%m', datum) AS INTEGER) IN (6,7,8)) >= 5 THEN 1 ELSE 0 END) +
|
||||
(CASE WHEN (SELECT COUNT(*) FROM diary WHERE user_id=? AND CAST(strftime('%m', datum) AS INTEGER) IN (9,10,11)) >= 5 THEN 1 ELSE 0 END) +
|
||||
(CASE WHEN (SELECT COUNT(*) FROM diary WHERE user_id=? AND CAST(strftime('%m', datum) AS INTEGER) IN (12,1,2)) >= 5 THEN 1 ELSE 0 END)
|
||||
AS jahreszeiten_score
|
||||
FROM (SELECT 1)
|
||||
""", (user_id, user_id, user_id, user_id)).fetchone()
|
||||
|
||||
# Schnee: Diary-Einträge bei Schnee (weathercode 71-77)
|
||||
schnee_row = conn.execute("""
|
||||
SELECT COUNT(*) AS cnt FROM diary
|
||||
WHERE user_id = ?
|
||||
AND weather_json IS NOT NULL
|
||||
AND CAST(json_extract(weather_json, '$.weathercode') AS INTEGER) BETWEEN 71 AND 77
|
||||
""", (user_id,)).fetchone()
|
||||
|
||||
metrics = {
|
||||
"total_km": stats["total_km"] if stats else 0,
|
||||
"routen": stats["routen"] if stats else 0,
|
||||
"pois": stats["pois"] if stats else 0,
|
||||
"streak": (streak_row["current_streak"] if streak_row else 0),
|
||||
"wiki_fotos": stats["wiki_fotos"] if stats else 0,
|
||||
"total_km": stats["total_km"] if stats else 0,
|
||||
"routen": stats["routen"] if stats else 0,
|
||||
"pois": stats["pois"] if stats else 0,
|
||||
"streak": (streak_row["current_streak"] if streak_row else 0),
|
||||
"wiki_fotos": stats["wiki_fotos"] if stats else 0,
|
||||
"wetter_tapfer_score": wetter_row["cnt"] if wetter_row else 0,
|
||||
"jahreszeiten_score": (jahreszeiten_row["jahreszeiten_score"] if jahreszeiten_row else 0),
|
||||
"schnee_eintraege": schnee_row["cnt"] if schnee_row else 0,
|
||||
}
|
||||
|
||||
earned = {r["badge_id"] for r in
|
||||
|
|
@ -211,6 +285,38 @@ async def my_achievements(user=Depends(get_current_user)):
|
|||
"SELECT current_streak, max_streak FROM users WHERE id=?", (uid,)
|
||||
).fetchone()
|
||||
|
||||
# Wetter-Tapferkeit
|
||||
wetter_row = conn.execute("""
|
||||
SELECT COUNT(*) AS cnt FROM diary d
|
||||
LEFT JOIN diary_dogs dd ON dd.diary_id = d.id
|
||||
WHERE d.user_id = ?
|
||||
AND d.weather_json IS NOT NULL
|
||||
AND (
|
||||
CAST(json_extract(d.weather_json, '$.precip_prob') AS INTEGER) > 60
|
||||
OR CAST(json_extract(d.weather_json, '$.temp_c') AS REAL) < 2
|
||||
OR CAST(json_extract(d.weather_json, '$.wind_kmh') AS REAL) > 50
|
||||
)
|
||||
""", (uid,)).fetchone()
|
||||
|
||||
# Jahreszeiten
|
||||
jahreszeiten_row = conn.execute("""
|
||||
SELECT
|
||||
(CASE WHEN (SELECT COUNT(*) FROM diary WHERE user_id=? AND CAST(strftime('%m', datum) AS INTEGER) IN (3,4,5)) >= 5 THEN 1 ELSE 0 END) +
|
||||
(CASE WHEN (SELECT COUNT(*) FROM diary WHERE user_id=? AND CAST(strftime('%m', datum) AS INTEGER) IN (6,7,8)) >= 5 THEN 1 ELSE 0 END) +
|
||||
(CASE WHEN (SELECT COUNT(*) FROM diary WHERE user_id=? AND CAST(strftime('%m', datum) AS INTEGER) IN (9,10,11)) >= 5 THEN 1 ELSE 0 END) +
|
||||
(CASE WHEN (SELECT COUNT(*) FROM diary WHERE user_id=? AND CAST(strftime('%m', datum) AS INTEGER) IN (12,1,2)) >= 5 THEN 1 ELSE 0 END)
|
||||
AS jahreszeiten_score
|
||||
FROM (SELECT 1)
|
||||
""", (uid, uid, uid, uid)).fetchone()
|
||||
|
||||
# Schnee-Einträge
|
||||
schnee_row = conn.execute("""
|
||||
SELECT COUNT(*) AS cnt FROM diary
|
||||
WHERE user_id = ?
|
||||
AND weather_json IS NOT NULL
|
||||
AND CAST(json_extract(weather_json, '$.weathercode') AS INTEGER) BETWEEN 71 AND 77
|
||||
""", (uid,)).fetchone()
|
||||
|
||||
earned_rows = conn.execute(
|
||||
"SELECT badge_id FROM user_badges WHERE user_id=?", (uid,)
|
||||
).fetchall()
|
||||
|
|
@ -230,11 +336,14 @@ async def my_achievements(user=Depends(get_current_user)):
|
|||
""", (stats["punkte"] if stats else 0,)).fetchone()
|
||||
|
||||
metrics = {
|
||||
"total_km": stats["total_km"] if stats else 0,
|
||||
"routen": stats["routen"] if stats else 0,
|
||||
"pois": stats["pois"] if stats else 0,
|
||||
"streak": (streak_row["current_streak"] if streak_row else 0),
|
||||
"wiki_fotos": stats["wiki_fotos"] if stats else 0,
|
||||
"total_km": stats["total_km"] if stats else 0,
|
||||
"routen": stats["routen"] if stats else 0,
|
||||
"pois": stats["pois"] if stats else 0,
|
||||
"streak": (streak_row["current_streak"] if streak_row else 0),
|
||||
"wiki_fotos": stats["wiki_fotos"] if stats else 0,
|
||||
"wetter_tapfer_score": wetter_row["cnt"] if wetter_row else 0,
|
||||
"jahreszeiten_score": (jahreszeiten_row["jahreszeiten_score"] if jahreszeiten_row else 0),
|
||||
"schnee_eintraege": schnee_row["cnt"] if schnee_row else 0,
|
||||
}
|
||||
|
||||
# Kategorien mit aktuellem Tier + Fortschritt aufbauen
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue