Fix ukladani fotek, pokus o odstraneni Optional

This commit is contained in:
Michal Kváček
2024-10-09 06:53:42 +02:00
parent d31f1c0c61
commit c6316262e5
30 changed files with 139 additions and 134 deletions
+7 -7
View File
@@ -9,13 +9,13 @@ class QueryBuilder:
def get_simple_query(
self,
extra_select: Optional[list] = None,
created_by_id: Optional[int] = None,
order_by: Optional[list] = None,
only_public: Optional[bool] = False,
only_my: Optional[bool] = False,
include_others_public: Optional[bool] = False,
url_slug: Optional[str] = None,
extra_select: list | None = None,
created_by_id: int | None = None,
order_by: list | None = None,
only_public: bool | None = False,
only_my: bool | None = False,
include_others_public: bool | None = False,
url_slug: str | None = None,
include_deleted: bool = False
):
if not extra_select:
+1 -1
View File
@@ -12,7 +12,7 @@ from emails.emails import WelcomeEmail
class RegistrationInput(BaseModel):
email: str = Field(..., min_length=4)
name: Optional[str]
name: str | None
password: str
@model_validator(mode="before")
+1 -1
View File
@@ -9,7 +9,7 @@ from utils.list_utils import chunks
@dataclasses.dataclass
class ElevationInfo:
id: Optional[int]
id: int | None
lat: float
lng: float
elevation: float
+5 -5
View File
@@ -9,7 +9,7 @@ class BaseDataloader:
def __init__(
self,
model: Type[models.BaseModel],
relationship_column, filters: Optional[list] = None
relationship_column, filters: list | None = None
):
super().__init__()
self.model = model
@@ -43,10 +43,10 @@ class MultiModelsDataloader(BaseDataloader):
self,
model: Type[models.BaseModel],
relationship_column=None,
filters: Optional[list] = None,
extra_select: Optional[list] = None,
extra_join: Optional[list] = None,
order_by: Optional[list] = None,
filters: list | None = None,
extra_select: list | None = None,
extra_join: list | None = None,
order_by: list | None = None,
):
super().__init__(model, relationship_column, filters)
@@ -4,7 +4,7 @@ from database import models
from graphql_schema.dataloaders.base import SingleModelByIdDataloader
def create_dataloader(model: Type[models.BaseModel], relationship_column=None, filters: Optional[list] = None):
def create_dataloader(model: Type[models.BaseModel], relationship_column=None, filters: list | None = None):
loader = SingleModelByIdDataloader(model, relationship_column, filters).load
return DataLoader(load_fn=loader, cache=False)
+3 -3
View File
@@ -31,9 +31,9 @@ class AircraftQueries:
@allow_public
async def aircraft(
root, info,
id: Optional[int] = None,
call_sign: Optional[str] = None,
public: Optional[bool] = False
id: int | None = None,
call_sign: str | None = None,
public: bool | None = False
) -> Aircraft:
filter_params = {}
if id:
+1 -1
View File
@@ -11,7 +11,7 @@ class AirspaceQueries:
@strawberry.field()
@error_logging
async def airspaces(
root, info, country: Optional[str] = None, types: Optional[list[str]] = None
root, info, country: str | None = None, types: Optional[list[str]] = None
) -> List[Airspace]:
filters = []
+6 -6
View File
@@ -25,12 +25,12 @@ class CopilotQueries:
@allow_public
async def copilot(
root, info: Info,
id: Optional[int] = None,
url_slug: Optional[str] = None,
pilot_username: Optional[str] = None,
upload_token: Optional[str] = None,
upload_flight_slug: Optional[str] = None,
public: Optional[bool] = False
id: int | None = None,
url_slug: str | None = None,
pilot_username: str | None = None,
upload_token: str | None = None,
upload_flight_slug: str | None = None,
public: bool | None = False
) -> Copilot:
filter_params = {}
if id:
+6 -6
View File
@@ -21,8 +21,8 @@ class EventQueries:
info,
limit: int,
offset: int = 0,
username: Optional[str] = None,
public: Optional[bool] = False,
username: str | None = None,
public: bool | None = False,
) -> PaginationWindow[Event]:
query = EventQueryResolver().get_query(
user_id=info.context.user_id,
@@ -43,10 +43,10 @@ class EventQueries:
@allow_public
async def event(
root, info,
id: Optional[int] = None,
url_slug: Optional[str] = None,
username: Optional[str] = None,
public: Optional[bool] = False
id: int | None = None,
url_slug: str | None = None,
username: str | None = None,
public: bool | None = False
) -> Event:
filter_params = get_detail_filters(id, url_slug)
if username:
+10 -10
View File
@@ -19,12 +19,12 @@ class FlightQueries:
root, info,
limit: int,
offset: int = 0,
username: Optional[str] = None,
event_id: Optional[int] = None,
public: Optional[bool] = False,
copilot_id: Optional[int] = None,
point_of_interest_id: Optional[int] = None,
aircraft_id: Optional[int] = None,
username: str | None = None,
event_id: int | None = None,
public: bool | None = False,
copilot_id: int | None = None,
point_of_interest_id: int | None = None,
aircraft_id: int | None = None,
) -> PaginationWindow[Flight]:
query = FlightQueryResolver().get_query(
user_id=info.context.user_id,
@@ -48,10 +48,10 @@ class FlightQueries:
@allow_public
async def flight(
root, info,
id: Optional[int] = None,
url_slug: Optional[str] = None,
username: Optional[str] = None,
public: Optional[bool] = False
id: int | None = None,
url_slug: str | None = None,
username: str | None = None,
public: bool | None = False
) -> Flight:
filter_params = get_detail_filters(id, url_slug)
if username:
+2 -2
View File
@@ -24,8 +24,8 @@ class FlightPlanQueries:
root,
info: Info,
id: int,
username: Optional[str] = None,
public: Optional[bool] = False
username: str | None = None,
public: bool | None = False
) -> FlightPlan:
filter_params = get_detail_filters(id)
if username:
@@ -10,7 +10,7 @@ async def handle_combobox_save(
input: ComboboxInput,
user_id: int,
name_column: str = "name",
extra_data: Optional[dict] = None
extra_data: dict | None = None
) -> int:
if input.id:
return input.id
@@ -2,7 +2,7 @@ from typing import Optional
from graphql import GraphQLError
def get_detail_filters(id: Optional[int] = None, url_slug: Optional[str] = None) -> dict:
def get_detail_filters(id: int | None = None, url_slug: str | None = None) -> dict:
filter_params = {}
if id:
filter_params['object_id'] = id
+9 -9
View File
@@ -16,12 +16,12 @@ class PhotoQueries:
@allow_public
async def photos(
root, info,
flight_id: Optional[int] = None,
copilot_id: Optional[int] = None,
uploaded_by_copilot_id: Optional[int] = None,
point_of_interest_id: Optional[int] = None,
aircraft_id: Optional[int] = None,
public: Optional[bool] = False,
flight_id: int | None = None,
copilot_id: int | None = None,
uploaded_by_copilot_id: int | None = None,
point_of_interest_id: int | None = None,
aircraft_id: int | None = None,
public: bool | None = False,
) -> List[Photo]:
return await PhotoQueryResolver().get_list(
public=public,
@@ -37,7 +37,7 @@ class PhotoQueries:
@strawberry.field()
@error_logging
@allow_public
async def photo(root, info, id: int, public: Optional[bool] = False, ) -> Photo:
async def photo(root, info, id: int, public: bool | None = False, ) -> Photo:
return await BaseQueryResolver(Photo, models.Photo).get_one(
object_id=id,
user_id=info.context.user_id,
@@ -63,7 +63,7 @@ class PhotoMutation:
@strawberry.mutation()
@error_logging
async def change_orientation(self, info, id: int, direction: str, copilot_upload_token: Optional[str] = None) -> Photo:
async def change_orientation(self, info, id: int, direction: str, copilot_upload_token: str | None = None) -> Photo:
if info.context.user_id is None and not copilot_upload_token:
raise_unauthorized()
@@ -83,7 +83,7 @@ class PhotoMutation:
@strawberry.mutation()
@error_logging
async def delete_photo(self, info, id: int, copilot_upload_token: Optional[str] = None) -> Photo:
async def delete_photo(self, info, id: int, copilot_upload_token: str | None = None) -> Photo:
if info.context.user_id is None and not copilot_upload_token:
raise_unauthorized()
+3 -3
View File
@@ -20,7 +20,7 @@ class PointOfInterestQueries:
async def points_of_interest(
root, info,
limit: int, offset: int = 0,
search: Optional[str] = None,
search: str | None = None,
public: bool = False
) -> PaginationWindow[PointOfInterest]:
query = BaseQueryResolver(PointOfInterest, models.PointOfInterest).get_query(
@@ -41,8 +41,8 @@ class PointOfInterestQueries:
@allow_public
async def point_of_interest(
root, info,
url_slug: Optional[str] = None,
id: Optional[int] = None,
url_slug: str | None = None,
id: int | None = None,
public: bool = False
) -> PointOfInterest:
filter_params = get_detail_filters(id, url_slug)
@@ -15,9 +15,9 @@ class AircraftQueryResolver(BaseQueryResolver):
def get_query(
self,
user_id: Optional[int] = None,
object_id: Optional[int] = None,
order_by: Optional[list] = None,
user_id: int | None = None,
object_id: int | None = None,
order_by: list | None = None,
organization_ids: Optional[Set[int]] = None,
*args,
**kwargs,
+10 -10
View File
@@ -31,14 +31,14 @@ class BaseQueryResolver(BaseResolver):
def get_query(
self,
user_id: Optional[int] = None,
object_id: Optional[int] = None,
order_by: Optional[list] = None,
only_public: Optional[bool] = False,
only_my: Optional[bool] = False,
include_others_public: Optional[bool] = False,
url_slug: Optional[str] = None,
filters: Optional[list] = None,
user_id: int | None = None,
object_id: int | None = None,
order_by: list | None = None,
only_public: bool | None = False,
only_my: bool | None = False,
include_others_public: bool | None = False,
url_slug: str | None = None,
filters: list | None = None,
**kwargs,
):
query = self.query_builder.get_simple_query(
@@ -77,11 +77,11 @@ class BaseQueryResolver(BaseResolver):
query = query.filter(or_(*search_clauses))
return query
async def get_list(self, user_id: Optional[int] = None, **kwargs) -> List[GQL_TYPE]:
async def get_list(self, user_id: int | None = None, **kwargs) -> List[GQL_TYPE]:
query = self.get_query(user_id=user_id, **kwargs)
return await self._get_list(query)
async def get_one(self, user_id: Optional[int] = None, **kwargs) -> GQL_TYPE:
async def get_one(self, user_id: int | None = None, **kwargs) -> GQL_TYPE:
query = self.get_query(user_id=user_id, **kwargs)
return await self._get_one(query)
@@ -13,10 +13,10 @@ class CopilotQueryResolver(BaseQueryResolver):
def get_query(
self,
user_id: Optional[int] = None,
object_id: Optional[int] = None,
order_by: Optional[list] = None,
only_public: Optional[bool] = False,
user_id: int | None = None,
object_id: int | None = None,
order_by: list | None = None,
only_public: bool | None = False,
**kwargs
):
pilot_username = kwargs.pop("pilot_username", None)
@@ -10,10 +10,10 @@ class EventQueryResolver(BaseQueryResolver):
def get_query(
self,
user_id: Optional[int] = None,
object_id: Optional[int] = None,
order_by: Optional[list] = None,
only_public: Optional[bool] = True,
user_id: int | None = None,
object_id: int | None = None,
order_by: list | None = None,
only_public: bool | None = True,
*args,
**kwargs,
):
@@ -1,7 +1,7 @@
import asyncio
import random
from typing import Optional
from sqlalchemy import delete, insert
from sqlalchemy import delete, insert, or_, select
from sqlalchemy.ext.asyncio import AsyncSession
from background_jobs.elevation import add_terrain_elevation_to_flight
from background_jobs.flight_title_photo import add_circular_avatar, generate_flight_title_photo
@@ -27,8 +27,8 @@ class FlightQueryResolver(BaseQueryResolver):
def get_query(
self,
user_id: Optional[int] = None,
only_public: Optional[bool] = False,
user_id: int | None = None,
only_public: bool | None = False,
*args,
**kwargs
):
@@ -56,8 +56,17 @@ class FlightQueryResolver(BaseQueryResolver):
if kwargs.get("point_of_interest_id"):
query = (
query.join(models.Flight.turn_points)
.filter(models.FlightTurnPoint.point_of_interest_id == kwargs["point_of_interest_id"])
query
.join(models.Flight.turn_points, isouter=True)
.filter(
or_(
models.FlightTurnPoint.point_of_interest_id == kwargs["point_of_interest_id"],
models.Flight.id.in_(
select(models.Photo.flight_id)
.filter(models.Photo.point_of_interest_id == kwargs["point_of_interest_id"])
)
)
)
)
if kwargs.get('username'):
@@ -21,9 +21,9 @@ class FlightPlanQueryResolver(BaseQueryResolver):
def get_query(
self,
user_id: Optional[int] = None,
only_public: Optional[bool] = False,
object_id: Optional[int] = None,
user_id: int | None = None,
only_public: bool | None = False,
object_id: int | None = None,
*args,
**kwargs
):
@@ -12,8 +12,8 @@ class OrganizationQueryResolver(BaseQueryResolver):
def get_query(
self,
object_id: Optional[int] = None,
order_by: Optional[list] = None,
object_id: int | None = None,
order_by: list | None = None,
**kwargs
):
query = (
+13 -16
View File
@@ -1,9 +1,6 @@
import os
import shutil
from time import time
from typing import Optional
import pymysql.err
import sqlalchemy
from PIL import Image
from graphql import GraphQLError
@@ -31,10 +28,10 @@ class PhotoQueryResolver(BaseQueryResolver):
def get_query(
self,
user_id: Optional[int] = None,
object_id: Optional[int] = None,
order_by: Optional[list] = None,
only_public: Optional[bool] = False,
user_id: int | None = None,
object_id: int | None = None,
order_by: list | None = None,
only_public: bool | None = False,
*args, **kwargs
):
query = super().get_query(
@@ -76,7 +73,7 @@ class PhotoMutationResolver(BaseMutationResolver):
super().__init__(Photo, models.Photo)
@staticmethod
def _copy_original(path: str, filename: str):
def _copy_original(path: str, filename: str) -> str:
original_filename = "_original_" + filename
if not os.path.isfile(path + "/" + original_filename):
shutil.copyfile(path + "/" + filename, path + "/" + original_filename)
@@ -107,7 +104,7 @@ class PhotoMutationResolver(BaseMutationResolver):
)
@staticmethod
async def _get_photo_info_by_copilot_token(db, photo_id: int, copilot_token: Optional[str]):
async def _get_photo_info_by_copilot_token(db, photo_id: int, copilot_token: str | None):
if not copilot_token:
return
@@ -175,29 +172,29 @@ class PhotoMutationResolver(BaseMutationResolver):
return photo
async def update(self, context, id: int, data: EditPhotoInput, user_id: int) -> Photo:
data = data.to_dict()
async def update(self, context, id: int, input: EditPhotoInput, user_id: int) -> Photo:
data = input.to_dict()
async with get_session() as db:
photo = await self._get_one(db, id, created_by_id=user_id)
if data.point_of_interest:
if input.point_of_interest:
data['point_of_interest_id'] = await handle_combobox_save(
db,
models.PointOfInterest,
data.point_of_interest,
input.point_of_interest,
user_id,
extra_data={"description": ""}
)
if data.copilots is not None:
if input.copilots is not None:
await db.execute(delete(models.copilot_has_photo).filter_by(photo_id=id))
for copilot in data.copilots:
for copilot in input.copilots:
await db.execute(insert(models.copilot_has_photo).values(photo_id=id, copilot_id=copilot.id))
return await self._do_update(db, obj=photo, data=data)
async def change_orientation(
self, id: int, user_id: int, direction: str, copilot_upload_token: Optional[str], info
self, id: int, user_id: int, direction: str, copilot_upload_token: str | None, info
):
photo = await self._get_photo_details(id, user_id, copilot_upload_token)
@@ -11,13 +11,13 @@ from graphql_schema.sqlalchemy_to_strawberry_type import strawberry_sqlalchemy_i
@strawberry.input()
class ComboboxInput:
id: Optional[int] = None
id: int | None = None
name: str
@strawberry_sqlalchemy_input(model=models.FlightPlanMarker, exclude_fields=["id", "flight_plan_id"])
class FlightPlanMarkerInput(BaseGraphqlInputType):
position: Optional[int] = 0
position: int | None = 0
@strawberry_sqlalchemy_input(model=models.Copilot, exclude_fields=["id"])
@@ -81,19 +81,19 @@ class EditEventInput(BaseGraphqlInputType):
class UploadPhotoInput:
photo: Upload
flight_id: int
name: Optional[str] = None
description: Optional[str] = None
name: str | None = None
description: str | None = None
point_of_interest: Optional[ComboboxInput] = None
copilot_upload_token: Optional[str] = None
copilot_upload_token: str | None = None
@strawberry.input
class EditPhotoInput:
name: Optional[str] = None
description: Optional[str] = None
name: str | None = None
description: str | None = None
point_of_interest: Optional[ComboboxInput] = None
copilots: Optional[List[ComboboxInput]] = None
aircraft_id: Optional[int] = None
aircraft_id: int | None = None
def to_dict(self):
return {
@@ -113,7 +113,7 @@ class CropInput(BaseGraphqlInputType):
@strawberry.input
class AdjustmentInput:
rotate: Optional[float] = 0
crop_after_rotate: Optional[bool] = True,
crop_after_rotate: bool | None = True,
brightness: Optional[float] = 1
contrast: Optional[float] = 1
saturation: Optional[float] = 1
@@ -138,8 +138,8 @@ class EditFlightInput(BaseGraphqlInputType):
@strawberry.input()
class CreateFlightInput(BaseGraphqlInputType):
aircraft: ComboboxInput
flight_plan_id: Optional[int] = None
name: Optional[str] = None
flight_plan_id: int | None = None
name: str | None = None
gpx_track_file: Optional[Upload] = None # TODO: poresit validaci uploadovaneho souboru!
landing_airport: Optional[ComboboxInput] = None
takeoff_airport: Optional[ComboboxInput] = None
@@ -152,7 +152,7 @@ class CreateFlightInput(BaseGraphqlInputType):
class TrackItemInput:
point_of_interest: Optional[ComboboxInput] = None
airport: Optional[ComboboxInput] = None
landing_duration: Optional[int] = None
landing_duration: int | None = None
gps_latitude: Optional[float] = None
gps_longitude: Optional[float] = None
+7 -7
View File
@@ -170,10 +170,10 @@ class Flight:
photos: List[Photo] = strawberry.field(resolver=lambda root: photos_dataloader.load(root.id))
track: Optional[Track] = strawberry.field(resolver=lambda root: track_dataloader.load(root.track_id))
duration_min_calculated: int = strawberry.field(resolver=lambda root: flight_duration_dataloader.load(root.id))
social_image_url: Optional[str] = strawberry.field(
social_image_url: str | None = strawberry.field(
resolver=lambda root: get_public_url(f'photos/{root.id}/title_photo.jpg')
)
debriefing_notes: Optional[str] = strawberry.field(
debriefing_notes: str | None = strawberry.field(
permission_classes=[IsAuthenticated],
resolver=lambda root: root.debriefing_notes
)
@@ -188,7 +188,7 @@ class FlightPlanMarker:
@strawberry.type
class FlightPlanTrack:
bearing: Optional[int]
bearing: int | None
distance: Optional[float]
from_: FlightPlanMarker = strawberry.field(name="from")
to: Optional[FlightPlanMarker]
@@ -247,7 +247,7 @@ class Copilot:
flights: List[Flight] = strawberry.field(resolver=resolve_flights)
photos: List[Photo] = strawberry.field(resolver=lambda root: photo_copilots_dataloader.load(root.id))
title_photo: Optional[Photo] = strawberry.field(resolver=lambda root: photo_dataloader.load(root.title_photo_id))
token: Optional[str] = strawberry.field(
token: str | None = strawberry.field(
permission_classes=[IsAuthenticated],
resolver=resolve_copilot_token
)
@@ -273,9 +273,9 @@ class Organization:
@strawberry_sqlalchemy_type(models.User, exclude_fields=['password_hashed'])
class User:
avatar_image_url: Optional[str] = strawberry.field(resolver=lambda root: get_avatar_url(root))
avatar_image_url: str | None = strawberry.field(resolver=lambda root: get_avatar_url(root))
title_image_url: str = strawberry.field(resolver=lambda root: get_title_image_url(root))
social_image_url: Optional[str] = strawberry.field(
social_image_url: str | None = strawberry.field(
resolver=lambda root: get_public_url(f'profile/{root.id}/title_photo.jpg')
)
organizations: List[Organization] = strawberry.field(
@@ -285,7 +285,7 @@ class User:
@strawberry_sqlalchemy_type(models.Event)
class Event:
async def load_flights(root, info, only_public: Optional[bool] = False):
async def load_flights(root, info, only_public: bool | None = False):
is_user_logged_in = bool(info.context.user_id)
if not is_user_logged_in or only_public:
dataloader = public_flights_by_event_dataloader
+5 -5
View File
@@ -44,11 +44,11 @@ class UserQueries:
class EditUserMutation:
@strawberry.input
class EditUserInput:
name: Optional[str] = None
description: Optional[str] = None
public_username: Optional[str] = None
old_password: Optional[str] = None
new_password: Optional[str] = None
name: str | None = None
description: str | None = None
public_username: str | None = None
old_password: str | None = None
new_password: str | None = None
avatar_image: Optional[Upload] = None
title_image: Optional[Upload] = None
-1
View File
@@ -1,6 +1,5 @@
import dataclasses
from typing import Set
import strawberry
from fastapi_jwt import JwtAuthorizationCredentials
from fastapi_jwt.jwt import JwtAccessBearerCookie
+1 -1
View File
@@ -14,7 +14,7 @@ def get_photo_basepath(flight_id: int) -> str:
return f"/app/uploads/photos/{flight_id}"
def get_public_url(filename: Optional[str]) -> str:
def get_public_url(filename: str | None) -> str:
return f"{API_URL}/uploads/{filename}" if filename else None
+1 -1
View File
@@ -24,7 +24,7 @@ def get_bounds(coordinates: list[dict[str, float]]) -> list[tuple[float, float]]
]
async def get_airport_id_by_gps(gps_lat: float, gps_lng: float) -> Optional[int]:
async def get_airport_id_by_gps(gps_lat: float, gps_lng: float) -> int | None:
async with get_session() as db:
query = (
select(models.Airport, func.coalesce(6371 * func.acos(
+3 -3
View File
@@ -38,7 +38,7 @@ class PhotoEditor:
self.img = Image.open(f"{path}/{filename}")
self.img_size = self.img.size
def resize(self, new_width: Optional[int] = None, new_height: Optional[int] = None):
def resize(self, new_width: int | None = None, new_height: int | None = None):
if not new_width and not new_height:
raise ValueError("Set either new_width or new_height")
@@ -127,8 +127,8 @@ class PhotoEditor:
return img_io
def write_to_file(
self, quality: int = 90, dest_path: Optional[str] = None, dest_filename: Optional[str] = None,
format_: Optional[str] = "JPEG"
self, quality: int = 90, dest_path: str | None = None, dest_filename: str | None = None,
format_: str | None = "JPEG"
) -> str:
check_directories(dest_path or self.path)