packlist/backend/routes/trips.py

116 lines
No EOL
3.4 KiB
Python

import re
from uuid import UUID, uuid4
from fastapi import APIRouter, Depends
from sqlalchemy.ext.asyncio import AsyncSession
from schemas import TripCreate
from models import Item, Trip, TripItem
from database import get_db
from sqlalchemy import select
from sqlalchemy.orm import selectinload
from config import FIXED_USER_ID
router = APIRouter(prefix="/trips", tags=["Trips"])
@router.post("/")
async def create_trip(trip: TripCreate, db: AsyncSession = Depends(get_db)):
user_id = FIXED_USER_ID
db_trip = Trip(
id=uuid4(),
name=trip.name,
user_id=user_id,
start_date=trip.start_date,
end_date=trip.end_date,
selected_tags=trip.selected_tags,
marked_tags=trip.marked_tags
)
await db.commit() # damit ID vorhanden ist
db.add(db_trip)
# Tage berechnen
days = (trip.end_date - trip.start_date).days + 1
nights = days - 1
# relevante Items
result = await db.execute(select(Item).where(Item.user_id == user_id))
all_items = result.scalars().all()
trip_items = []
for item in all_items:
item_tag_names = [tag.name for tag in item.tags]
if not set(item_tag_names).issubset(set(trip.selected_tags)):
continue
item_text = replace_placeholders(item.name, days, nights)
# markierte Tags matchen?
matching_marked = set(item_tag_names) & set(trip.marked_tags)
if matching_marked:
for tag in matching_marked:
trip_items.append(TripItem(
id=uuid4(),
trip_id=db_trip.id,
item_id=item.id,
tag=tag,
name=item.name,
calculated_label=item_text,
checked=False
))
else:
trip_items.append(TripItem(
id=uuid4(),
trip_id=db_trip.id,
item_id=item.id,
tag=None,
name=item.name,
calculated_label=item_text,
checked=False
))
db.add_all(trip_items)
await db.commit()
return {"status": "trip created", "trip_id": str(db_trip.id)}
@router.get("/{trip_id}/items")
async def get_trip_items(trip_id: UUID, db: AsyncSession = Depends(get_db)):
result = await db.execute(select(TripItem).where(TripItem.trip_id == trip_id))
items = result.scalars().all()
return [
{
"label": item.calculated_label,
"tag": item.tag,
"checked": item.checked
} for item in items
]
@router.get("/")
async def get_trips(db: AsyncSession = Depends(get_db)):
user_id = FIXED_USER_ID
result = await db.execute(select(Trip).where(Trip.user_id == user_id))
trips = result.scalars().all()
return [
{
"id": str(trip.id),
"name": trip.name,
"start_date": trip.start_date,
"end_date": trip.end_date,
"selected_tags": trip.selected_tags,
"marked_tags": trip.marked_tags
} for trip in trips
]
def replace_placeholders(text: str, days: int, nights: int) -> str:
def replacer(match):
expr = match.group(1)
expr = expr.replace("days", str(days)).replace("nights", str(nights))
try:
return str(eval(expr))
except:
return match.group(0)
return re.sub(r"{(.*?)}", replacer, text)