tailfin/api/schemas/aircraft.py
2024-01-15 09:01:21 -06:00

172 lines
5.5 KiB
Python

from enum import Enum
from utils import to_objectid
from pydantic import BaseModel, field_validator
from pydantic_core.core_schema import ValidationInfo
from schemas.utils import PyObjectId, PositiveFloat
category_class = {
"Airplane": [
"Single-Engine Land",
"Multi-Engine Land",
"Single-Engine Sea",
"Multi-Engine Sea",
],
"Rotorcraft": [
"Helicopter",
"Gyroplane",
],
"Powered Lift": [
"Powered Lift",
],
"Glider": [
"Glider",
],
"Lighter-Than-Air": [
"Airship",
"Balloon",
],
"Powered Parachute": [
"Powered Parachute Land",
"Powered Parachute Sea",
],
"Weight-Shift Control": [
"Weight-Shift Control Land",
"Weight-Shift Control Sea",
],
}
class AircraftCategory(Enum):
airplane = "Airplane"
rotorcraft = "Rotorcraft"
powered_lift = "Powered Lift"
glider = "Glider"
lighter_than_air = "Lighter-Than-Air"
ppg = "Powered Parachute"
weight_shift = "Weight-Shift Control"
aircraft_category_dict = {cls.name: cls.value for cls in AircraftCategory}
class AircraftClass(Enum):
# Airplane
sel = "Single-Engine Land"
ses = "Single-Engine Sea"
mel = "Multi-Engine Land"
mes = "Multi-Engine Sea"
# Rotorcraft
helicopter = "Helicopter"
gyroplane = "Gyroplane"
# Powered Lift
powered_lift = "Powered Lift"
# Glider
glider = "Glider"
# Lighther-than-air
airship = "Airship"
balloon = "Balloon"
# Powered Parachute
ppl = "Powered Parachute Land"
pps = "Powered Parachute Sea"
# Weight-Shift
wsl = "Weight-Shift Control Land"
wss = "Weight-Shift Control Sea"
aircraft_class_dict = {cls.name: cls.value for cls in AircraftClass}
class AircraftCreateSchema(BaseModel):
tail_no: str
make: str
model: str
aircraft_category: AircraftCategory
aircraft_class: AircraftClass
hobbs: PositiveFloat
@field_validator('aircraft_class')
def validate_class(cls, v: str, info: ValidationInfo, **kwargs):
"""
Dependent field validator for aircraft class. Ensures class corresponds to the correct category
:param v: Value of aircraft_class
:param values: Other values in schema
:param kwargs:
:return: v
"""
if 'aircraft_category' in info.data.keys():
category = info.data['aircraft_category']
if category == AircraftCategory.airplane and v not in [AircraftClass.sel, AircraftClass.mel,
AircraftClass.ses, AircraftClass.mes]:
raise ValueError("Class must be SEL, MEL, SES, or MES for Airplane category")
elif category == AircraftCategory.rotorcraft and v not in [AircraftClass.helicopter,
AircraftClass.gyroplane]:
raise ValueError("Class must be Helicopter or Gyroplane for Rotorcraft category")
elif category == AircraftCategory.powered_lift and not v == AircraftClass.powered_lift:
raise ValueError("Class must be Powered Lift for Powered Lift category")
elif category == AircraftCategory.glider and not v == AircraftClass.glider:
raise ValueError("Class must be Glider for Glider category")
elif category == AircraftCategory.lighter_than_air and v not in [
AircraftClass.airship, AircraftClass.balloon]:
raise ValueError("Class must be Airship or Balloon for Lighter-Than-Air category")
elif category == AircraftCategory.ppg and v not in [AircraftClass.ppl,
AircraftClass.pps]:
raise ValueError("Class must be Powered Parachute Land or "
"Powered Parachute Sea for Powered Parachute category")
elif category == AircraftCategory.weight_shift and v not in [AircraftClass.wsl,
AircraftClass.wss]:
raise ValueError("Class must be Weight-Shift Control Land or Weight-Shift "
"Control Sea for Weight-Shift Control category")
return v
class AircraftDisplaySchema(AircraftCreateSchema):
user: PyObjectId
id: PyObjectId
# HELPERS #
def aircraft_add_helper(aircraft: dict, user: str) -> dict:
"""
Convert given aircraft dict to a format that can be inserted into the db
:param aircraft: Aircraft request body
:param user: User that created aircraft
:return: Combined dict that can be inserted into db
"""
aircraft["user"] = to_objectid(user)
aircraft["aircraft_category"] = aircraft["aircraft_category"].name
aircraft["aircraft_class"] = aircraft["aircraft_class"].name
return aircraft
def aircraft_display_helper(aircraft: dict) -> dict:
"""
Convert given db response into a format usable by AircraftDisplaySchema
:param aircraft:
:return: USable dict
"""
aircraft["id"] = str(aircraft["_id"])
aircraft["user"] = str(aircraft["user"])
if aircraft["aircraft_category"] is not AircraftCategory:
aircraft["aircraft_category"] = AircraftCategory.__members__.get(aircraft["aircraft_category"])
if aircraft["aircraft_class"] is not AircraftClass:
aircraft["aircraft_class"] = AircraftClass.__members__.get(aircraft["aircraft_class"])
return aircraft