SyncAPI/extensions/devices.py

84 lines
3.7 KiB
Python

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"]
del device["user"]
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, client: str, apikey: APIKey = Depends(get_api_key)):
user = user_by_key(apikey)
if (configGet("devices", "limits") != -1) and (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, "client": client, "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, client: 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, "client": client}})
col_saves.update_many({"user": user, "device": name}, {"$set": {"device": new_name}})
return Response(status_code=HTTP_204_NO_CONTENT)