API pro podporu vytvareni letu z planu

This commit is contained in:
Michal Kváček
2024-06-30 02:31:37 +02:00
parent ac3b496459
commit e541508f75
6 changed files with 132 additions and 8 deletions
@@ -0,0 +1,30 @@
"""add flight.flight_plan_id fk
Revision ID: 989152b7184a
Revises: f9e1e8a01683
Create Date: 2024-06-27 17:09:19.933094
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '989152b7184a'
down_revision = 'f9e1e8a01683'
branch_labels = None
depends_on = None
def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('flight', sa.Column('flight_plan_id', sa.Integer(), nullable=True))
op.create_foreign_key(None, 'flight', 'flight_plan', ['flight_plan_id'], ['id'])
# ### end Alembic commands ###
def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_constraint(None, 'flight', type_='foreignkey')
op.drop_column('flight', 'flight_plan_id')
# ### end Alembic commands ###
@@ -0,0 +1,40 @@
"""Add poi and airport id to flight plan track marker
Revision ID: 8cc01c03e980
Revises: 989152b7184a
Create Date: 2024-06-30 00:27:08.976891
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import mysql
# revision identifiers, used by Alembic.
revision = '8cc01c03e980'
down_revision = '989152b7184a'
branch_labels = None
depends_on = None
def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.alter_column('airport', 'openaip_id',
existing_type=mysql.VARCHAR(length=32),
nullable=True)
op.add_column('flight_plan_marker', sa.Column('airport_id', sa.Integer(), nullable=True))
op.add_column('flight_plan_marker', sa.Column('point_of_interest_id', sa.Integer(), nullable=True))
op.create_foreign_key(None, 'flight_plan_marker', 'point_of_interest', ['point_of_interest_id'], ['id'])
op.create_foreign_key(None, 'flight_plan_marker', 'airport', ['airport_id'], ['id'])
# ### end Alembic commands ###
def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_constraint(None, 'flight_plan_marker', type_='foreignkey')
op.drop_constraint(None, 'flight_plan_marker', type_='foreignkey')
op.drop_column('flight_plan_marker', 'point_of_interest_id')
op.drop_column('flight_plan_marker', 'airport_id')
op.alter_column('airport', 'openaip_id',
existing_type=mysql.VARCHAR(length=32),
nullable=False)
# ### end Alembic commands ###
+31 -5
View File
@@ -104,6 +104,7 @@ class FlightPlan(BaseModel):
is_default_name: Mapped[bool] = mapped_column(Boolean, server_default='0')
is_public: Mapped[bool] = mapped_column(Boolean, server_default='0')
is_editable_by_copilot: Mapped[bool] = mapped_column(Boolean, server_default='0')
track_id: Mapped[int] = mapped_column(Integer, ForeignKey('track.id'), nullable=True)
description: Mapped[str] = mapped_column(Text, nullable=False, server_default="")
planned_speed: Mapped[int] = mapped_column(Integer, nullable=False, default=150)
planned_takeoff_datetime: Mapped[datetime] = mapped_column(DateTime, nullable=True)
@@ -114,21 +115,44 @@ class FlightPlan(BaseModel):
copilots: Mapped[List['Copilot']] = relationship(secondary=flight_plan_has_copilot)
aircraft: Mapped['Aircraft'] = relationship()
markers: Mapped['FlightPlanMarker'] = relationship()
markers: Mapped[List['FlightPlanMarker']] = relationship()
created_by: Mapped['User'] = relationship()
class Track(BaseModel):
__tablename__ = "track"
id: Mapped[int] = mapped_column(primary_key=True)
bounds: Mapped[list[tuple[float, float]]] = mapped_column(JSON())
created_by_id: Mapped[int] = mapped_column(Integer, ForeignKey('user.id'))
created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now())
created_by: Mapped['User'] = relationship()
class TrackPoint(BaseModel):
__tablename__ = "track_point"
id: Mapped[int] = mapped_column(primary_key=True)
timestamp: Mapped[datetime] = mapped_column(DateTime, nullable=False)
track_id: Mapped[id] = mapped_column(Integer, ForeignKey('track.id'))
gps_latitude: Mapped[float] = mapped_column(Float, nullable=False)
gps_longitude: Mapped[float] = mapped_column(Float, nullable=False)
elevation: Mapped[float] = mapped_column(Float, nullable=True)
class FlightPlanMarker(BaseModel):
__tablename__ = "flight_plan_marker"
id: Mapped[int] = mapped_column(primary_key=True)
flight_plan_id: Mapped[int] = mapped_column(Integer, ForeignKey('flight_plan.id'))
airport_id: Mapped[int] = mapped_column(Integer, ForeignKey("airport.id"), nullable=True)
point_of_interest_id: Mapped[int] = mapped_column(Integer, ForeignKey("point_of_interest.id"), nullable=True)
weather_info_id: Mapped[int] = mapped_column(Integer, ForeignKey('weather_info.id'), nullable=True)
name: Mapped[str] = mapped_column(String(128), nullable=False)
type: Mapped[str] = mapped_column(String(64), nullable=False)
position: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
gps_latitude: Mapped[float] = mapped_column(Float, nullable=False)
gps_longitude: Mapped[float] = mapped_column(Float, nullable=False)
weather_info_id: Mapped[int] = mapped_column(Integer, ForeignKey('weather_info.id'), nullable=True)
class Airport(BaseModel):
@@ -136,7 +160,7 @@ class Airport(BaseModel):
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(String(128), nullable=False)
openaip_id: Mapped[str] = mapped_column(String(32), nullable=False, unique=True)
openaip_id: Mapped[str] = mapped_column(String(32), nullable=True, unique=True)
icao_code: Mapped[str] = mapped_column(String(8), nullable=False)
gps_latitude: Mapped[float] = mapped_column(Float, nullable=True)
gps_longitude: Mapped[float] = mapped_column(Float, nullable=True)
@@ -385,8 +409,10 @@ class Flight(BaseModel):
landing_datetime: Mapped[datetime] = mapped_column(DateTime, nullable=False)
duration_total: Mapped[int] = mapped_column(Integer, nullable=True)
duration_pic: Mapped[int] = mapped_column(Integer, nullable=True)
gpx_track_filename: Mapped[str] = mapped_column(String(128), nullable=True)
has_terrain_elevation: Mapped[bool] = mapped_column(Boolean, default=False, nullable=False)
flight_plan_id: Mapped[int] = mapped_column(Integer, ForeignKey('flight_plan.id'), nullable=True)
track_id: Mapped[int] = mapped_column(Integer, ForeignKey('track.id'), nullable=True)
gpx_track_filename: Mapped[str] = mapped_column(String(128), nullable=True) # deprecated
has_terrain_elevation: Mapped[bool] = mapped_column(Boolean, default=False, nullable=False) # deprecated
aircraft_id: Mapped[int] = mapped_column(Integer, ForeignKey('aircraft.id'))
takeoff_weather_info_id: Mapped[int] = mapped_column(Integer, ForeignKey('weather_info.id'), nullable=True)
landing_weather_info_id: Mapped[int] = mapped_column(Integer, ForeignKey('weather_info.id'), nullable=True)
@@ -1,4 +1,6 @@
import asyncio
import random
import uuid
from typing import List, Optional
from sqlalchemy import delete, insert, select, func, text
from sqlalchemy.ext.asyncio import AsyncSession
@@ -142,12 +144,15 @@ class FlightMutationResolver(BaseMutationResolver):
data.update({
"aircraft_id": aircraft_id,
"has_terrain_elevation": False,
"name": "",
"name": input.name or '',
"description": "",
"created_by_id": context.user_id
})
flight = await self._do_create(db, data)
if input.track is not None:
await handle_track_edit(db=db, flight_id=flight.id, track=input.track, user_id=user_id)
context.background_tasks.add_task(
download_weather_for_flight,
flight_id=flight.id, airport_id=flight.takeoff_airport_id, date_time=flight.takeoff_datetime,
@@ -256,14 +261,23 @@ async def handle_track_edit(db: AsyncSession, flight_id: int, track: List[TrackI
if item.point_of_interest:
poi_id = await handle_combobox_save(
db, models.PointOfInterest, item.point_of_interest, user_id, extra_data={"description": ""}
db, models.PointOfInterest, item.point_of_interest, user_id, extra_data={
"description": "",
'gps_latitude': item.gps_latitude,
'gps_longitude': item.gps_longitude
}
)
if item.airport:
airport_id = await handle_combobox_save(
db, models.Airport, item.airport, user_id,
name_column="icao_code",
extra_data={"name": item.airport.name}
extra_data={
"name": item.airport.name,
'gps_latitude': item.gps_latitude,
'gps_longitude': item.gps_longitude,
'openaip_id': f'custom-{random.randint(0, 999999)}'
}
)
await models.FlightTrack.create(
@@ -52,9 +52,18 @@ class FlightPlanMutationResolver(BaseMutationResolver):
position = 0
for marker in markers:
if marker.type == 'poi':
assert bool(marker.point_of_interest_id)
if marker.type == 'airport':
assert bool(marker.airport_id)
await models.FlightPlanMarker.create(db, data={
"position": position,
"flight_plan_id": flight_plan.id,
"airport_id": marker.airport_id,
"point_of_interest_id": marker.point_of_interest_id,
"type": marker.type,
"name": marker.name,
"gps_latitude": marker.gps_latitude,
@@ -138,11 +138,14 @@ class EditFlightInput(BaseGraphqlInputType):
@strawberry.input()
class CreateFlightInput(BaseGraphqlInputType):
aircraft: ComboboxInput
flight_plan_id: Optional[int] = None
name: Optional[str] = None
gpx_track_file: Optional[Upload] = None # TODO: poresit validaci uploadovaneho souboru!
landing_airport: Optional[ComboboxInput] = None
takeoff_airport: Optional[ComboboxInput] = None
takeoff_datetime: Optional[datetime] = None
landing_datetime: Optional[datetime] = None
track: Optional[List[TrackItemInput]] = None
@strawberry.input()
@@ -150,6 +153,8 @@ class TrackItemInput:
point_of_interest: Optional[ComboboxInput] = None
airport: Optional[ComboboxInput] = None
landing_duration: Optional[int] = None
gps_latitude: Optional[float] = None
gps_longitude: Optional[float] = None
@strawberry_sqlalchemy_input(models.Aircraft, exclude_fields=['id', 'photo_filename'])