generateur_v3/backend/api/database/exercices/models.py
2023-02-23 17:11:57 +01:00

185 lines
4.5 KiB
Python

from enum import Enum
from typing import List
from typing import TYPE_CHECKING, Optional
from pydantic import BaseModel
from pydantic import validator
from sqlalchemy.inspection import inspect
from sqlmodel import JSON, Column
from sqlmodel import SQLModel, Field, Relationship
from database.auth.models import User
from services.io import get_filename_from_path
from services.schema import as_form
from .FileField import FileField
if TYPE_CHECKING:
from database.auth.models import User
class ExampleEnum(str, Enum):
csv = 'csv'
pdf = 'pdf'
web = 'web'
undisponible = 'undisponible'
class GeneratorOutput(BaseModel):
calcul: str
correction: str | None = None
class Example(BaseModel):
type: ExampleEnum = ExampleEnum.undisponible
data: List[GeneratorOutput] | None = None
class ExercicesTagLink(SQLModel, table=True):
exercice_id: Optional[int] = Field(
default=None, foreign_key='exercice.id', primary_key=True)
tag_id: Optional[int] = Field(
default=None, foreign_key='tag.id', primary_key=True)
class ExerciceBase(SQLModel):
name: str = Field(max_length=50, index=True)
consigne: Optional[str] = Field(max_length=200, default=None)
private: Optional[bool] = Field(default=False)
class Supports(SQLModel):
csv: bool
pdf: bool
web: bool
class Exercice(ExerciceBase, Supports, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
id_code: str = Field(unique=True, index=True)
exo_source: FileField['/uploads']
author_id: int = Field(foreign_key='user.id')
author: "User" = Relationship(back_populates='exercices')
origin_id: Optional[int] = Field(
foreign_key='exercice.id', default=None, nullable=True)
original: Optional['Exercice'] = Relationship(back_populates='duplicated', sa_relationship_kwargs=dict(
remote_side='Exercice.id'
))
duplicated: List['Exercice'] = Relationship(back_populates='original')
tags: List['Tag'] = Relationship(
back_populates='exercices', link_model=ExercicesTagLink)
examples: Optional[Example] = Field(
sa_column=Column(JSON), default={})
def dict_relationship(self, *, exclude: List[str], include: List[str]):
relationships = inspect(self.__class__).relationships.items()
relationsData = {rname: getattr(self, rname) for rname, rp in relationships if
rname not in exclude and (rname in include if len(include) != 0 else True)}
return {**self.dict(), **relationsData}
class Config:
validate_assignment = True
extra = 'allow'
# translate the folowing object to python enum
class ColorEnum(Enum):
bleu = "rgb(51,123,255)"
vert = "rgb(0,204,0)"
rouge = "rgb(255,0,0)"
marron = "rgb(153,76,0)"
violet = "rgb(204,0,204)"
jaune = "rgb(255,255,0)"
orange = "rgb(255,128,0)"
noir = "rgb(10,10,10)"
rose = "rgb(255,102,255)"
blanc = "rgb(240,240,240)"
blanche = "rgb(240,240,240)"
class TagBase(SQLModel):
label: str = Field(max_length=20)
color: ColorEnum
class Tag(TagBase, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
id_code: str = Field(unique=True, index=True)
author_id: int = Field(foreign_key='user.id')
author: "User" = Relationship(back_populates='tags')
exercices: List["Exercice"] = Relationship(
back_populates='tags', link_model=ExercicesTagLink)
class TagCreate(TagBase):
id_code: str = None
class TagRead(TagBase):
id_code: str
@as_form
class ExerciceCreate(ExerciceBase):
pass
class ExerciceEdit(ExerciceCreate):
pass
class Author(SQLModel):
username: str
class ExerciceOrigin(SQLModel):
# id: int
id_code: str
name: str
author: str
def get_source_path_from_name_and_id(name: str, id_code: str):
return f'/uploads/{id_code}/{name}'
class ExerciceReadBase(ExerciceBase):
id_code: str
author: Author
original: ExerciceOrigin | None
tags: List[TagRead] = None
exo_source: str
examples: Example = None
is_author: bool = None
@validator('exo_source')
def get_exo_source_name(cls, value, values):
if value is not None:
return get_filename_from_path(value)
return value
class ExerciceRead(ExerciceBase, Supports):
id_code: str
id: int
author_id: int
exo_source: str
author: User
original: Optional[Exercice]
tags: List[Tag]
examples: Example
class ExerciceReadFull(ExerciceReadBase):
supports: Supports