simplify models.py imports, add typehints, add future TODO ideas, add set_votes safety logging method, move and typehint Period.submissions as a List

This commit is contained in:
Xevion
2021-02-14 01:19:18 -06:00
parent 28d7768340
commit 21781d3529

View File

@@ -1,16 +1,24 @@
import datetime import datetime
import enum import enum
import functools import functools
import logging
from typing import List
from sqlalchemy import Boolean, Column, DateTime, Enum, ForeignKey, Integer, Text from sqlalchemy import Boolean, Column, DateTime, Enum, ForeignKey, Integer, Text
from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
from bot.exceptions import FinishedPeriod from bot import constants, exceptions
logger = logging.getLogger(__file__)
logger.setLevel(constants.LOGGING_LEVEL)
Base = declarative_base() Base = declarative_base()
# TODO: Setup and test basic automatic migration.
class PeriodStates(enum.Enum): class PeriodStates(enum.Enum):
""" """
A enum representing the possible states of on-going period. A enum representing the possible states of on-going period.
@@ -52,9 +60,9 @@ def check_not_finished(func):
@functools.wraps(func) @functools.wraps(func)
def wrapper(self, *args, **kwargs): def wrapper(self, *args, **kwargs):
if self.state is PeriodStates.FINISHED: raise FinishedPeriod(f"Period is in it's Finished state.") if self.state is PeriodStates.FINISHED: raise exceptions.FinishedPeriod(f"Period is in it's Finished state.")
elif not self.active: raise FinishedPeriod("Period is no longer active.") elif not self.active: raise exceptions.FinishedPeriod("Period is no longer active.")
elif self.completed: raise FinishedPeriod("Period is already completed.") elif self.completed: raise exceptions.FinishedPeriod("Period is already completed.")
func(self, *args, **kwargs) func(self, *args, **kwargs)
return wrapper return wrapper
@@ -67,10 +75,17 @@ class Submission(Base):
id = Column(Integer, primary_key=True) # Doubles as the ID this Guild has in Discord id = Column(Integer, primary_key=True) # Doubles as the ID this Guild has in Discord
user = Column(Integer) # The ID of the user who submitted it. user = Column(Integer) # The ID of the user who submitted it.
timestamp = Column(DateTime) # When the Submission was posted timestamp = Column(DateTime) # When the Submission was posted
votes = Column(Integer, default=0)
period_id = Column(Integer, ForeignKey("period.id")) # The id of the period this Submission relates to. period_id = Column(Integer, ForeignKey("period.id")) # The id of the period this Submission relates to.
period = relationship("Period", back_populates="submissions") # The period this submission was made in. period = relationship("Period", back_populates="submissions") # The period this submission was made in.
def set_votes(self, n: int) -> None:
"""Sets the number of votes for this Submission."""
if self.votes != n:
logger.warning(f'True vote count was off for Submission {self.id} by {n - self.votes}.')
self.votes = n
class Period(Base): class Period(Base):
"""Represents a particular period of submissions and voting for a given""" """Represents a particular period of submissions and voting for a given"""
@@ -79,12 +94,14 @@ class Period(Base):
id = Column(Integer, primary_key=True) id = Column(Integer, primary_key=True)
guild_id = Column(Integer, ForeignKey("guild.id")) # The guild this period was created in. guild_id = Column(Integer, ForeignKey("guild.id")) # The guild this period was created in.
guild = relationship("Guild", back_populates="periods", foreign_keys=guild_id) guild = relationship("Guild", back_populates="periods", foreign_keys=guild_id)
submissions: List[Submission] = relationship("Submission",
back_populates="period") # All the submissions submitted during this Period's active state.
state = Column(Enum(PeriodStates), default=PeriodStates.READY) # The current state of the period. state = Column(Enum(PeriodStates), default=PeriodStates.READY) # The current state of the period.
active = Column(Boolean, default=True) # Whether this Period is currently running. State will not necessarily be FINISHED. active = Column(Boolean, default=True) # Whether this Period is currently running. State will not necessarily be FINISHED.
completed = Column(Boolean, default=False) # Whether this Period was completed to the end, properly. completed = Column(Boolean, default=False) # Whether this Period was completed to the end, properly.
submissions = relationship("Submission", back_populates="period") # All the submissions submitted during this Period's active state. # TODO: Add automatic duration based advancement logic and tracking columns.
start_time = Column(DateTime, default=datetime.datetime.utcnow()) # When this period was created/started (Ready state). start_time = Column(DateTime, default=datetime.datetime.utcnow()) # When this period was created/started (Ready state).
submissions_time = Column(DateTime, nullable=True) # When this period switched to the Submissions state. submissions_time = Column(DateTime, nullable=True) # When this period switched to the Submissions state.