Compare commits
13 Commits
7ee06bbfe8
...
a627c1ef78
| Author | SHA1 | Date | |
|---|---|---|---|
| a627c1ef78 | |||
| 3346612fe6 | |||
| 57fc551e64 | |||
| f5e165aa11 | |||
| 12bb232785 | |||
| 926d5a5afb | |||
| 456bdbf63a | |||
| 5d40e4f358 | |||
| cc55e92a7d | |||
| 7f2c2b5db8 | |||
| 1e1676952d | |||
| 56b5415bc9 | |||
| 649f10be3f |
@ -1,4 +1,2 @@
|
|||||||
Use ```bash
|
Use ``uv build``
|
||||||
uv build
|
|
||||||
```
|
|
||||||
to build package. Then git commit & push.
|
to build package. Then git commit & push.
|
||||||
@ -10,7 +10,7 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ["uv_build>=0.10.2,<0.11.0"]
|
requires = ["uv_build>=0.10.2,<0.12"]
|
||||||
build-backend = "uv_build"
|
build-backend = "uv_build"
|
||||||
|
|
||||||
[dependency-groups]
|
[dependency-groups]
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
from typing import Annotated
|
from typing import Literal
|
||||||
from pydantic import Field
|
from pydantic import Field
|
||||||
|
|
||||||
from .non_members import FormerMemberModel
|
from .non_members import FormerMemberModel
|
||||||
@ -6,7 +6,8 @@ from .enums import Membership, OnlineAlmanacField
|
|||||||
from .submodels import Address, LoginInfo
|
from .submodels import Address, LoginInfo
|
||||||
|
|
||||||
class MemberModel(FormerMemberModel):
|
class MemberModel(FormerMemberModel):
|
||||||
membership: Annotated[Membership, Field(pattern="member")]
|
# requires that Membership equals member
|
||||||
|
membership: Literal[Membership.member] = Membership.member
|
||||||
|
|
||||||
login: LoginInfo
|
login: LoginInfo
|
||||||
address: Address
|
address: Address
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
from typing import Annotated
|
from typing import Literal
|
||||||
from pydantic import Field
|
from pydantic import Field
|
||||||
|
|
||||||
from .person import PersonModel
|
from .person import PersonModel
|
||||||
@ -13,12 +13,12 @@ class FormerMemberModel(PersonModel):
|
|||||||
# company emails?
|
# company emails?
|
||||||
|
|
||||||
class AlumnModel(FormerMemberModel):
|
class AlumnModel(FormerMemberModel):
|
||||||
membership: Annotated[Membership, Field(pattern="alumn")]
|
membership: Literal[Membership.alumn] = Membership.alumn
|
||||||
|
|
||||||
graduated: bool = False
|
graduated: bool = False
|
||||||
receive_spam_mail: bool = True
|
receive_spam_mail: bool = True
|
||||||
|
|
||||||
class ExternalModel(PersonModel):
|
class ExternalModel(PersonModel):
|
||||||
membership: Annotated[Membership, Field(pattern="extern")]
|
membership: Literal[Membership.extern] = Membership.extern
|
||||||
# TODO... payment???
|
# TODO... payment???
|
||||||
# TODO require login info??
|
# TODO require login info??
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
from fiber_package.util import EntityList
|
from fiber_package.util import EntityList, GroupList
|
||||||
|
|
||||||
class AssociationModel(BaseModel):
|
class AssociationModel(BaseModel):
|
||||||
full_name: str
|
full_name: str
|
||||||
members: EntityList = EntityList("member", [])
|
members: EntityList
|
||||||
# committees: GroupList("commmittee", 0) # type: ignore
|
committees: GroupList
|
||||||
# events: GroupList("event", 0) # type: ignore
|
guilds: GroupList
|
||||||
# activities: GroupList("activity", 0) # type: ignore
|
# events: GroupList
|
||||||
# mailings: GroupList("mailing", 0) # type: ignore
|
# activities: GroupList
|
||||||
# mailalias: GroupList("mailalias", 0) # type: ignore
|
# mailings: GroupList
|
||||||
50
src/fiber_package/groups/committees/committee.py
Normal file
50
src/fiber_package/groups/committees/committee.py
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
from pydantic import BaseModel, model_validator
|
||||||
|
from fiber_package.util import EntityList, GroupList, GroupRef
|
||||||
|
|
||||||
|
from typing import Self
|
||||||
|
from datetime import date
|
||||||
|
|
||||||
|
from .enums import CommitteeType
|
||||||
|
|
||||||
|
'''
|
||||||
|
Committees are groups of members for a definite period.
|
||||||
|
Every committee has a list of editions.
|
||||||
|
An edition is a definite group of members with functions and a timespan.
|
||||||
|
'''
|
||||||
|
|
||||||
|
class CommitteeModel(BaseModel):
|
||||||
|
full_name_EN: str
|
||||||
|
full_name_NL: str
|
||||||
|
description_EN: str = ""
|
||||||
|
description_NL: str = ""
|
||||||
|
committee_type: CommitteeType
|
||||||
|
|
||||||
|
active: bool = True
|
||||||
|
|
||||||
|
editions: GroupList
|
||||||
|
current_edition: GroupRef | None
|
||||||
|
|
||||||
|
@model_validator(mode='after')
|
||||||
|
def current_edition_in_editions(self) -> Self:
|
||||||
|
uuid = self.current_edition
|
||||||
|
if uuid is None:
|
||||||
|
return self
|
||||||
|
if uuid not in self.editions:
|
||||||
|
raise ValueError("Current edition must be in list of editions")
|
||||||
|
return self
|
||||||
|
|
||||||
|
# TODO... maybe require that an active board always has a current_edition that is non-empty?
|
||||||
|
|
||||||
|
class CommitteeEditionModel(BaseModel):
|
||||||
|
members: EntityList
|
||||||
|
functions: dict[UUID4, str]
|
||||||
|
|
||||||
|
start_date: date
|
||||||
|
end_date: date | None # None means ongoing
|
||||||
|
|
||||||
|
@model_validator(mode='after')
|
||||||
|
def functions_to_members_only(self) -> Self:
|
||||||
|
for uuid in self.functions.keys():
|
||||||
|
if uuid not in self.members:
|
||||||
|
raise ValueError("Cannot only assign functions to members")
|
||||||
|
return self
|
||||||
8
src/fiber_package/groups/committees/enums.py
Normal file
8
src/fiber_package/groups/committees/enums.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
from enum import StrEnum
|
||||||
|
|
||||||
|
class CommitteeType(StrEnum):
|
||||||
|
board_committee = "Board committee"
|
||||||
|
gmm_committee = "GMM committee"
|
||||||
|
board = "board"
|
||||||
|
|
||||||
|
|
||||||
42
src/fiber_package/groups/committees/guild.py
Normal file
42
src/fiber_package/groups/committees/guild.py
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
from pydantic import BaseModel, model_validator
|
||||||
|
from fiber_package.util import EntityList
|
||||||
|
|
||||||
|
from datetime import date
|
||||||
|
|
||||||
|
from typing import Self
|
||||||
|
|
||||||
|
|
||||||
|
'''
|
||||||
|
Guilds are groups of members for an indefinite period.
|
||||||
|
They have a list of members.
|
||||||
|
|
||||||
|
Removing old members from last_active is done in fiber
|
||||||
|
'''
|
||||||
|
|
||||||
|
class GuildModel(BaseModel):
|
||||||
|
full_name_EN: str
|
||||||
|
full_name_NL: str
|
||||||
|
description_EN: str
|
||||||
|
description_NL: str
|
||||||
|
|
||||||
|
members: EntityList
|
||||||
|
previous_members: EntityList
|
||||||
|
|
||||||
|
guild_masters: EntityList
|
||||||
|
|
||||||
|
last_active: dict[EntityRef, date]
|
||||||
|
|
||||||
|
@model_validator(mode='after')
|
||||||
|
def current_members_not_previous(self) -> Self:
|
||||||
|
for member in self.members:
|
||||||
|
if member in self.previous_members:
|
||||||
|
raise ValueError("There can be no overlap between members and previous members!")
|
||||||
|
return self
|
||||||
|
|
||||||
|
@model_validator(mode='after')
|
||||||
|
def guild_masters_are_members(self) -> Self:
|
||||||
|
for master in self.guild_masters:
|
||||||
|
if master not in self.members:
|
||||||
|
raise ValueError("All guild masters must be members!")
|
||||||
|
return self
|
||||||
|
|
||||||
@ -60,7 +60,7 @@ class ActivityModel(CommunicationModel):
|
|||||||
Field(pattern=CommunicationCategory.activity)
|
Field(pattern=CommunicationCategory.activity)
|
||||||
]
|
]
|
||||||
|
|
||||||
signuplist: GroupRef = GroupRef("signuplist", None)
|
signuplist: GroupRef | None = None
|
||||||
# TODO: validate that a signuplist can only be attached if category is
|
# TODO: validate that a signuplist can only be attached if category is
|
||||||
# activity? Or should this not be validated?
|
# activity? Or should this not be validated?
|
||||||
|
|
||||||
|
|||||||
@ -2,5 +2,5 @@ from pydantic import BaseModel
|
|||||||
from fiber_package.util import GroupList, EntityList
|
from fiber_package.util import GroupList, EntityList
|
||||||
|
|
||||||
class RootGroupModel(BaseModel):
|
class RootGroupModel(BaseModel):
|
||||||
associations: GroupList = GroupList("association", [])
|
associations: GroupList
|
||||||
sys_admins: EntityList = EntityList("login", [])
|
sys_admins: EntityList
|
||||||
@ -7,6 +7,7 @@ from fiber_package.util import GroupRef
|
|||||||
A sign-up list is a list of members that have signed up for a given activity.
|
A sign-up list is a list of members that have signed up for a given activity.
|
||||||
'''
|
'''
|
||||||
class SignuplistModel(BaseModel):
|
class SignuplistModel(BaseModel):
|
||||||
activity: GroupRef = GroupRef("communication", None)
|
activity: GroupRef | None = None
|
||||||
# TODO: validate that the communication is indeed an activity (or should
|
# TODO: validate that the communication is indeed an activity (or should
|
||||||
# this be done?)
|
# this be done?)
|
||||||
|
# Should None be allowed?
|
||||||
|
|||||||
@ -1,23 +1,9 @@
|
|||||||
from dataclasses import dataclass, field
|
from typing import Annotated
|
||||||
|
from pydantic import RootModel, Field, UUID4
|
||||||
|
|
||||||
from pydantic import UUID4
|
|
||||||
|
|
||||||
@dataclass(slots=True)
|
EntityList = Annotated[list[UUID4], Field(default_factory=list)]
|
||||||
class EntityList:
|
GroupList = Annotated[list[UUID4], Field(default_factory=list)]
|
||||||
template: str
|
|
||||||
uuids: list[UUID4] = field(default_factory=list)
|
|
||||||
|
|
||||||
@dataclass(slots=True)
|
EntityRef = UUID4
|
||||||
class GroupList:
|
GroupRef = UUID4
|
||||||
template: str
|
|
||||||
uuids: list[UUID4] = field(default_factory=list)
|
|
||||||
|
|
||||||
@dataclass(slots=True)
|
|
||||||
class EntityRef:
|
|
||||||
template: str
|
|
||||||
uuid: UUID4 | None = None
|
|
||||||
|
|
||||||
@dataclass(slots=True)
|
|
||||||
class GroupRef:
|
|
||||||
template: str
|
|
||||||
uuid: UUID4 | None = None
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user