generateur_v3/backend/api/database/exercices/models.py

184 lines
4.5 KiB
Python

from sqlmodel import JSON, Column, select
from sqlalchemy.inspection import inspect
from enum import Enum
import os
from pydantic import BaseModel
from pydantic import validator, root_validator
from generateur.generateur_main import generate_from_path
from services.exoValidation import get_support_from_path
from services.io import add_fast_api_root, get_filename_from_path
from services.schema import as_form
from typing import Any, List, Optional
from sqlmodel import SQLModel, Field, Relationship, Session
from database.auth.models import User, UserRead
from typing import TYPE_CHECKING, Optional
from .FileField import FileField
from database.db import get_session
if TYPE_CHECKING:
from database.auth.models import User
class ExampleEnum(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'
class ColorEnum(Enum):
green='#00ff00'
red="#ff0000"
blue="#0000ff"
string="string"
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