Feature: Wetter-Verbesserung im Tagebuch — Auto-Wetter, Chip-Fix, Detail-Fix (SW by-v695)
- diary.js: Weather-Chip in der Liste nutzt jetzt temp_c (korrekter Feldname) - diary.js: Detail-View zeigt "emoji temp · X km/h Wind · Y% Regen" (precip_prob statt Luftfeuchtigkeit) - diary.js: Bei neuem Eintrag ohne GPS → Wetter wird via GPS-API vorgeholt und als weather_json mitgesendet - diary.py: DiaryCreate-Modell um weather_json-Feld erweitert; client-geliefertes Wetter wird gespeichert wenn kein GPS-basiertes Wetter verfügbar - SW by-v695, APP_VER 695
This commit is contained in:
parent
6152d6bf0e
commit
b1d9fb4f54
4 changed files with 43 additions and 16 deletions
|
|
@ -9,7 +9,7 @@ from auth import get_current_user, require_admin
|
|||
import ki as KI
|
||||
import httpx
|
||||
import weather as weather_mod
|
||||
from media_utils import convert_media, extract_video_thumb, safe_media_path, validate_upload, extract_gps_from_exif, generate_preview, preview_url_from
|
||||
from media_utils import convert_media, extract_video_thumb, safe_media_path, validate_upload, extract_gps_from_exif, generate_preview, preview_url_from, get_image_size
|
||||
from timeutils import safe_client_time
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
|
@ -30,6 +30,7 @@ class DiaryCreate(BaseModel):
|
|||
location_name: Optional[str] = None
|
||||
is_milestone: bool = False
|
||||
dog_ids: Optional[list[int]] = None # alle Hunde inkl. primär; None = nur primary
|
||||
weather_json: Optional[str] = None # Client-seitig vorab geholtes Wetter (Fallback wenn kein GPS)
|
||||
|
||||
|
||||
class DiaryUpdate(BaseModel):
|
||||
|
|
@ -350,6 +351,19 @@ async def create_diary(dog_id: int, data: DiaryCreate,
|
|||
)
|
||||
entry = conn.execute("SELECT * FROM diary WHERE id=?", (entry_id,)).fetchone()
|
||||
|
||||
elif data.weather_json:
|
||||
# Client hat Wetter vorab geholt (kein GPS-Standort gesetzt) → direkt speichern
|
||||
try:
|
||||
json.loads(data.weather_json) # Validierung
|
||||
with db() as conn:
|
||||
conn.execute(
|
||||
"UPDATE diary SET weather_json=? WHERE id=?",
|
||||
(data.weather_json, entry_id)
|
||||
)
|
||||
entry = conn.execute("SELECT * FROM diary WHERE id=?", (entry_id,)).fetchone()
|
||||
except Exception as exc:
|
||||
logger.warning("Client-weather_json ungültig: %s", exc)
|
||||
|
||||
return _entry_dict(entry, dogs_map, media_map)
|
||||
|
||||
|
||||
|
|
@ -692,10 +706,12 @@ async def upload_media(dog_id: int, entry_id: int,
|
|||
|
||||
media_url = f"/media/diary/{filename}"
|
||||
|
||||
# EXIF-GPS aus Bild extrahieren (nur bei Bilddateien)
|
||||
exif_gps = None
|
||||
# Bildmaße + EXIF-GPS (nur bei Bilddateien)
|
||||
exif_gps = None
|
||||
img_size = None
|
||||
if media_type == "image":
|
||||
exif_gps = extract_gps_from_exif(raw_data)
|
||||
img_size = get_image_size(raw_data)
|
||||
|
||||
with db() as conn:
|
||||
# sort_order = nächste freie Position
|
||||
|
|
@ -706,8 +722,9 @@ async def upload_media(dog_id: int, entry_id: int,
|
|||
# Erstes Item eines Eintrags wird automatisch Cover
|
||||
is_cover = 1 if max_order == -1 else 0
|
||||
conn.execute(
|
||||
"INSERT INTO diary_media (diary_id, url, media_type, sort_order, is_cover) VALUES (?,?,?,?,?)",
|
||||
(entry_id, media_url, media_type, max_order + 1, is_cover)
|
||||
"INSERT INTO diary_media (diary_id, url, media_type, sort_order, is_cover, img_width, img_height) VALUES (?,?,?,?,?,?,?)",
|
||||
(entry_id, media_url, media_type, max_order + 1, is_cover,
|
||||
img_size[0] if img_size else None, img_size[1] if img_size else None)
|
||||
)
|
||||
new_id = conn.execute(
|
||||
"SELECT id FROM diary_media WHERE diary_id=? ORDER BY id DESC LIMIT 1",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue