mirror of
				https://github.com/ae-utbm/sith.git
				synced 2025-11-04 11:03:04 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			156 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			156 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
from typing import Literal
 | 
						|
 | 
						|
from django.db.models import Q
 | 
						|
from django.utils import html
 | 
						|
from haystack.query import SearchQuerySet
 | 
						|
from ninja import FilterSchema, ModelSchema, Schema
 | 
						|
from pydantic import AliasPath, ConfigDict, Field, TypeAdapter
 | 
						|
from pydantic.alias_generators import to_camel
 | 
						|
 | 
						|
from pedagogy.models import UV
 | 
						|
 | 
						|
 | 
						|
class UtbmShortUvSchema(Schema):
 | 
						|
    """Short representation of an UV in the UTBM API.
 | 
						|
 | 
						|
    Notes:
 | 
						|
        This schema holds only the fields we actually need.
 | 
						|
        The UTBM API returns more data than that.
 | 
						|
    """
 | 
						|
 | 
						|
    model_config = ConfigDict(alias_generator=to_camel)
 | 
						|
 | 
						|
    code: str
 | 
						|
    code_formation: str
 | 
						|
    code_categorie: str | None
 | 
						|
    code_langue: str
 | 
						|
    ouvert_automne: bool
 | 
						|
    ouvert_printemps: bool
 | 
						|
 | 
						|
 | 
						|
class WorkloadSchema(Schema):
 | 
						|
    model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True)
 | 
						|
 | 
						|
    code: Literal["TD", "TP", "CM", "THE", "TE"]
 | 
						|
    nbh: int
 | 
						|
 | 
						|
 | 
						|
class SemesterUvState(Schema):
 | 
						|
    """The state of the UV during either autumn or spring semester"""
 | 
						|
 | 
						|
    model_config = ConfigDict(alias_generator=to_camel)
 | 
						|
 | 
						|
    responsable: str
 | 
						|
    ouvert: bool
 | 
						|
 | 
						|
 | 
						|
ShortUvList = TypeAdapter(list[UtbmShortUvSchema])
 | 
						|
 | 
						|
 | 
						|
class UtbmFullUvSchema(Schema):
 | 
						|
    """Long representation of an UV in the UTBM API."""
 | 
						|
 | 
						|
    model_config = ConfigDict(alias_generator=to_camel)
 | 
						|
 | 
						|
    code: str
 | 
						|
    departement: str = "NA"
 | 
						|
    libelle: str | None
 | 
						|
    objectifs: str | None
 | 
						|
    programme: str | None
 | 
						|
    acquisition_competences: str | None
 | 
						|
    acquisition_notions: str | None
 | 
						|
    langue: str
 | 
						|
    code_langue: str
 | 
						|
    credits_ects: int
 | 
						|
    activites: list[WorkloadSchema]
 | 
						|
    respo_automne: str | None = Field(
 | 
						|
        None, validation_alias=AliasPath("automne", "responsable")
 | 
						|
    )
 | 
						|
    respo_printemps: str | None = Field(
 | 
						|
        None, validation_alias=AliasPath("printemps", "responsable")
 | 
						|
    )
 | 
						|
 | 
						|
 | 
						|
class SimpleUvSchema(ModelSchema):
 | 
						|
    """Our minimal representation of an UV."""
 | 
						|
 | 
						|
    class Meta:
 | 
						|
        model = UV
 | 
						|
        fields = [
 | 
						|
            "id",
 | 
						|
            "title",
 | 
						|
            "code",
 | 
						|
            "credit_type",
 | 
						|
            "semester",
 | 
						|
            "department",
 | 
						|
        ]
 | 
						|
 | 
						|
 | 
						|
class UvSchema(ModelSchema):
 | 
						|
    """Our complete representation of an UV"""
 | 
						|
 | 
						|
    class Meta:
 | 
						|
        model = UV
 | 
						|
        fields = [
 | 
						|
            "id",
 | 
						|
            "title",
 | 
						|
            "code",
 | 
						|
            "hours_THE",
 | 
						|
            "hours_TD",
 | 
						|
            "hours_TP",
 | 
						|
            "hours_TE",
 | 
						|
            "hours_CM",
 | 
						|
            "credit_type",
 | 
						|
            "semester",
 | 
						|
            "language",
 | 
						|
            "department",
 | 
						|
            "credits",
 | 
						|
            "manager",
 | 
						|
            "skills",
 | 
						|
            "key_concepts",
 | 
						|
            "objectives",
 | 
						|
            "program",
 | 
						|
        ]
 | 
						|
 | 
						|
 | 
						|
class UvFilterSchema(FilterSchema):
 | 
						|
    search: str | None = Field(None, q="code__icontains")
 | 
						|
    semester: set[Literal["AUTUMN", "SPRING"]] | None = None
 | 
						|
    credit_type: set[Literal["CS", "TM", "EC", "OM", "QC"]] | None = Field(
 | 
						|
        None, q="credit_type__in"
 | 
						|
    )
 | 
						|
    language: str = "FR"
 | 
						|
    department: set[str] | None = Field(None, q="department__in")
 | 
						|
 | 
						|
    def filter_search(self, value: str | None) -> Q:
 | 
						|
        """Special filter for the search text.
 | 
						|
 | 
						|
        It does a full text search if available.
 | 
						|
        """
 | 
						|
        if not value:
 | 
						|
            return Q()
 | 
						|
 | 
						|
        if len(value) < 3 or (len(value) < 5 and any(c.isdigit() for c in value)):
 | 
						|
            # Likely to be an UV code
 | 
						|
            return Q(code__istartswith=value)
 | 
						|
 | 
						|
        qs = list(
 | 
						|
            SearchQuerySet()
 | 
						|
            .models(UV)
 | 
						|
            .autocomplete(auto=html.escape(value))
 | 
						|
            .values_list("pk", flat=True)
 | 
						|
        )
 | 
						|
 | 
						|
        return Q(id__in=qs)
 | 
						|
 | 
						|
    def filter_semester(self, value: set[str] | None) -> Q:
 | 
						|
        """Special filter for the semester.
 | 
						|
 | 
						|
        If either "SPRING" or "AUTUMN" is given, UV that are available
 | 
						|
        during "AUTUMN_AND_SPRING" will be filtered.
 | 
						|
        """
 | 
						|
        if not value:
 | 
						|
            return Q()
 | 
						|
        value.add("AUTUMN_AND_SPRING")
 | 
						|
        return Q(semester__in=value)
 |