Bot commit: Добавлен файл models.py
This commit is contained in:
parent
f31d5221fd
commit
1d9fe9bfe3
450
models.py
Normal file
450
models.py
Normal file
@ -0,0 +1,450 @@
|
|||||||
|
from pydantic import BaseModel, Field, model_validator, validator, ConfigDict
|
||||||
|
from typing import List, Optional, Literal
|
||||||
|
from datetime import datetime, date, timezone
|
||||||
|
from fastapi.security import OAuth2PasswordRequestForm
|
||||||
|
import json
|
||||||
|
from fastapi import File, Form, UploadFile
|
||||||
|
|
||||||
|
|
||||||
|
class NotifyItem(BaseModel):
|
||||||
|
user_id: str
|
||||||
|
text: str
|
||||||
|
title: Optional[str] = "Уведомление"
|
||||||
|
link: str = "/profile"
|
||||||
|
type_item: str = "c"
|
||||||
|
|
||||||
|
|
||||||
|
class DeliverySendRequest(BaseModel):
|
||||||
|
sender: str
|
||||||
|
too: str
|
||||||
|
item: str
|
||||||
|
delivery_type: Literal["СДЭК", "Самостоятельно"]
|
||||||
|
track: Optional[str] = Field(None, description="Трэк-номер для СДЭК")
|
||||||
|
|
||||||
|
|
||||||
|
class DeliveryAcceptRequest(BaseModel):
|
||||||
|
item: str
|
||||||
|
|
||||||
|
|
||||||
|
class UserRegister(BaseModel):
|
||||||
|
username: Optional[str]
|
||||||
|
phone: Optional[str]
|
||||||
|
email: Optional[str]
|
||||||
|
# img: Optional[UploadFile]
|
||||||
|
password: str
|
||||||
|
client_id: str
|
||||||
|
roles: List[str] = ["user"]
|
||||||
|
extra_scopes: List[str] = []
|
||||||
|
birthday: Optional[date]
|
||||||
|
grade: Optional[str]
|
||||||
|
female_name_lastname: Optional[str] = Field(None, alias="Female_Name_Lastame")
|
||||||
|
living_place: Optional[str]
|
||||||
|
offer_accepted: Optional[bool] = False
|
||||||
|
offer_accepted_at: Optional[datetime] = None
|
||||||
|
|
||||||
|
@model_validator(mode='after')
|
||||||
|
def at_least_one_identifier(self):
|
||||||
|
if not any([self.username, self.phone, self.email]):
|
||||||
|
raise ValueError("At least one of username, phone or email is required")
|
||||||
|
return self
|
||||||
|
model_config = {"validate_by_name": True}
|
||||||
|
|
||||||
|
|
||||||
|
class FormCompetition(BaseModel):
|
||||||
|
id: str
|
||||||
|
title: str
|
||||||
|
address: Optional[str]
|
||||||
|
topic: Optional[str]
|
||||||
|
short_desc: Optional[str]
|
||||||
|
rules_file_id: Optional[str]
|
||||||
|
poster_file_id: Optional[str]
|
||||||
|
min_paintings: Optional[int]
|
||||||
|
max_paintings: Optional[int]
|
||||||
|
|
||||||
|
|
||||||
|
class UserLoginForm(OAuth2PasswordRequestForm):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class LoginRequest(BaseModel):
|
||||||
|
identifier: str
|
||||||
|
password: str
|
||||||
|
client_id: str
|
||||||
|
|
||||||
|
|
||||||
|
class RestoreRequest(BaseModel):
|
||||||
|
identifier: str
|
||||||
|
next: str
|
||||||
|
|
||||||
|
|
||||||
|
class ResetPasswordRequest(BaseModel):
|
||||||
|
token: str
|
||||||
|
new_password: str
|
||||||
|
|
||||||
|
|
||||||
|
class AdminLoginRequest(BaseModel):
|
||||||
|
user_id: str
|
||||||
|
|
||||||
|
|
||||||
|
class PartnercompetitionRequest(BaseModel):
|
||||||
|
competition_id: str
|
||||||
|
post_id: str
|
||||||
|
status: str
|
||||||
|
|
||||||
|
|
||||||
|
class CompetitionArtistRequest(BaseModel):
|
||||||
|
competition_id: str
|
||||||
|
user_id: str
|
||||||
|
|
||||||
|
|
||||||
|
class Partnercompetitionstop(BaseModel):
|
||||||
|
competition_id: str
|
||||||
|
|
||||||
|
|
||||||
|
class PartnerExhibitionDelete(BaseModel):
|
||||||
|
exhibition_id: str
|
||||||
|
|
||||||
|
|
||||||
|
class PostEditDescription(BaseModel):
|
||||||
|
post_id: str
|
||||||
|
description: str
|
||||||
|
|
||||||
|
|
||||||
|
class TokenResponse(BaseModel):
|
||||||
|
access_token: str
|
||||||
|
refresh_token: str
|
||||||
|
token_type: str = "bearer"
|
||||||
|
|
||||||
|
|
||||||
|
class RefreshRequest(BaseModel):
|
||||||
|
refresh_token: str | None = None
|
||||||
|
client_id: str | None = None
|
||||||
|
|
||||||
|
|
||||||
|
class CompetitionCreate(BaseModel):
|
||||||
|
datetime_start: datetime
|
||||||
|
date_finish: datetime
|
||||||
|
poster: UploadFile
|
||||||
|
type_: str
|
||||||
|
title: str
|
||||||
|
topic: Optional[str] = None
|
||||||
|
nominations: List[str] = []
|
||||||
|
address: str
|
||||||
|
short_desc: Optional[str] = None
|
||||||
|
rules_link: Optional[str] = None
|
||||||
|
rules: Optional[UploadFile] = None
|
||||||
|
min_paintings: int
|
||||||
|
max_paintings: int
|
||||||
|
emailsNotify: bool = False
|
||||||
|
serviceSocial: bool = False
|
||||||
|
userSocial: bool = False
|
||||||
|
|
||||||
|
@model_validator(mode="after")
|
||||||
|
def make_aware(cls, values):
|
||||||
|
tz = timezone.utc
|
||||||
|
if not values.rules_link and not values.rules:
|
||||||
|
raise ValueError(
|
||||||
|
"Укажите хотя бы один из параметров: `rules_link` ИЛИ `rules` (файл)."
|
||||||
|
)
|
||||||
|
if values.datetime_start and values.datetime_start.tzinfo is None:
|
||||||
|
values.datetime_start = values.datetime_start.replace(tzinfo=tz)
|
||||||
|
elif values.datetime_start:
|
||||||
|
values.datetime_start = values.datetime_start.astimezone(tz)
|
||||||
|
if values.date_finish and values.date_finish.tzinfo is None:
|
||||||
|
values.date_finish = values.date_finish.replace(tzinfo=tz)
|
||||||
|
elif values.date_finish:
|
||||||
|
values.date_finish = values.date_finish.astimezone(tz)
|
||||||
|
return values
|
||||||
|
|
||||||
|
@validator("nominations", pre=True, always=True)
|
||||||
|
def parse_nominations(cls, v):
|
||||||
|
if v is None:
|
||||||
|
return None
|
||||||
|
if isinstance(v, list):
|
||||||
|
return v
|
||||||
|
try:
|
||||||
|
data = json.loads(v)
|
||||||
|
return data if isinstance(data, list) else [data]
|
||||||
|
except (json.JSONDecodeError, TypeError):
|
||||||
|
return [v]
|
||||||
|
|
||||||
|
|
||||||
|
class ExhibitionCreate(BaseModel):
|
||||||
|
datetime_start: datetime
|
||||||
|
date_finish: datetime
|
||||||
|
poster: UploadFile
|
||||||
|
rules: Optional[UploadFile] = None
|
||||||
|
rules_link: Optional[str] = None
|
||||||
|
tizer: Optional[UploadFile] = None
|
||||||
|
tizer_link: Optional[str] = None
|
||||||
|
title: str
|
||||||
|
topic: Optional[str] = None
|
||||||
|
address: Optional[str] = None
|
||||||
|
place: Optional[str] = None
|
||||||
|
|
||||||
|
@model_validator(mode="after")
|
||||||
|
def make_aware(cls, values):
|
||||||
|
tz = timezone.utc
|
||||||
|
if not values.rules_link and not values.rules:
|
||||||
|
raise ValueError(
|
||||||
|
"Укажите хотя бы один из параметров: `rules_link` ИЛИ `rules` (файл)."
|
||||||
|
)
|
||||||
|
if not values.tizer_link and not values.tizer:
|
||||||
|
raise ValueError(
|
||||||
|
"Укажите хотя бы один из параметров: `tizer_link` ИЛИ `tizer` (файл)."
|
||||||
|
)
|
||||||
|
if values.datetime_start and values.datetime_start.tzinfo is None:
|
||||||
|
values.datetime_start = values.datetime_start.replace(tzinfo=tz)
|
||||||
|
elif values.datetime_start:
|
||||||
|
values.datetime_start = values.datetime_start.astimezone(tz)
|
||||||
|
if values.date_finish and values.date_finish.tzinfo is None:
|
||||||
|
values.date_finish = values.date_finish.replace(tzinfo=tz)
|
||||||
|
elif values.date_finish:
|
||||||
|
values.date_finish = values.date_finish.astimezone(tz)
|
||||||
|
return values
|
||||||
|
|
||||||
|
|
||||||
|
async def build_payload(
|
||||||
|
datetime_start: datetime = Form(...),
|
||||||
|
date_finish: datetime = Form(...),
|
||||||
|
poster: UploadFile = File(...),
|
||||||
|
type_: str = Form(...),
|
||||||
|
title: str = Form(...),
|
||||||
|
topic: Optional[str] = Form(None),
|
||||||
|
nominations: Optional[str] = Form(None),
|
||||||
|
address: str = Form(...),
|
||||||
|
short_desc: Optional[str] = Form(None),
|
||||||
|
rules_link: Optional[str] = Form(None),
|
||||||
|
rules: Optional[UploadFile] = File(None),
|
||||||
|
min_paintings: int = Form(...),
|
||||||
|
max_paintings: int = Form(...),
|
||||||
|
emailsNotify: bool = Form(False),
|
||||||
|
serviceSocial: bool = Form(False),
|
||||||
|
userSocial: bool = Form(False),
|
||||||
|
) -> CompetitionCreate:
|
||||||
|
return CompetitionCreate(
|
||||||
|
datetime_start=datetime_start,
|
||||||
|
date_finish=date_finish,
|
||||||
|
poster=poster,
|
||||||
|
type_=type_,
|
||||||
|
title=title,
|
||||||
|
topic=topic,
|
||||||
|
nominations=nominations,
|
||||||
|
address=address,
|
||||||
|
short_desc=short_desc,
|
||||||
|
rules_link=rules_link,
|
||||||
|
rules=rules,
|
||||||
|
min_paintings=min_paintings,
|
||||||
|
max_paintings=max_paintings,
|
||||||
|
emailsNotify=emailsNotify,
|
||||||
|
serviceSocial=serviceSocial,
|
||||||
|
userSocial=userSocial,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class CompetitionUpdate(BaseModel):
|
||||||
|
datetime_start: Optional[datetime] = None
|
||||||
|
date_finish: Optional[datetime] = None
|
||||||
|
poster: Optional[UploadFile] = None
|
||||||
|
type_: Optional[str] = None
|
||||||
|
title: Optional[str] = None
|
||||||
|
topic: Optional[str] = None
|
||||||
|
nominations: Optional[List[str]] = None
|
||||||
|
rules_link: Optional[str] = None
|
||||||
|
address: Optional[str] = None
|
||||||
|
short_desc: Optional[str] = None
|
||||||
|
rules: Optional[UploadFile] = None
|
||||||
|
min_paintings: Optional[int] = None
|
||||||
|
max_paintings: Optional[int] = None
|
||||||
|
emailsNotify: Optional[bool] = False
|
||||||
|
serviceSocial: Optional[bool] = False
|
||||||
|
userSocial: Optional[bool] = False
|
||||||
|
|
||||||
|
model_config = ConfigDict(
|
||||||
|
arbitrary_types_allowed=True,
|
||||||
|
json_encoders={
|
||||||
|
datetime: lambda v: v.isoformat()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
@model_validator(mode="after")
|
||||||
|
def make_aware(cls, values):
|
||||||
|
tz = timezone.utc
|
||||||
|
if values.datetime_start and values.datetime_start.tzinfo is None:
|
||||||
|
values.datetime_start = values.datetime_start.replace(tzinfo=tz)
|
||||||
|
elif values.datetime_start:
|
||||||
|
values.datetime_start = values.datetime_start.astimezone(tz)
|
||||||
|
if values.date_finish and values.date_finish.tzinfo is None:
|
||||||
|
values.date_finish = values.date_finish.replace(tzinfo=tz)
|
||||||
|
elif values.date_finish:
|
||||||
|
values.date_finish = values.date_finish.astimezone(tz)
|
||||||
|
return values
|
||||||
|
|
||||||
|
|
||||||
|
@validator("nominations", pre=True, always=True)
|
||||||
|
def parse_nominations(cls, v):
|
||||||
|
if v is None:
|
||||||
|
return None
|
||||||
|
if isinstance(v, list):
|
||||||
|
return v
|
||||||
|
try:
|
||||||
|
data = json.loads(v)
|
||||||
|
return data if isinstance(data, list) else [data]
|
||||||
|
except (json.JSONDecodeError, TypeError):
|
||||||
|
return [v]
|
||||||
|
|
||||||
|
|
||||||
|
async def build_update_payload(
|
||||||
|
datetime_start: Optional[datetime] = Form(None),
|
||||||
|
date_finish: Optional[datetime] = Form(None),
|
||||||
|
poster: Optional[UploadFile] = File(None),
|
||||||
|
type_: Optional[str] = Form(...),
|
||||||
|
title: Optional[str] = Form(None),
|
||||||
|
topic: Optional[str] = Form(None),
|
||||||
|
nominations: Optional[str] = Form(None),
|
||||||
|
rules_link: Optional[str] = Form(None),
|
||||||
|
address: Optional[str] = Form(None),
|
||||||
|
short_desc: Optional[str] = Form(None),
|
||||||
|
rules: Optional[UploadFile] = File(None),
|
||||||
|
min_paintings: Optional[int] = Form(None),
|
||||||
|
max_paintings: Optional[int] = Form(None),
|
||||||
|
emailsNotify: Optional[bool] = Form(False),
|
||||||
|
serviceSocial: Optional[bool] = Form(False),
|
||||||
|
userSocial: Optional[bool] = Form(False),
|
||||||
|
) -> CompetitionUpdate:
|
||||||
|
return CompetitionUpdate(
|
||||||
|
datetime_start=datetime_start,
|
||||||
|
date_finish=date_finish,
|
||||||
|
poster=poster,
|
||||||
|
type_=type_,
|
||||||
|
title=title,
|
||||||
|
topic=topic,
|
||||||
|
nominations=nominations,
|
||||||
|
rules_link=rules_link,
|
||||||
|
address=address,
|
||||||
|
short_desc=short_desc,
|
||||||
|
rules=rules,
|
||||||
|
min_paintings=min_paintings,
|
||||||
|
max_paintings=max_paintings,
|
||||||
|
emailsNotify=emailsNotify,
|
||||||
|
serviceSocial=serviceSocial,
|
||||||
|
userSocial=userSocial,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class CompetitionPublishParams(BaseModel):
|
||||||
|
competition_id: str
|
||||||
|
emailsNotify: bool = False
|
||||||
|
serviceSocial: bool = False
|
||||||
|
userSocial: bool = False
|
||||||
|
usersSocial: bool = False
|
||||||
|
|
||||||
|
|
||||||
|
async def build_publish_payload(
|
||||||
|
competition_id: str = Form(...),
|
||||||
|
emailsNotify: bool = Form(False),
|
||||||
|
serviceSocial: bool = Form(False),
|
||||||
|
userSocial: bool = Form(False),
|
||||||
|
usersSocial: bool = Form(False),
|
||||||
|
) -> CompetitionPublishParams:
|
||||||
|
return CompetitionPublishParams(
|
||||||
|
competition_id=competition_id,
|
||||||
|
emailsNotify=emailsNotify,
|
||||||
|
serviceSocial=serviceSocial,
|
||||||
|
userSocial=userSocial,
|
||||||
|
usersSocial=usersSocial,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def build_exhibition_payload(
|
||||||
|
datetime_start: datetime = Form(...),
|
||||||
|
date_finish: datetime = Form(...),
|
||||||
|
poster: Optional[UploadFile] = File(...),
|
||||||
|
rules: Optional[UploadFile] = File(None),
|
||||||
|
rules_link: Optional[str] = Form(None),
|
||||||
|
tizer: Optional[UploadFile] = File(None),
|
||||||
|
tizer_link: Optional[str] = Form(None),
|
||||||
|
title: str = Form(...),
|
||||||
|
topic: Optional[str] = Form(None),
|
||||||
|
address: Optional[str] = Form(None),
|
||||||
|
place: Optional[str] = Form(None),
|
||||||
|
) -> ExhibitionCreate:
|
||||||
|
return ExhibitionCreate(
|
||||||
|
datetime_start=datetime_start,
|
||||||
|
date_finish=date_finish,
|
||||||
|
poster=poster,
|
||||||
|
rules=rules,
|
||||||
|
rules_link=rules_link,
|
||||||
|
tizer=tizer,
|
||||||
|
tizer_link=tizer_link,
|
||||||
|
title=title,
|
||||||
|
topic=topic,
|
||||||
|
address=address,
|
||||||
|
place=place,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ExhibitionUpdate(BaseModel):
|
||||||
|
datetime_start: Optional[datetime] = None
|
||||||
|
date_finish: Optional[datetime] = None
|
||||||
|
poster: Optional[UploadFile] = None
|
||||||
|
rules: Optional[UploadFile] = None
|
||||||
|
rules_link: Optional[str] = None
|
||||||
|
tizer: Optional[UploadFile] = None
|
||||||
|
tizer_link: Optional[str] = None
|
||||||
|
title: Optional[str] = None
|
||||||
|
topic: Optional[str] = None
|
||||||
|
address: Optional[str] = None
|
||||||
|
place: Optional[str] = None
|
||||||
|
short_desc: Optional[str] = None
|
||||||
|
|
||||||
|
model_config = ConfigDict(
|
||||||
|
arbitrary_types_allowed=True,
|
||||||
|
json_encoders={
|
||||||
|
datetime: lambda v: v.isoformat()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
@model_validator(mode="after")
|
||||||
|
def make_aware(cls, values):
|
||||||
|
tz = timezone.utc
|
||||||
|
if values.datetime_start and values.datetime_start.tzinfo is None:
|
||||||
|
values.datetime_start = values.datetime_start.replace(tzinfo=tz)
|
||||||
|
elif values.datetime_start:
|
||||||
|
values.datetime_start = values.datetime_start.astimezone(tz)
|
||||||
|
|
||||||
|
if values.date_finish and values.date_finish.tzinfo is None:
|
||||||
|
values.date_finish = values.date_finish.replace(tzinfo=tz)
|
||||||
|
elif values.date_finish:
|
||||||
|
values.date_finish = values.date_finish.astimezone(tz)
|
||||||
|
return values
|
||||||
|
|
||||||
|
|
||||||
|
async def build_update_exhibition_payload(
|
||||||
|
datetime_start: Optional[datetime] = Form(None),
|
||||||
|
date_finish: Optional[datetime] = Form(None),
|
||||||
|
poster: Optional[UploadFile] = File(None),
|
||||||
|
rules: Optional[UploadFile] = File(None),
|
||||||
|
rules_link: Optional[str] = Form(None),
|
||||||
|
tizer: Optional[UploadFile] = File(None),
|
||||||
|
tizer_link: Optional[str] = Form(None),
|
||||||
|
title: Optional[str] = Form(None),
|
||||||
|
topic: Optional[str] = Form(None),
|
||||||
|
address: Optional[str] = Form(None),
|
||||||
|
place: Optional[str] = Form(None),
|
||||||
|
short_desc: Optional[str] = Form(None),
|
||||||
|
) -> ExhibitionUpdate:
|
||||||
|
return ExhibitionUpdate(
|
||||||
|
datetime_start=datetime_start,
|
||||||
|
date_finish=date_finish,
|
||||||
|
poster=poster,
|
||||||
|
rules=rules,
|
||||||
|
rules_link=rules_link,
|
||||||
|
tizer=tizer,
|
||||||
|
tizer_link=tizer_link,
|
||||||
|
title=title,
|
||||||
|
topic=topic,
|
||||||
|
address=address,
|
||||||
|
place=place,
|
||||||
|
short_desc=short_desc,
|
||||||
|
)
|
||||||
Loading…
Reference in New Issue
Block a user