Uprava struktury letu a fotky, uprava GPS pozic v DB

This commit is contained in:
Michal Kváček
2023-07-03 13:23:59 +02:00
parent ba5c3b6a49
commit f8245492b9
18 changed files with 277 additions and 77 deletions
+34
View File
@@ -0,0 +1,34 @@
from collections import defaultdict
from typing import List
from sqlalchemy import select
from strawberry.dataloader import DataLoader
from database import async_session
from database.models import Photo
async def load_collection(ids: List[int]):
async with async_session() as session:
models = (await session.scalars(select(Photo).filter(Photo.flight_id.in_(ids)))).all()
photos_by_flight_id = defaultdict(list)
for photo in models:
photos_by_flight_id[photo.flight_id].append(photo)
return [photos_by_flight_id[id_] for id_ in ids]
async def load(ids: List[int]):
async with async_session() as session:
models = (
await session.scalars(
select(Photo)
.filter(Photo.is_flight_cover.is_(True))
.filter(Photo.flight_id.in_(ids)))
).all()
photos = {p.id: p for p in models}
return [photos.get(id_) for id_ in ids]
photos_dataloader = DataLoader(load_fn=load_collection, cache=False)
cover_photo_loader = DataLoader(load_fn=load)
+2 -6
View File
@@ -1,20 +1,17 @@
import uuid
from typing import List, Optional
import strawberry
from strawberry.file_uploads import Upload
from sqlalchemy import select
from database import models
from graphql_schema.sqlalchemy_to_strawberry_type import strawberry_sqlalchemy_type, strawberry_sqlalchemy_input
from upload_utils import handle_file_upload, delete_file
from upload_utils import handle_file_upload, delete_file, get_public_url
AIRCRAFT_UPLOAD_DEST_PATH = "/app/uploads/aircrafts/"
@strawberry_sqlalchemy_type(models.Aircraft)
class Aircraft:
photo_url: Optional[str] = strawberry.field(
resolver=lambda root: f"http://localhost:8000/uploads/{root.photo_filename}" if root.photo_filename else None
)
photo_url: Optional[str] = strawberry.field(resolver=lambda root: get_public_url(root.photo_filename))
def get_base_query(user_id: int):
@@ -52,7 +49,6 @@ class CreateAircraftMutation:
class CreateAircraftInput:
photo: Optional[Upload]
@strawberry.mutation
async def create_aircraft(root, info, input: CreateAircraftInput) -> Aircraft:
# TODO: kontrola organizace
+13 -5
View File
@@ -2,21 +2,21 @@ from datetime import timedelta
from typing import List, Optional
import strawberry
from sqlalchemy import select
from strawberry.file_uploads import Upload
from database import models
from graphql_schema.dataloaders import copilots_dataloader
from graphql_schema.dataloaders.aircraft import aircraft_dataloader
from graphql_schema.dataloaders.airport import airport_dataloader
from graphql_schema.dataloaders.photos import photos_dataloader, cover_photo_loader
from graphql_schema.entities.aircraft import Aircraft
from graphql_schema.entities.airport import Airport
from graphql_schema.entities.copilot import CopilotType
from graphql_schema.entities.photo import Photo
from graphql_schema.sqlalchemy_to_strawberry_type import strawberry_sqlalchemy_type, strawberry_sqlalchemy_input
from upload_utils import handle_file_upload
# Bude se hodit: https://strawberry.rocks/docs/types/lazy
@strawberry_sqlalchemy_type(models.Flight)
class Flight:
async def load_takeoff_airport(root):
@@ -31,6 +31,12 @@ class Flight:
async def load_copilot(root):
return await copilots_dataloader.load(root.copilot_id)
async def load_photos(root):
return await photos_dataloader.load(root.id)
async def load_cover_photo(root):
return await cover_photo_loader.load(root.id)
def duration_min_calculated(root):
if root.duration_total:
return root.duration_total
@@ -46,6 +52,9 @@ class Flight:
aircraft: Aircraft = strawberry.field(resolver=load_aircraft)
takeoff_airport: Airport = strawberry.field(resolver=load_takeoff_airport)
landing_airport: Airport = strawberry.field(resolver=load_landing_airport)
cover_photo: Optional[Photo] = strawberry.field(resolver=load_cover_photo)
photos: List[Photo] = strawberry.field(resolver=load_photos)
def get_base_query(user_id: int):
@@ -113,7 +122,6 @@ class CreateFlightMutation:
@strawberry.type
class EditFlightMutation:
@strawberry_sqlalchemy_input(models.Flight, exclude_fields=["id"], all_optional=True)
class EditFlightInput:
pass
@@ -122,4 +130,4 @@ class EditFlightMutation:
async def edit_flight(self, info, id: int, input: EditFlightInput) -> Flight:
input_data = input.to_dict()
return await models.Flight.update(info.context.db, id=id, data=input_data)
return await models.Flight.update(info.context.db, id=id, data=input_data)
+37 -8
View File
@@ -1,13 +1,16 @@
from typing import List, Optional
from typing import List
import strawberry
from sqlalchemy import select
from strawberry.file_uploads import Upload
from database import models
from graphql_schema.sqlalchemy_to_strawberry_type import strawberry_sqlalchemy_type, strawberry_sqlalchemy_input
from upload_utils import get_public_url, handle_file_upload
@strawberry_sqlalchemy_type(models.Photo)
class Photo:
pass
url: str = strawberry.field(resolver=lambda root: get_public_url(root.filename))
thumbnail_url: str = strawberry.field(resolver=lambda root: get_public_url(f"thumbs/{root.filename}"))
def get_base_query(user_id: int):
@@ -27,18 +30,37 @@ class PhotoQueries:
@strawberry.type
class DeletePhotoMutation:
class UploadPhotoMutation:
@strawberry_sqlalchemy_input(models.Photo, exclude_fields=["id", "filename"])
class UploadPhotoInput:
photo: Upload
@strawberry.input
class DeletePhotoInput:
id: int
@strawberry.mutation
async def upload_photo(self, info, input: UploadPhotoInput) -> Photo:
photos_dest = f"/app/uploads/photos/{input.flight_id}/"
filename = await handle_file_upload(input.photo, photos_dest)
# todo: udelat nahled do thumbs slozky
created_photo = await models.Photo.create(data={
"flight_id": input.flight_id,
"name": input.name,
"filename": filename,
"description": input.description,
"created_by_id": info.context.user_id,
}, db_session=info.context.db)
return created_photo
@strawberry.type
class EditPhotoMutation:
@strawberry_sqlalchemy_input(models.Photo, exclude_fields=[], all_optional=True)
class UpdatePhotoInput:
class EditPhotoInput:
pass
@strawberry.mutation
async def update_photo(self, info, input: UpdatePhotoInput) -> Photo:
async def update_photo(self, info, input: EditPhotoInput) -> Photo:
query = get_base_query(info.context.user_id)
photo = info.context.db.scalars(query.filter(models.Photo.id == input.id))
@@ -47,6 +69,13 @@ class DeletePhotoMutation:
return photo
@strawberry.type
class DeletePhotoMutation:
@strawberry.input
class DeletePhotoInput:
id: int
@strawberry.mutation
async def delete_photo(self, info, input: DeletePhotoInput) -> Photo:
pass
+4
View File
@@ -1,6 +1,7 @@
from strawberry.tools import merge_types
from graphql_schema.entities.aircraft import CreateAircraftMutation, EditAircraftMutation, DeleteAircraftMutation
from graphql_schema.entities.flight import CreateFlightMutation, EditFlightMutation
from graphql_schema.entities.photo import UploadPhotoMutation, DeletePhotoMutation, EditPhotoMutation
Mutation = merge_types("Mutation", (
CreateAircraftMutation,
@@ -8,4 +9,7 @@ Mutation = merge_types("Mutation", (
DeleteAircraftMutation,
EditFlightMutation,
CreateFlightMutation,
UploadPhotoMutation,
EditPhotoMutation,
DeletePhotoMutation
))
@@ -51,7 +51,11 @@ def strawberry_sqlalchemy_input(
ignored_fields = exclude_fields + ["created_at", "created_by_id", "updated_by_id", "updated_at", "deleted"]
def to_dict(self):
return {name: getattr(self, name) for name, _ in get_columns_from_model(model, ignored_fields) if getattr(self, name) is not None}
return {
name: getattr(self, name)
for name, _ in get_columns_from_model(model, ignored_fields)
if getattr(self, name) is not None
}
def wrapper(cls):
annotations = get_annotations_for_scalars(
@@ -65,10 +69,8 @@ def strawberry_sqlalchemy_input(
for col, col_type in annotations.items():
try:
print("AAAAAAAAAA", col_type)
if col_type._name == 'Optional': # noqa
setattr(cls, col, None)
print(" nastavuji")
except AttributeError:
pass