|
8 | 8 | from ..models.models import (Image, Place, Trip, TripCreate, TripDay, |
9 | 9 | TripDayBase, TripDayRead, TripItem, |
10 | 10 | TripItemCreate, TripItemRead, TripItemUpdate, |
11 | | - TripPlaceLink, TripRead, TripReadBase, TripUpdate) |
| 11 | + TripPlaceLink, TripRead, TripReadBase, TripShare, |
| 12 | + TripShareURL, TripUpdate) |
12 | 13 | from ..security import verify_exists_and_owns |
13 | | -from ..utils.utils import b64img_decode, remove_image, save_image_to_file |
| 14 | +from ..utils.utils import (b64img_decode, generate_urlsafe, remove_image, |
| 15 | + save_image_to_file) |
14 | 16 |
|
15 | 17 | router = APIRouter(prefix="/api/trips", tags=["trips"]) |
16 | 18 |
|
@@ -338,3 +340,70 @@ def delete_tripitem( |
338 | 340 | session.delete(db_item) |
339 | 341 | session.commit() |
340 | 342 | return {} |
| 343 | + |
| 344 | + |
| 345 | +@router.get("/shared/{token}", response_model=TripRead) |
| 346 | +def read_shared_trip( |
| 347 | + session: SessionDep, |
| 348 | + token: str, |
| 349 | +) -> TripRead: |
| 350 | + share = session.exec(select(TripShare).where(TripShare.token == token)).first() |
| 351 | + if not share: |
| 352 | + raise HTTPException(status_code=404, detail="Not found") |
| 353 | + |
| 354 | + db_trip = session.get(Trip, share.trip_id) |
| 355 | + return TripRead.serialize(db_trip) |
| 356 | + |
| 357 | + |
| 358 | +@router.get("/{trip_id}/share", response_model=TripShareURL) |
| 359 | +def get_shared_trip_url( |
| 360 | + session: SessionDep, |
| 361 | + trip_id: int, |
| 362 | + current_user: Annotated[str, Depends(get_current_username)], |
| 363 | +) -> TripShareURL: |
| 364 | + db_trip = session.get(Trip, trip_id) |
| 365 | + verify_exists_and_owns(current_user, db_trip) |
| 366 | + |
| 367 | + share = session.exec(select(TripShare).where(TripShare.trip_id == trip_id)).first() |
| 368 | + if not share: |
| 369 | + raise HTTPException(status_code=404, detail="Not found") |
| 370 | + |
| 371 | + return {"url": f"/s/t/{share.token}"} |
| 372 | + |
| 373 | + |
| 374 | +@router.post("/{trip_id}/share", response_model=TripShareURL) |
| 375 | +def create_shared_trip( |
| 376 | + session: SessionDep, |
| 377 | + trip_id: int, |
| 378 | + current_user: Annotated[str, Depends(get_current_username)], |
| 379 | +) -> TripShareURL: |
| 380 | + db_trip = session.get(Trip, trip_id) |
| 381 | + verify_exists_and_owns(current_user, db_trip) |
| 382 | + |
| 383 | + shared = session.exec(select(TripShare).where(TripShare.trip_id == trip_id)).first() |
| 384 | + if shared: |
| 385 | + raise HTTPException(status_code=409, detail="The resource already exists") |
| 386 | + |
| 387 | + token = generate_urlsafe() |
| 388 | + trip_share = TripShare(token=token, trip_id=trip_id, user=current_user) |
| 389 | + session.add(trip_share) |
| 390 | + session.commit() |
| 391 | + return {"url": f"/s/t/{token}"} |
| 392 | + |
| 393 | + |
| 394 | +@router.delete("/{trip_id}/share") |
| 395 | +def delete_shared_trip( |
| 396 | + session: SessionDep, |
| 397 | + trip_id: int, |
| 398 | + current_user: Annotated[str, Depends(get_current_username)], |
| 399 | +): |
| 400 | + db_trip = session.get(Trip, trip_id) |
| 401 | + verify_exists_and_owns(current_user, db_trip) |
| 402 | + |
| 403 | + db_share = session.exec(select(TripShare).where(TripShare.trip_id == trip_id)).first() |
| 404 | + if not db_share: |
| 405 | + raise HTTPException(status_code=404, detail="Not found") |
| 406 | + |
| 407 | + session.delete(db_share) |
| 408 | + session.commit() |
| 409 | + return {} |
0 commit comments