-
Notifications
You must be signed in to change notification settings - Fork 398
introduce user groups #1621
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
introduce user groups #1621
Changes from all commits
ef2d6be
84b8ba3
383aac6
b1ee39d
402e1cc
4a25bd6
5bc8b03
53acd80
7430dbf
3ec9be7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,7 +6,10 @@ | |
| # Copyright © 2010-2012 Matteo Boscariol <boscarim@hotmail.com> | ||
| # Copyright © 2012-2018 Luca Wehrstedt <luca.wehrstedt@gmail.com> | ||
| # Copyright © 2015 William Di Luigi <williamdiluigi@gmail.com> | ||
| # Copyright © 2015 Fabian Gundlach <320pointsguy@gmail.com> | ||
| # Copyright © 2016 Myungwoo Chun <mc.tamaki@gmail.com> | ||
| # Copyright © 2017-2026 Tobias Lenz <t_lenz94@web.de> | ||
| # Copyright © 2021 Manuel Gundlach <manuel.gundlach@gmail.com> | ||
| # | ||
| # This program is free software: you can redistribute it and/or modify | ||
| # it under the terms of the GNU Affero General Public License as | ||
|
|
@@ -29,7 +32,7 @@ | |
| from ipaddress import IPv4Network, IPv6Network | ||
|
|
||
| from sqlalchemy.dialects.postgresql import ARRAY, CIDR | ||
| from sqlalchemy.orm import relationship | ||
| from sqlalchemy.orm import backref, relationship | ||
| from sqlalchemy.schema import Column, ForeignKey, CheckConstraint, \ | ||
| UniqueConstraint | ||
| from sqlalchemy.types import Boolean, Integer, String, Unicode, DateTime, \ | ||
|
|
@@ -41,6 +44,101 @@ | |
| if typing.TYPE_CHECKING: | ||
| from . import Submission, UserTest | ||
|
|
||
|
|
||
| class Group(Base): | ||
| """Class to store a group of users (for timing, etc.). | ||
|
|
||
| """ | ||
| __tablename__ = 'groups' | ||
| __table_args__ = ( | ||
| UniqueConstraint('contest_id', 'name'), | ||
| CheckConstraint("start <= stop"), | ||
| CheckConstraint("stop <= analysis_start"), | ||
| CheckConstraint("analysis_start <= analysis_stop"), | ||
| ) | ||
|
|
||
| # Auto increment primary key. | ||
| id: int = Column( | ||
| Integer, | ||
| primary_key=True) | ||
|
|
||
| name: str = Column( | ||
| Unicode, | ||
| nullable=False) | ||
|
|
||
| # Beginning and ending of the contest. | ||
| start: datetime = Column( | ||
| DateTime, | ||
| nullable=False, | ||
| default=datetime(2000, 1, 1)) | ||
| stop: datetime = Column( | ||
| DateTime, | ||
| nullable=False, | ||
| default=datetime(2100, 1, 1)) | ||
|
|
||
| # Beginning and ending of the analysis mode for this group. | ||
| analysis_enabled: bool = Column( | ||
| Boolean, | ||
| nullable=False, | ||
| default=False) | ||
| analysis_start: datetime = Column( | ||
| DateTime, | ||
| nullable=False, | ||
| default=datetime(2100, 1, 1)) | ||
| analysis_stop: datetime = Column( | ||
| DateTime, | ||
| nullable=False, | ||
| default=datetime(2100, 1, 1)) | ||
|
|
||
| # Max contest time for each user in seconds. | ||
| per_user_time: timedelta | None = Column( | ||
| Interval, | ||
| CheckConstraint("per_user_time >= '0 seconds'"), | ||
| nullable=True) | ||
|
|
||
| # Contest (id and object) to which this user group belongs. | ||
| contest_id: int = Column( | ||
| Integer, | ||
| ForeignKey(Contest.id, | ||
| onupdate="CASCADE", ondelete="CASCADE"), | ||
| # nullable=False, | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we have an explicit nullable=True or nullable=False on every column, so why not have it here too? (i don't know who initially did this, but i like it being explicit because then i don't have to remember what sqlalchemy's default is :) ) |
||
| index=True) | ||
| contest: Contest = relationship( | ||
| Contest, | ||
| foreign_keys=[contest_id], | ||
| back_populates="groups") | ||
|
|
||
| def phase(self, timestamp: datetime) -> int: | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it looks like you copied an older version of phase() from contest.py to here. i'd prefer keeping the comment i added to it. |
||
| """Return: -1 if contest isn't started yet at time timestamp, | ||
| 0 if the contest is active at time timestamp, | ||
| 1 if the contest has ended but analysis mode | ||
| hasn't started yet | ||
| 2 if the contest has ended and analysis mode is active | ||
| 3 if the contest has ended and analysis mode is disabled or | ||
| has ended | ||
|
|
||
| timestamp (datetime): the time we are iterested in. | ||
| return (int): contest phase as above. | ||
|
|
||
| """ | ||
| if timestamp < self.start: | ||
| return -1 | ||
| if timestamp <= self.stop: | ||
| return 0 | ||
| if self.analysis_enabled: | ||
| if timestamp < self.analysis_start: | ||
| return 1 | ||
| elif timestamp <= self.analysis_stop: | ||
| return 2 | ||
| return 3 | ||
|
|
||
| participations: list["Participation"] = relationship( | ||
| "Participation", | ||
| cascade="all, delete-orphan", | ||
| passive_deletes=True, | ||
| back_populates="group") | ||
|
|
||
|
|
||
| class User(Base): | ||
| """Class to store a user. | ||
|
|
||
|
|
@@ -231,6 +329,17 @@ class Participation(Base): | |
| back_populates="participations") | ||
| __table_args__ = (UniqueConstraint("contest_id", "user_id"),) | ||
|
|
||
| # Group this user belongs to | ||
| group_id: int = Column( | ||
| Integer, | ||
| ForeignKey(Group.id, | ||
| onupdate="CASCADE", ondelete="CASCADE"), | ||
| nullable=False, | ||
| index=True) | ||
| group: Group = relationship( | ||
| Group, | ||
| back_populates="participations") | ||
|
|
||
| # Team (id and object) that the user is representing with this | ||
| # participation. | ||
| team_id: int | None = Column( | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this import is unnecessary now