from bson import ObjectId import bson from fastapi import APIRouter, HTTPException from fastapi.params import Depends import pymongo from app.dto import PinDTO from app.models import HTTPError from app.models.user import User from .utils import get_current_user, objectid_misformatted import app.config as config # Best workaround found for _id typed as ObjectId (creating Exception bcause JSON doesn't support custom types countrary to BSON, used by Mongo) # also allows to create DTOs at the time, but not at it's best (project structure is chaotic FTM :s) import app.serializers as serializers # Import all serializers (detailed in __init__.py) # Database setup client = pymongo.MongoClient(config.MONGODB_URL, username=config.MONGODB_USERNAME, password=config.MONGODB_PASSWORD) db = client[config.MONGODB_DATABASE] pins_collection = db["pins"] pins_router = APIRouter( prefix="/pin", tags=["Pins"] ) @pins_router.get( path="/{id}", responses={401: {"model": HTTPError}, 404: {"model": HTTPError}, 422: {"model": HTTPError}} ) async def get_pin(id: str, current_user: User = Depends(get_current_user)): try: pin = pins_collection.find_one({"_id": ObjectId(id)}) except bson.errors.InvalidId: objectid_misformatted() if pin is None: raise HTTPException(status_code=404, detail="Pin not found") return serializers.pin_serialize(pin) @pins_router.patch( path="/{id}", responses={401: {"model": HTTPError}, 404: {"model": HTTPError}, 422: {"model": HTTPError}} ) async def update_pin(id: str, pin: PinDTO, current_user: User = Depends(get_current_user)): try: result = pins_collection.update_one({"_id": ObjectId(id)}, {"$set": pin.model_dump()}) except bson.errors.InvalidId: objectid_misformatted() if result.matched_count == 0: raise HTTPException(status_code=404, detail="Pin not found") return {"message": "Pin updated"} @pins_router.post( path="/add", responses={401: {"model": HTTPError}} ) async def add_pin(pin: PinDTO, current_user: User = Depends(get_current_user)): pin.user_id = current_user.uid pin_id = pins_collection.insert_one(pin.model_dump()).inserted_id return {"id": str(pin_id)} @pins_router.get( path="s", responses={401: {"model": HTTPError}} ) async def list_pins(current_user: User = Depends(get_current_user)): pins = serializers.pins_serialize(pins_collection.find().to_list(), current_user.uid) return pins