Add Card table

Updating factory to do all work in session fixture
This commit is contained in:
Cal Corum 2024-10-13 01:53:20 -05:00
parent 968a2ab609
commit 59fa207212
5 changed files with 170 additions and 58 deletions

View File

@ -13,7 +13,7 @@ from in_game import ai_manager
from in_game.game_helpers import PUBLIC_FIELDS_CATEGORY_NAME, legal_check
from in_game.data_cache import get_pd_team
from in_game.gameplay_models import Lineup, Session, engine, get_player, player_description, select, Game, get_team
from in_game.gameplay_queries import get_channel_game_or_none, get_games_by_team_id
from in_game.gameplay_queries import get_channel_game_or_none, get_active_games_by_team
class Gameplay(commands.Cog):
@ -86,7 +86,7 @@ class Gameplay(commands.Cog):
ai_team = away_team if away_team.is_ai else home_team
human_team = away_team if home_team.is_ai else away_team
conflict_games = get_games_by_team_id(session, team_id=human_team.id)
conflict_games = get_active_games_by_team(session, team_id=human_team.id)
if len(conflict_games) > 0:
await interaction.edit_original_response(
content=f'Ope. The {human_team.sname} are already playing over in {interaction.guild.get_channel(conflict_games[0].channel_id).mention}'

View File

@ -1,10 +1,10 @@
import datetime
import logging
import discord
from sqlmodel import Session, SQLModel, create_engine, select, or_, Field, Relationship
from sqlalchemy import func
from api_calls import db_get
from helpers import PD_SEASON
from api_calls import db_get, db_post
sqlite_url = 'sqlite:///storage/gameplay.db'
@ -41,13 +41,25 @@ class Game(SQLModel, table=True):
game_type: str | None = Field(default=None)
cardset_links: list[GameCardsetLink] = Relationship(back_populates='game')
lineups: list['Lineup'] = Relationship(back_populates='game')
lineups: list['Lineup'] = Relationship(back_populates='game', cascade_delete=True)
@property
def cardset_param_string(self) -> str:
pri_cardsets = ''
back_cardsets = ''
for link in self.cardset_links:
if link.priority == 1:
pri_cardsets += f'&cardset_id={link.cardset_id}'
else:
back_cardsets += f'&backup_cardset_id={link.cardset_id}'
return f'{pri_cardsets}{back_cardsets}'
# @property
# def game_prop(self) -> str:
# return f'Game {self.id} / Week {self.week_num} / Type {self.game_type}'
class CardsetBase(SQLModel):
id: int | None = Field(default=None, primary_key=True)
name: str
@ -59,22 +71,6 @@ class Cardset(CardsetBase, table=True):
players: list['Player'] = Relationship(back_populates='cardset')
class Lineup(SQLModel, table=True):
id: int | None = Field(default=None, primary_key=True)
team_id: int
player_id: int
card_id: int
position: str = Field(index=True)
batting_order: int = Field(index=True)
after_play: int | None = Field(default=0)
replacing_id: int | None = Field(default=None)
active: bool = Field(default=True, index=True)
is_fatigued: bool | None = Field(default=None)
game_id: int = Field(foreign_key='game.id', index=True)
game: Game = Relationship(back_populates='lineups')
class TeamBase(SQLModel):
id: int = Field(primary_key=True)
abbrev: str = Field(index=True)
@ -101,7 +97,8 @@ class TeamBase(SQLModel):
class Team(TeamBase, table=True):
pass
cards: list['Card'] = Relationship(back_populates='team', cascade_delete=True)
lineups: list['Lineup'] = Relationship(back_populates='team', cascade_delete=True)
async def get_team(
@ -148,13 +145,13 @@ async def get_team(
return cache_team(t_query)
elif gm_id is not None:
t_query = await db_get('teams', params=[('season', PD_SEASON), ('gm_id', gm_id)])
t_query = await db_get('teams', params=[('gm_id', gm_id)])
if t_query['count'] != 0:
for team in [x for x in t_query['teams'] if 'gauntlet' not in x['abbrev'].lower()]:
return cache_team(team)
elif team_abbrev is not None:
t_query = await db_get('teams', params=[('season', PD_SEASON), ('abbrev', team_abbrev)])
t_query = await db_get('teams', params=[('abbrev', team_abbrev)])
if t_query['count'] != 0:
for team in [x for x in t_query['teams'] if 'gauntlet' not in x['abbrev'].lower()]:
return cache_team(team)
@ -196,6 +193,84 @@ class PlayerBase(SQLModel):
class Player(PlayerBase, table=True):
cardset: Cardset = Relationship(back_populates='players')
cards: list['Card'] = Relationship(back_populates='player', cascade_delete=True)
lineups: list['Lineup'] = Relationship(back_populates='player', cascade_delete=True)
class CardBase(SQLModel):
id: int | None = Field(default=None, primary_key=True)
player_id: int = Field(foreign_key='player.id', index=True, ondelete='CASCADE')
team_id: int = Field(foreign_key='team.id', index=True, ondelete='CASCADE')
variant: int | None = Field(default=0)
created: datetime.datetime | None = Field(default=datetime.datetime.now())
class Card(CardBase, table=True):
player: Player = Relationship(back_populates='cards')
team: Team = Relationship(back_populates='cards',)
lineups: list['Lineup'] = Relationship(back_populates='card', cascade_delete=True)
async def get_or_create_ai_card(session: Session, player: Player, team: Team) -> Card:
if not team.is_ai:
err = f'Cannot create AI cards for human teams'
logging.error(f'gameplay_models - get_or_create_ai_card: {err}')
raise TypeError(err)
async def pull_card(player, team):
c_query = await db_get('cards', params=[('team_id', team.id), ('player_id', player.id)])
if c_query['count'] > 0:
valid_card = CardBase.model_validate(c_query['cards'][0], from_attributes=True)
db_card = Card.model_validate(valid_card)
session.add(db_card)
session.commit()
session.refresh(db_card)
return db_card
else:
return None
this_card = await pull_card(player, team)
if this_card is not None:
return this_card
logging.info(f'gameplay_models - get_or_create_ai_card: creating {player.description} {player.name} card for {team.abbrev}')
await db_post(
'cards',
payload={'cards': [
{'player_id': player.id, 'team_id': team.id, 'pack_id': 1}
]}
)
this_card = await pull_card(player, team)
if this_card is not None:
return this_card
err = f'Could not create {player.name} card for {team.abbrev}'
logging.error(f'gameplay_models - get_or_create_ai_card - {err}')
raise LookupError(err)
class Lineup(SQLModel, table=True):
id: int | None = Field(default=None, primary_key=True)
position: str = Field(index=True)
batting_order: int = Field(index=True)
after_play: int | None = Field(default=0)
replacing_id: int | None = Field(default=None)
active: bool = Field(default=True, index=True)
is_fatigued: bool | None = Field(default=None)
game_id: int = Field(foreign_key='game.id', index=True, ondelete='CASCADE')
game: Game = Relationship(back_populates='lineups')
team_id: int = Field(foreign_key='team.id', index=True, ondelete='CASCADE')
team: Team = Relationship(back_populates='lineups')
player_id: int = Field(foreign_key='player.id', index=True, ondelete='CASCADE')
player: Player = Relationship(back_populates='lineups')
card_id: int = Field(foreign_key='card.id', index=True, ondelete='CASCADE')
card: Card = Relationship(back_populates='lineups')
def player_description(player: Player = None, player_dict: dict = None) -> str:

View File

@ -17,5 +17,5 @@ def get_channel_game_or_none(session: Session, channel_id: int) -> Game | None:
return all_games[0]
def get_games_by_team_id(session: Session, team_id: int) -> list[Game]:
def get_active_games_by_team(session: Session, team_id: int) -> list[Game]:
return session.exec(select(Game).where(Game.active, or_(Game.away_team_id == team_id, Game.home_team_id == team_id))).all()

View File

@ -14,7 +14,51 @@ def session_fixture():
)
SQLModel.metadata.create_all(engine)
with Session(engine) as session:
yield session
team_1 = Team(
id=31, abbrev='NCB', sname='CornBelters', lname='Normal CornBelters', gmid=1234, gmname='Cal', gsheet='asdf1234', wallet=6969, team_value=69420, collection_value=169420, color='006900', season=7, event=False, career=1234, ranking=1337, has_guide=True, is_ai=False
)
team_2 = Team(
id=400, abbrev='WV', sname='Black Bears', lname='West Virginia Black Bears', gmid=5678, gmname='Evil Cal', gsheet='https://i.postimg.cc/HjDc8bBF/blackbears-transparent.png', wallet=350, team_value=420, collection_value=169, color='6699FF', season=7, event=False, career=2, ranking=969, has_guide=False, is_ai=False
)
team_3 = Team(
id=69, abbrev='NCB3', sname='CornBelters', lname='Normal CornBelters', gmid=1234, gmname='Cal', gsheet='asdf1234', wallet=6969, team_value=69420, collection_value=169420, color='006900', season=7, event=False, career=1234, ranking=1337, has_guide=True, is_ai=False
)
team_4 = Team(
id=420, abbrev='WV4', sname='Black Bears', lname='West Virginia Black Bears', gmid=5678, gmname='Evil Cal', gsheet='https://i.postimg.cc/HjDc8bBF/blackbears-transparent.png', wallet=350, team_value=420, collection_value=169, color='6699FF', season=7, event=False, career=2, ranking=969, has_guide=False, is_ai=False
)
incomplete_team = Team(
id=446, abbrev='CLS', sname='Macho Men', lname='Columbus Macho Men', gmid=181818, gmname='Mason Socc', gsheet='asdf1234', wallet=6969, team_value=69420, collection_value=169420, color='https://i.postimg.cc/8kLZCYXh/S10CLS.png', season=7, event=False, career=0
)
old_cache_team = Team(
id=3, abbrev='BAL', sname='Orioles', lname='Baltimore Orioles', gmid=181818, gmname='Brandon Hyde', gsheet='asdf1234', wallet=6969, team_value=69420, collection_value=169420, color='https://i.postimg.cc/8kLZCYXh/S10CLS.png', season=7, event=False, career=0, ranking=500, has_guide=False, is_ai=False, created=datetime.datetime.today() - datetime.timedelta(days=60)
)
session.add(team_1)
session.add(team_2)
session.add(team_3)
session.add(team_4)
# session.add(incomplete_team)
session.add(old_cache_team)
session.commit()
game_1 = Game(away_team_id=1, home_team_id=2, channel_id=1234, season=9)
game_2 = Game(away_team_id=4, home_team_id=3, channel_id=5678, season=9, active=False, is_pd=True, ranked=True, week_num=6, game_num=9, away_roster_id=69, home_roster_id=420, first_message=12345678, ai_team='home', game_type='minor-league')
game_3 = Game(away_team_id=3, home_team_id=4, channel_id=5678, season=9, active=True, is_pd=True, ranked=True, week_num=6, game_num=10, away_roster_id=69, home_roster_id=420, first_message=34567890, ai_team='home', game_type='minor-league')
session.add(game_1)
session.add(game_2)
session.add(game_3)
session.commit()
# all_lineups = []
# for team in [team_1, team_2]:
# for (order, pos) in [(1, 'C'), (2, '1B'), (3, '2B'), (4, '3B'), (5, 'SS'), (6, 'LF'), (7, 'CF'), (8, 'RF'), (9, 'DH'), (10, 'P')]:
# all_lineups.append(Lineup(team_id=team, card_id=order, player_id=68+order, position=pos, batting_order=order, game=game_1))
# for team in [team_3, team_4]:
# for (order, pos) in [(1, 'C'), (2, '1B'), (3, '2B'), (4, '3B'), (5, 'SS'), (6, 'LF'), (7, 'CF'), (8, 'RF'), (9, 'DH'), (10, 'P')]:
# all_lineups.append(Lineup(team_id=team, card_id=order, player_id=100+order, position=pos, batting_order=order, game=game_3))
yield session
@pytest.fixture(name='new_games')

View File

@ -1,17 +1,15 @@
import pytest
from sqlalchemy import delete
from sqlmodel import Session
from in_game.gameplay_models import Game, select
from in_game.gameplay_queries import get_games_by_channel, get_channel_game_or_none, get_games_by_team_id
from in_game.gameplay_queries import get_games_by_channel, get_channel_game_or_none, get_active_games_by_team
from factory import session_fixture, new_games_fixture
def test_create_game(session: Session, new_games: list[Game]):
game_1 = new_games[0]
game_2 = new_games[1]
session.add(game_1)
session.add(game_2)
session.commit()
game_1 = session.get(Game, 1)
game_2 = session.get(Game, 2)
assert game_1.away_team_id == 1
assert game_1.home_team_id == 2
@ -39,25 +37,23 @@ def test_create_game(session: Session, new_games: list[Game]):
assert game_2.game_type == 'minor-league'
def test_select_all_empty(session: Session):
def test_select_all(session: Session):
games = session.exec(select(Game)).all()
assert len(games) == 3
session.execute(delete(Game))
session.commit()
games = session.exec(select(Game)).all()
assert len(games) == 0
def test_games_by_channel(session: Session, new_games: list[Game]):
game_1 = new_games[0]
game_2 = new_games[1]
game_3 = new_games[2]
session.add(game_1)
session.add(game_2)
session.add(game_3)
session.commit()
assert get_channel_game_or_none(session, 1234) is not None
assert get_channel_game_or_none(session, 5678) is not None
assert get_channel_game_or_none(session, 69) is None
game_2 = session.get(Game, 2)
game_2.active = True
session.add(game_2)
session.commit()
@ -67,6 +63,7 @@ def test_games_by_channel(session: Session, new_games: list[Game]):
assert str(exc_info) == "<ExceptionInfo LookupError('Too many games found in get_channel_game_or_none') tblen=2>"
game_3 = session.get(Game, 3)
game_2.active = False
game_3.active = False
session.add(game_2)
@ -77,24 +74,20 @@ def test_games_by_channel(session: Session, new_games: list[Game]):
def test_games_by_team(session: Session, new_games: list[Game]):
game_1 = new_games[1]
game_2 = new_games[2]
session.add(game_1)
assert len(get_active_games_by_team(session, team_id=3)) == 1
game_2 = session.get(Game, 2)
game_2.active = True
session.add(game_2)
session.commit()
assert len(get_games_by_team_id(session, team_id=3)) == 1
assert len(get_active_games_by_team(session, team_id=3)) == 2
game_1.active = True
session.add(game_1)
session.commit()
assert len(get_games_by_team_id(session, team_id=3)) == 2
game_1.active = False
game_3 = session.get(Game, 3)
game_3.active = False
game_2.active = False
session.add(game_1)
session.add(game_3)
session.add(game_2)
session.commit()
assert len(get_games_by_team_id(session, team_id=3)) == 0
assert len(get_active_games_by_team(session, team_id=3)) == 0