from modules.app import app, get_api_key, user_by_key from modules.database import col_devices, col_saves from fastapi import HTTPException, Depends from fastapi.responses import UJSONResponse, Response from fastapi.openapi.models import APIKey from starlette.status import HTTP_204_NO_CONTENT, HTTP_403_FORBIDDEN, HTTP_404_NOT_FOUND, HTTP_409_CONFLICT from modules.utils import configGet @app.get("/devices", response_class=UJSONResponse, description="Get all devices") async def devices_get(apikey: APIKey = Depends(get_api_key)): devices = list(col_devices.find({"user": user_by_key(apikey)})) if len(devices) == 0: raise HTTPException(HTTP_404_NOT_FOUND, detail="Could not find any devices.") output = [] for device in devices: out_device = device del out_device["_id"] del out_device["user"] output.append(out_device) return UJSONResponse(output) @app.get("/devices/{name}", response_class=UJSONResponse, description="Get information about device by name") async def devices_get_by_name(name: str, apikey: APIKey = Depends(get_api_key)): device = col_devices.find_one({"user": user_by_key(apikey), "name": name}) if device is not None: del device["_id"] return UJSONResponse(device) else: raise HTTPException(HTTP_404_NOT_FOUND, detail="Could not find device with that name.") @app.delete("/devices/{name}", description="Get information about device by name") async def devices_delete_by_name(name: str, apikey: APIKey = Depends(get_api_key)): user = user_by_key(apikey) device = col_devices.find_one({"user": user, "name": name}) if device is not None: col_devices.find_one_and_delete({"user": user, "name": name}) col_saves.delete_many({"user": user, "device": name}) return Response(status_code=HTTP_204_NO_CONTENT) else: raise HTTPException(HTTP_404_NOT_FOUND, detail="Could not find device with that name.") @app.post("/devices", response_class=UJSONResponse, description="Create new device") async def devices_post(name: str, os: str, apikey: APIKey = Depends(get_api_key)): user = user_by_key(apikey) if col_devices.count_documents({"user": user}) >= configGet("devices", "limits"): return UJSONResponse( { "detail": f'Too many devices. This instance allows to register only {configGet("devices", "limits")} devices per user', "limit": configGet("devices", "limits") }, status_code=HTTP_403_FORBIDDEN ) if col_devices.find_one({"user": user, "name": name}) is not None: raise HTTPException(HTTP_409_CONFLICT, detail="Device with this name already exists.") col_devices.insert_one({"user": user, "name": name, "os": os, "last_save": 0}) return Response(status_code=HTTP_204_NO_CONTENT) @app.patch("/devices/{name}", description="Update name of the existing device") async def devices_patch(name: str, new_name: str, os: str, apikey: APIKey = Depends(get_api_key)): user = user_by_key(apikey) if col_devices.find_one({"user": user, "name": name}) is None: raise HTTPException(HTTP_404_NOT_FOUND, detail="Could not find device with that name.") if col_devices.find_one({"user": user, "name": new_name}) is not None: raise HTTPException(HTTP_409_CONFLICT, detail="Device with this name already exists.") col_devices.find_one_and_update({"user": user, "name": name}, {"$set": {"name": new_name, "os": os}}) col_saves.update_many({"user": user, "device": name}, {"$set": {"device": new_name}}) return Response(status_code=HTTP_204_NO_CONTENT)