Added designers to boardgames (howly mowly)

This commit is contained in:
Yarne Coppens 2024-08-19 13:50:27 +02:00
parent 35f104cedc
commit c1ae021dae
9 changed files with 141 additions and 18 deletions

1
.gitignore vendored
View file

@ -162,3 +162,4 @@ cython_debug/
secrets/auth.yaml
db/database.db
.vscode/

View file

@ -1,6 +1,7 @@
from datetime import date
from enum import Enum
from sqlmodel import Field, SQLModel, Relationship
from src.classes import many_to_many_links
class BoardgameType(Enum):
@ -42,14 +43,17 @@ class BoardGame(BoardGameBase, table=True):
id: int = Field(primary_key=True)
type: BoardgameType = BoardgameType.BOARDGAME
plays: list["Play"] = Relationship(back_populates='boardgame')
designers: list["Designer"] = Relationship(back_populates="designed_boardgames", link_model=many_to_many_links.DesignerBoardGameLink)
class BoardGamePublic(BoardGameBase):
id: int
type: BoardgameType
plays: list["Play"]
designers: list["Designer"]
class BoardGameNoPlays(BoardGameBase):
id: int
designers: list["Designer"]
type: BoardgameType = BoardgameType.BOARDGAME
class BoardGameExpansion(BoardGameBase, table=True):
@ -57,16 +61,19 @@ class BoardGameExpansion(BoardGameBase, table=True):
expansion_for: int = Field(default=None, foreign_key="boardgame.id")
type: BoardgameType = BoardgameType.BOARDGAMEEXPANSION
plays: list["Play"] = Relationship(back_populates='boardgameexpansion')
designers: list["Designer"] = Relationship(back_populates="designed_expansions", link_model=many_to_many_links.DesignerBoardGameExpansionLink)
class BoardGameExpansionPublic(BoardGameBase):
id: int
expansion_for: int
type: BoardgameType
plays: list["Play"]
designers: list["Designer"]
class BoardGameExpansionNoPlays(BoardGameBase):
id: int
expansion_for: int
designers: list["Designer"]
type: BoardgameType = BoardgameType.BOARDGAMEEXPANSION
class OwnedBoardGame(OwnedBoardGameBase, table=True):
@ -91,5 +98,8 @@ class WishlistBoardGameExpansion(WishlistBoardGameBase, table=True):
from src.classes.play_classes import Play, PlayPublic
from src.classes.people_classes import Designer
BoardGame.model_rebuild()
BoardGameExpansion.model_rebuild()
BoardGameNoPlays.model_rebuild()
BoardGameExpansionNoPlays.model_rebuild()

View file

@ -0,0 +1,9 @@
from sqlmodel import Field,SQLModel
class DesignerBoardGameLink(SQLModel, table=True):
boardgame_id: int | None = Field(default=None, foreign_key="boardgame.id", primary_key=True)
designer_id: int | None = Field(default=None, foreign_key="designer.id", primary_key=True)
class DesignerBoardGameExpansionLink(SQLModel, table=True):
boardgame_id: int | None = Field(default=None, foreign_key="boardgameexpansion.id", primary_key=True)
designer_id: int | None = Field(default=None, foreign_key="designer.id", primary_key=True)

View file

@ -0,0 +1,9 @@
from sqlmodel import Field, SQLModel, Relationship
from src.classes import boardgame_classes, many_to_many_links
class Designer(SQLModel, table=True):
id: int = Field(primary_key=True)
name: str
designed_boardgames: list[boardgame_classes.BoardGame] | None = Relationship(back_populates="designers", link_model=many_to_many_links.DesignerBoardGameLink)
designed_expansions: list[boardgame_classes.BoardGameExpansion] | None = Relationship(back_populates="designers", link_model=many_to_many_links.DesignerBoardGameExpansionLink)

View file

@ -55,5 +55,6 @@ class PlayPublicWithPlayers(PlayPublic):
from src.classes.boardgame_classes import BoardGame, BoardGameExpansion, BoardGameNoPlays, BoardGameExpansionNoPlays
from src.classes.people_classes import Designer
Play.model_rebuild()
PlayPublicWithPlayers.model_rebuild()

View file

@ -1,5 +1,4 @@
from typing import Union
from datetime import date, timedelta, datetime
from pydantic import BaseModel
from sqlmodel import Session
from threading import Thread
@ -15,7 +14,7 @@ from src.filters import boardgame_filters, play_filters
is_refreshing = False
def get_session():
async def get_session():
with Session(data_connection.get_db_engine()) as session:
yield session
@ -114,6 +113,15 @@ def get_owned_collection(query: BoardgameFilterParams = Depends(), session: Sess
return to_return_boardgames
@app.get('/collection', response_model=list[Union[boardgame_classes.BoardGame, boardgame_classes.BoardGameExpansion]])
def get_collection(query: BoardgameFilterParams = Depends(), session: Session = Depends(get_session)):
to_return_boardgames = data_connection.get_user_collection(session)
to_return_boardgames = query.do_filtering(to_return_boardgames)
to_return_boardgames.sort(key=lambda x: x.name)
return to_return_boardgames
@app.get("/wishlist", response_model=list[Union[boardgame_classes.WishlistBoardGame, boardgame_classes.WishlistBoardGameExpansion]])
def get_wishlist_collection(priority: int = 0, query: BoardgameFilterParams = Depends(), session: Session = Depends(get_session)):

View file

@ -9,10 +9,13 @@ from typing import Union
import html
from tqdm import tqdm
from src.classes import boardgame_classes, play_classes
from src.modules import auth_manager
from sqlmodel import Session, select
from src.classes import boardgame_classes, play_classes, people_classes
from src.modules import auth_manager, data_connection
from src.config import definitions
authenticated_session: requests.Session = requests.Session()
def url_to_xml_object(url: HttpUrl) -> ET.Element:
@ -79,9 +82,17 @@ def convert_xml_to_boardgame(boardgame_xml: ET.Element) -> Union[boardgame_class
all_links = boardgame_xml.findall('link')
designers = []
for link in all_links:
if link.get('type') == 'boardgameexpansion':
expansion_ids.append(int(link.get('id')))
match link.get('type'):
case 'boardgameexpansion':
expansion_ids.append(int(link.get('id')))
case 'boardgamedesigner':
designer_id = int(link.get('id'))
designer_name = link.get('value')
designer = people_classes.Designer(id=designer_id, name=designer_name)
designers.append(designer)
boardgame_dict = {
"id" : int(boardgame_xml.get('id')),
@ -95,7 +106,8 @@ def convert_xml_to_boardgame(boardgame_xml: ET.Element) -> Union[boardgame_class
"max_players" : int(boardgame_xml.find('maxplayers').get('value')),
"min_playing_time" : int(boardgame_xml.find('minplaytime').get('value')),
"max_playing_time" : int(boardgame_xml.find('maxplaytime').get('value')),
"min_age" : int(boardgame_xml.find('minage').get('value'))
"min_age" : int(boardgame_xml.find('minage').get('value')),
"designers" : designers
}
match boardgame_type:

View file

@ -21,9 +21,20 @@ def get_boardgame(session: Session, boardgame_id: int) -> Union[boardgame_classe
to_return_boardgame = boardgame_in_db
else:
to_return_boardgame = bgg_connection.get_boardgame(boardgame_id)
boardgame_new_linked_designers = []
# for designer in to_return_boardgame.designers:
# designer_in_db = db_connection.get_designer(session, designer.id)
# if designer_in_db == None:
# db_connection.add_designer(session, designer)
# designer_in_db = db_connection.get_designer(session, designer.id)
# boardgame_new_linked_designers.append(designer_in_db)
# to_return_boardgame.designers = boardgame_new_linked_designers
db_connection.add_boardgame(session, to_return_boardgame)
to_return_boardgame = db_connection.get_boardgame(session, boardgame_id)
return to_return_boardgame
@ -32,18 +43,40 @@ def get_multiple_boardgames(session: Session, boardgame_ids: list[int]) -> list[
if len(boardgame_ids_missing) != 0:
missing_boardgames = bgg_connection.get_multiple_boardgames(boardgame_ids_missing)
# for boardgame in missing_boardgames:
# db_connection.add_multiple_designers(session, boardgame.designers)
# boardgame.designers, missing_designer_ids = db_connection.get_multiple_designers(session, [designer.id for designer in boardgame.designers])
# assert len(missing_designer_ids) == 0, "This list should be empty"
# missing_boardgames_linked_people = []
# for boardgame in missing_boardgames:
# boardgame_new_linked_designers = []
# for designer in boardgame.designers:
# designer_in_db = db_connection.get_designer(session, designer.id)
# if designer_in_db == None:
# db_connection.add_designer(session, designer)
# designer_in_db = db_connection.get_designer(session, designer.id)
# boardgame_new_linked_designers.append(designer_in_db)
# boardgame.designers = boardgame_new_linked_designers
# session.refresh(boardgame)
db_connection.add_multiple_boardgames(session, missing_boardgames)
boardgames_in_db, boardgame_ids_missing = db_connection.get_multiple_boardgames(session, boardgame_ids=boardgame_ids)
return boardgames_in_db
def get_user_collection(session: Session, ) -> list[Union[boardgame_classes.BoardGame, boardgame_classes.OwnedBoardGame]]:
def get_user_collection(session: Session) -> list[Union[boardgame_classes.BoardGame, boardgame_classes.OwnedBoardGame]]:
boardgames_from_db: list[boardgame_classes.BoardGame] = db_connection.get_all_boardgames(session, boardgame_classes.BoardGame)
boardgame_expansions_from_db: list[boardgame_classes.BoardGameExpansion] = db_connection.get_all_boardgames(session, boardgame_classes.BoardGameExpansion)
if len(boardgames_from_db) == 0 and len(boardgame_expansions_from_db) == 0:
boardgames = bgg_connection.get_user_collection()
#db_connection.add_boardgame(session, boardgame)
db_connection.add_multiple_boardgames(session, boardgames)
boardgames_from_db: list[boardgame_classes.BoardGame] = db_connection.get_all_boardgames(session, boardgame_classes.BoardGame)
@ -110,7 +143,7 @@ def get_plays(session: Session) -> list[play_classes.Play]:
assert len(list(filter(lambda x: x == None, played_boardgame_ids))) == 0, plays_from_db
get_multiple_boardgames(session, played_boardgame_ids + played_expansion_ids)
#get_multiple_boardgames(session, played_boardgame_ids + played_expansion_ids)
return plays_from_db

View file

@ -5,13 +5,13 @@ from threading import Lock
critical_function_lock = Lock()
from src.classes import boardgame_classes, play_classes
from src.classes import boardgame_classes, play_classes, people_classes
sqlite_url = definitions.SQLITE_URL
connect_args = {"check_same_thread": False}
engine = create_engine(sqlite_url, echo=False, connect_args=connect_args)
engine = create_engine(sqlite_url, echo=True, connect_args=connect_args)
def get_engine():
return engine
@ -22,14 +22,20 @@ def add_boardgame(session: Session, boardgame: Union[
boardgame_classes.WishlistBoardGame, boardgame_classes.WishlistBoardGameExpansion]):
with critical_function_lock:
boardgame_designers = boardgame.designers
for designer_index in range(len(boardgame_designers)):
designer_in_db = get_designer(session, boardgame_designers[designer_index].id)
if designer_in_db != None:
boardgame.designers[designer_index] = designer_in_db
is_boardgame_present = len(session.exec(
select(boardgame.__class__).where(boardgame.__class__.id == boardgame.id)
).all()) != 0
if not is_boardgame_present:
session.add(boardgame)
session.commit()
session.refresh(boardgame)
def add_multiple_boardgames(session: Session, boardgame_list: list[Union[
boardgame_classes.BoardGame, boardgame_classes.BoardGameExpansion,
@ -37,15 +43,47 @@ def add_multiple_boardgames(session: Session, boardgame_list: list[Union[
boardgame_classes.WishlistBoardGame, boardgame_classes.WishlistBoardGameExpansion]]):
with critical_function_lock:
for boardgame in boardgame_list:
is_boardgame_present = len(session.exec(
select(boardgame.__class__).where(boardgame.__class__.id == boardgame.id)
).all()) != 0
altered_boardgames = []
for boardgame_index in range(len(boardgame_list)):
boardgame_designers = boardgame_list[boardgame_index].designers
for designer_index in range(len(boardgame_designers)):
designer_in_db = get_designer(session, boardgame_designers[designer_index].id)
if designer_in_db != None:
boardgame_list[boardgame_index].designers[designer_index] = designer_in_db
statement = select(boardgame_list[boardgame_index].__class__).where(boardgame_list[boardgame_index].__class__.id == boardgame_list[boardgame_index].id)
is_boardgame_present = len(session.exec(statement).all()) != 0
if not is_boardgame_present:
session.add(boardgame)
session.add(boardgame_list[boardgame_index])
altered_boardgames.append(boardgame_list[boardgame_index])
session.commit()
[session.refresh(boardgame) for boardgame in altered_boardgames]
def get_designer(session: Session, designer_id: int) -> people_classes.Designer:
statement = select(people_classes.Designer).where(people_classes.Designer.id == designer_id)
designer = session.exec(statement).all()
if len(designer) == 0:
designer = None
else:
designer = designer[0]
return designer
def get_multiple_designers(session: Session, designer_ids: list[int]) -> list[people_classes.Designer]:
statement = select(people_classes.Designer).where(people_classes.Designer.id.in_(designer_ids))
results = session.exec(statement)
designers = results.all()
missing_designer_ids = list(filter(lambda x: x not in [designer.id for designer in designers], designer_ids))
return designers, missing_designer_ids
def get_boardgame(session: Session, boardgame_id: int) -> Union[
boardgame_classes.BoardGame, boardgame_classes.BoardGameExpansion]:
@ -104,6 +142,7 @@ def add_play(session: Session, play: play_classes.Play):
session.add(play)
session.commit()
session.refresh(play)
def add_multiple_plays(session: Session, play_list: list[play_classes.Play]):
@ -115,6 +154,7 @@ def add_multiple_plays(session: Session, play_list: list[play_classes.Play]):
session.add(play)
session.commit()
[session.refresh(play) for play in play_list]
def get_plays(session: Session, ) -> list[play_classes.Play]:
statement = select(play_classes.Play)