Split frontend model from backend model
All checks were successful
Build Formula10 Docker Image / build-docker (push) Successful in 26s

This commit is contained in:
2024-02-25 15:09:59 +01:00
parent a9b1bc4403
commit 991a1a177e
38 changed files with 1094 additions and 930 deletions

View File

@ -0,0 +1,44 @@
from urllib.parse import quote
from formula10.database.model.db_driver import DbDriver
from formula10.frontend.model.team import NONE_TEAM, Team
class Driver():
@classmethod
def from_db_driver(cls, db_driver: DbDriver):
driver: Driver = cls()
driver.name = db_driver.name
driver.abbr = db_driver.abbr
driver.country = db_driver.country_code
driver.team = Team.from_db_team(db_driver.team)
return driver
def to_db_driver(self) -> DbDriver:
db_driver: DbDriver = DbDriver(name=self.name)
db_driver.abbr = self.abbr
db_driver.country_code = self.country
db_driver.team_name = self.team.name
return db_driver
def __eq__(self, __value: object) -> bool:
if isinstance(__value, Driver):
return self.name == __value.name
return NotImplemented
name: str
abbr: str
country: str
team: Team
@property
def name_sanitized(self) -> str:
return quote(self.name)
NONE_DRIVER: Driver = Driver()
NONE_DRIVER.name = "None"
NONE_DRIVER.abbr = "None"
NONE_DRIVER.country = "NO"
NONE_DRIVER.team = NONE_TEAM

View File

@ -0,0 +1,37 @@
from datetime import datetime
from urllib.parse import quote
from formula10.database.model.db_race import DbRace
class Race():
@classmethod
def from_db_race(cls, db_race: DbRace):
race: Race = cls()
race.name = db_race.name
race.number = db_race.number
race.date = db_race.date
race.place_to_guess = db_race.pxx
return race
def to_db_race(self) -> DbRace:
db_race: DbRace = DbRace(name=self.name,
number=self.number,
date=self.date,
pxx=self.place_to_guess)
return db_race
def __eq__(self, __value: object) -> bool:
if isinstance(__value, Race):
return self.name == __value.name
return NotImplemented
name: str
number: int
date: datetime
place_to_guess: int
@property
def name_sanitized(self) -> str:
return quote(self.name)

View File

@ -0,0 +1,33 @@
from formula10.database.model.db_race_guess import DbRaceGuess
from formula10.frontend.model.driver import Driver
from formula10.frontend.model.race import Race
from formula10.frontend.model.user import User
class RaceGuess():
@classmethod
def from_db_race_guess(cls, db_race_guess: DbRaceGuess):
race_guess: RaceGuess = cls()
race_guess.user = User.from_db_user(db_race_guess.user)
race_guess.race = Race.from_db_race(db_race_guess.race)
race_guess.pxx_guess = Driver.from_db_driver(db_race_guess.pxx)
race_guess.dnf_guess = Driver.from_db_driver(db_race_guess.dnf)
return race_guess
def to_db_race_guess(self) -> DbRaceGuess:
db_race_guess: DbRaceGuess = DbRaceGuess(user_name=self.user.name,
race_name=self.race.name,
pxx_driver_name=self.pxx_guess.name,
dnf_driver_name=self.dnf_guess.name)
return db_race_guess
def __eq__(self, __value: object) -> bool:
if isinstance(__value, RaceGuess):
return self.user == __value.user and self.race == __value.race
return NotImplemented
user: User
race: Race
pxx_guess: Driver
dnf_guess: Driver

View File

@ -0,0 +1,148 @@
import json
from typing import Dict, List
from formula10.database.common_queries import find_single_driver_strict
from formula10.database.model.db_race_result import DbRaceResult
from formula10.frontend.model.driver import NONE_DRIVER, Driver
from formula10.frontend.model.race import Race
class RaceResult:
@classmethod
def from_db_race_result(cls, db_race_result: DbRaceResult):
race_result: RaceResult = cls()
race_result.race = Race.from_db_race(db_race_result.race)
# Deserialize from json
standing: Dict[str, str] = json.loads(db_race_result.pxx_driver_names_json)
initial_dnf: List[str] = json.loads(db_race_result.first_dnf_driver_names_json)
all_dnfs: List[str] = json.loads(db_race_result.dnf_driver_names_json)
standing_exclusions: List[str] = json.loads(db_race_result.excluded_driver_names_json)
# Populate relationships
race_result.standing = {
position: Driver.from_db_driver(find_single_driver_strict(driver_name))
for position, driver_name in standing.items()
}
race_result.initial_dnf = [
Driver.from_db_driver(find_single_driver_strict(driver_name))
for driver_name in initial_dnf
]
race_result.all_dnfs = [
Driver.from_db_driver(find_single_driver_strict(driver_name))
for driver_name in all_dnfs
]
race_result.standing_exclusions = [
Driver.from_db_driver(find_single_driver_strict(driver_name))
for driver_name in standing_exclusions
]
return race_result
def to_db_race_result(self) -> DbRaceResult:
# "Unpopulate" relationships, remove none driver
standing: Dict[str, str] = {
position: driver.name for position, driver in self.standing.items()
}
initial_dnf: List[str] = [
driver.name for driver in self.initial_dnf if driver
]
all_dnfs: List[str] = [
driver.name for driver in self.all_dnfs if driver
]
standing_exclusions: List[str] = [
driver.name for driver in self.standing_exclusions if driver
]
# Serialize to json
db_race_result: DbRaceResult = DbRaceResult(race_name=self.race.name,
pxx_driver_names_json=json.dumps(standing),
first_dnf_driver_names_json=json.dumps(initial_dnf),
dnf_driver_names_json=json.dumps(all_dnfs),
excluded_driver_names_json=json.dumps(standing_exclusions))
return db_race_result
def __eq__(self, __value: object) -> bool:
if isinstance(__value, RaceResult):
return self.race == __value.race
return NotImplemented
race: Race
standing: Dict[str, Driver]
initial_dnf: List[Driver]
all_dnfs: List[Driver]
standing_exclusions: List[Driver]
def offset_from_place_to_guess(self, offset: int, respect_nc:bool = True) -> Driver:
position: str = str(self.race.place_to_guess + offset)
if position not in self.standing:
raise Exception(f"Position {position} not found in RaceResult.standing")
if self.standing[position] in self.standing_exclusions and respect_nc:
return NONE_DRIVER
return self.standing[position]
def driver_standing_position_string(self, driver: Driver) -> str:
if driver == NONE_DRIVER:
return ""
for position, _driver in self.standing.items():
if driver == _driver and driver not in self.standing_exclusions:
return f" (P{position})"
return " (NC)"
def driver_standing_points_string(self, driver: Driver) -> str:
points_strings: Dict[int, str] = {
0: "10 Points",
1: "6 Points",
2: "3 Points",
3: "1 Points"
}
if driver == NONE_DRIVER:
if self.standing[str(self.race.place_to_guess)] in self.standing_exclusions:
return "10 Points"
else:
return "0 Points"
for position, _driver in self.standing.items():
if driver == _driver and driver not in self.standing_exclusions:
position_offset: int = abs(self.race.place_to_guess - int(position))
if position_offset in points_strings:
return points_strings[position_offset]
else:
return "0 Points"
raise Exception(f"Could not get points string for driver {driver.name}")
def driver_dnf_points_string(self, driver: Driver) -> str:
if driver == NONE_DRIVER:
if len(self.initial_dnf) == 0:
return "10 Points"
else:
return "0 Points"
if driver in self.initial_dnf:
return "10 Points"
else:
return "0 Points"
def ordered_standing_list(self) -> List[Driver]:
return [
self.standing[str(position)] for position in range(1, 21)
]
def initial_dnf_string(self) -> str:
if len(self.initial_dnf) == 0:
return NONE_DRIVER.name
dnf_string: str = ""
for driver in self.initial_dnf:
dnf_string += f"{driver.abbr} "
return dnf_string[0:len(dnf_string)-1] # Remove last space

View File

@ -0,0 +1,73 @@
import json
from typing import List
from formula10.database.common_queries import find_single_driver_strict
from formula10.database.model.db_season_guess import DbSeasonGuess
from formula10.frontend.model.driver import Driver
from formula10.frontend.model.team import Team
from formula10.frontend.model.user import User
class SeasonGuess():
@classmethod
def from_db_season_guess(cls, db_season_guess: DbSeasonGuess):
season_guess: SeasonGuess = cls()
season_guess.user = User.from_db_user(db_season_guess.user)
season_guess.hot_take = db_season_guess.hot_take if db_season_guess.hot_take is not None else None
season_guess.p2_wcc = Team.from_db_team(db_season_guess.p2_team) if db_season_guess.p2_team is not None else None
season_guess.most_overtakes = Driver.from_db_driver(db_season_guess.overtake_driver) if db_season_guess.overtake_driver is not None else None
season_guess.most_dnfs = Driver.from_db_driver(db_season_guess.dnf_driver) if db_season_guess.dnf_driver is not None else None
season_guess.most_wdc_gained = Driver.from_db_driver(db_season_guess.gained_driver) if db_season_guess.gained_driver is not None else None
season_guess.most_wdc_lost = Driver.from_db_driver(db_season_guess.lost_driver) if db_season_guess.lost_driver is not None else None
# Deserialize from json
team_winners: List[str | None] = json.loads(db_season_guess.team_winners_driver_names_json)
podiums: List[str] = json.loads(db_season_guess.podium_drivers_driver_names_json)
# Populate relationships
season_guess.team_winners = [
Driver.from_db_driver(find_single_driver_strict(driver_name)) if driver_name is not None else None
for driver_name in team_winners
]
season_guess.podiums = [
Driver.from_db_driver(find_single_driver_strict(driver_name))
for driver_name in podiums
]
return season_guess
def to_db_season_guess(self):
# "Unpopulate" relationships
team_winners: List[str | None] = [
driver.name if driver is not None else None
for driver in self.team_winners
]
podiums: List[str] = [
driver.name for driver in self.podiums
]
# Serialize to json
db_season_guess: DbSeasonGuess = DbSeasonGuess(user_name=self.user.name,
team_winners_driver_names_json=json.dumps(team_winners),
podium_drivers_driver_names_json=json.dumps(podiums))
db_season_guess.user_name = self.user.name
db_season_guess.hot_take = self.hot_take
db_season_guess.p2_team_name = self.p2_wcc.name if self.p2_wcc is not None else None
db_season_guess.overtake_driver_name = self.most_overtakes.name if self.most_overtakes is not None else None
db_season_guess.dnf_driver_name = self.most_dnfs.name if self.most_dnfs is not None else None
db_season_guess.gained_driver_name = self.most_wdc_gained.name if self.most_wdc_gained is not None else None
db_season_guess.lost_driver_name = self.most_wdc_lost.name if self.most_wdc_lost is not None else None
return db_season_guess
user: User
hot_take: str | None
p2_wcc: Team | None
most_overtakes: Driver | None
most_dnfs: Driver | None
most_wdc_gained: Driver | None
most_wdc_lost: Driver | None
team_winners: List[Driver | None]
podiums: List[Driver]
def hot_take_string(self) -> str:
return self.hot_take if self.hot_take is not None else ""

View File

@ -0,0 +1,30 @@
from urllib.parse import quote
from formula10.database.model.db_team import DbTeam
class Team():
@classmethod
def from_db_team(cls, db_team: DbTeam):
team: Team = cls()
team.name = db_team.name
return team
def to_db_team(self) -> DbTeam:
db_team: DbTeam = DbTeam(name=self.name)
return db_team
def __eq__(self, __value: object) -> bool:
if isinstance(__value, Team):
return self.name == __value.name
return NotImplemented
name: str
@property
def name_sanitized(self) -> str:
return quote(self.name)
NONE_TEAM: Team = Team()
NONE_TEAM.name = "None"

View File

@ -0,0 +1,29 @@
from urllib.parse import quote
from formula10.database.model.db_user import DbUser
class User():
@classmethod
def from_db_user(cls, db_user: DbUser):
user: User = cls()
user.name = db_user.name
user.enabled = db_user.enabled
return user
def to_db_user(self) -> DbUser:
db_user: DbUser = DbUser(name=self.name, enabled=self.enabled)
return db_user
def __eq__(self, __value: object) -> bool:
if isinstance(__value, User):
return self.name == __value.name
return NotImplemented
name: str
enabled: bool
@property
def name_sanitized(self) -> str:
return quote(self.name)