Added designers to boardgames (howly mowly)

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

1
.gitignore vendored
View file

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

View file

@ -1,6 +1,7 @@
from datetime import date from datetime import date
from enum import Enum from enum import Enum
from sqlmodel import Field, SQLModel, Relationship from sqlmodel import Field, SQLModel, Relationship
from src.classes import many_to_many_links
class BoardgameType(Enum): class BoardgameType(Enum):
@ -42,14 +43,17 @@ class BoardGame(BoardGameBase, table=True):
id: int = Field(primary_key=True) id: int = Field(primary_key=True)
type: BoardgameType = BoardgameType.BOARDGAME type: BoardgameType = BoardgameType.BOARDGAME
plays: list["Play"] = Relationship(back_populates='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): class BoardGamePublic(BoardGameBase):
id: int id: int
type: BoardgameType type: BoardgameType
plays: list["Play"] plays: list["Play"]
designers: list["Designer"]
class BoardGameNoPlays(BoardGameBase): class BoardGameNoPlays(BoardGameBase):
id: int id: int
designers: list["Designer"]
type: BoardgameType = BoardgameType.BOARDGAME type: BoardgameType = BoardgameType.BOARDGAME
class BoardGameExpansion(BoardGameBase, table=True): class BoardGameExpansion(BoardGameBase, table=True):
@ -57,16 +61,19 @@ class BoardGameExpansion(BoardGameBase, table=True):
expansion_for: int = Field(default=None, foreign_key="boardgame.id") expansion_for: int = Field(default=None, foreign_key="boardgame.id")
type: BoardgameType = BoardgameType.BOARDGAMEEXPANSION type: BoardgameType = BoardgameType.BOARDGAMEEXPANSION
plays: list["Play"] = Relationship(back_populates='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): class BoardGameExpansionPublic(BoardGameBase):
id: int id: int
expansion_for: int expansion_for: int
type: BoardgameType type: BoardgameType
plays: list["Play"] plays: list["Play"]
designers: list["Designer"]
class BoardGameExpansionNoPlays(BoardGameBase): class BoardGameExpansionNoPlays(BoardGameBase):
id: int id: int
expansion_for: int expansion_for: int
designers: list["Designer"]
type: BoardgameType = BoardgameType.BOARDGAMEEXPANSION type: BoardgameType = BoardgameType.BOARDGAMEEXPANSION
class OwnedBoardGame(OwnedBoardGameBase, table=True): 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.play_classes import Play, PlayPublic
from src.classes.people_classes import Designer
BoardGame.model_rebuild() BoardGame.model_rebuild()
BoardGameExpansion.model_rebuild() BoardGameExpansion.model_rebuild()
BoardGameNoPlays.model_rebuild()
BoardGameExpansionNoPlays.model_rebuild()

View file

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

View file

@ -1,5 +1,4 @@
from typing import Union from typing import Union
from datetime import date, timedelta, datetime
from pydantic import BaseModel from pydantic import BaseModel
from sqlmodel import Session from sqlmodel import Session
from threading import Thread from threading import Thread
@ -15,7 +14,7 @@ from src.filters import boardgame_filters, play_filters
is_refreshing = False is_refreshing = False
def get_session(): async def get_session():
with Session(data_connection.get_db_engine()) as session: with Session(data_connection.get_db_engine()) as session:
yield session yield session
@ -114,6 +113,15 @@ def get_owned_collection(query: BoardgameFilterParams = Depends(), session: Sess
return to_return_boardgames 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]]) @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)): 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 import html
from tqdm import tqdm from tqdm import tqdm
from src.classes import boardgame_classes, play_classes from sqlmodel import Session, select
from src.modules import auth_manager
from src.classes import boardgame_classes, play_classes, people_classes
from src.modules import auth_manager, data_connection
from src.config import definitions from src.config import definitions
authenticated_session: requests.Session = requests.Session() authenticated_session: requests.Session = requests.Session()
def url_to_xml_object(url: HttpUrl) -> ET.Element: 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') all_links = boardgame_xml.findall('link')
designers = []
for link in all_links: for link in all_links:
if link.get('type') == 'boardgameexpansion': match link.get('type'):
expansion_ids.append(int(link.get('id'))) 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 = { boardgame_dict = {
"id" : int(boardgame_xml.get('id')), "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')), "max_players" : int(boardgame_xml.find('maxplayers').get('value')),
"min_playing_time" : int(boardgame_xml.find('minplaytime').get('value')), "min_playing_time" : int(boardgame_xml.find('minplaytime').get('value')),
"max_playing_time" : int(boardgame_xml.find('maxplaytime').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: match boardgame_type:

View file

@ -21,8 +21,19 @@ def get_boardgame(session: Session, boardgame_id: int) -> Union[boardgame_classe
to_return_boardgame = boardgame_in_db to_return_boardgame = boardgame_in_db
else: else:
to_return_boardgame = bgg_connection.get_boardgame(boardgame_id) 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) db_connection.add_boardgame(session, to_return_boardgame)
to_return_boardgame = db_connection.get_boardgame(session, boardgame_id) to_return_boardgame = db_connection.get_boardgame(session, boardgame_id)
return to_return_boardgame 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: if len(boardgame_ids_missing) != 0:
missing_boardgames = bgg_connection.get_multiple_boardgames(boardgame_ids_missing) 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) db_connection.add_multiple_boardgames(session, missing_boardgames)
boardgames_in_db, boardgame_ids_missing = db_connection.get_multiple_boardgames(session, boardgame_ids=boardgame_ids) boardgames_in_db, boardgame_ids_missing = db_connection.get_multiple_boardgames(session, boardgame_ids=boardgame_ids)
return boardgames_in_db 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) 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) 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: if len(boardgames_from_db) == 0 and len(boardgame_expansions_from_db) == 0:
boardgames = bgg_connection.get_user_collection() boardgames = bgg_connection.get_user_collection()
#db_connection.add_boardgame(session, boardgame)
db_connection.add_multiple_boardgames(session, boardgames) db_connection.add_multiple_boardgames(session, boardgames)
boardgames_from_db: list[boardgame_classes.BoardGame] = db_connection.get_all_boardgames(session, boardgame_classes.BoardGame) 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 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 return plays_from_db

View file

@ -5,13 +5,13 @@ from threading import Lock
critical_function_lock = 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 sqlite_url = definitions.SQLITE_URL
connect_args = {"check_same_thread": False} 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(): def get_engine():
return engine return engine
@ -22,14 +22,20 @@ def add_boardgame(session: Session, boardgame: Union[
boardgame_classes.WishlistBoardGame, boardgame_classes.WishlistBoardGameExpansion]): boardgame_classes.WishlistBoardGame, boardgame_classes.WishlistBoardGameExpansion]):
with critical_function_lock: 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( is_boardgame_present = len(session.exec(
select(boardgame.__class__).where(boardgame.__class__.id == boardgame.id) select(boardgame.__class__).where(boardgame.__class__.id == boardgame.id)
).all()) != 0 ).all()) != 0
if not is_boardgame_present: if not is_boardgame_present:
session.add(boardgame) session.add(boardgame)
session.commit() session.commit()
session.refresh(boardgame)
def add_multiple_boardgames(session: Session, boardgame_list: list[Union[ def add_multiple_boardgames(session: Session, boardgame_list: list[Union[
boardgame_classes.BoardGame, boardgame_classes.BoardGameExpansion, 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]]): boardgame_classes.WishlistBoardGame, boardgame_classes.WishlistBoardGameExpansion]]):
with critical_function_lock: with critical_function_lock:
for boardgame in boardgame_list: altered_boardgames = []
is_boardgame_present = len(session.exec( for boardgame_index in range(len(boardgame_list)):
select(boardgame.__class__).where(boardgame.__class__.id == boardgame.id) boardgame_designers = boardgame_list[boardgame_index].designers
).all()) != 0 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: if not is_boardgame_present:
session.add(boardgame) session.add(boardgame_list[boardgame_index])
altered_boardgames.append(boardgame_list[boardgame_index])
session.commit() 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[ def get_boardgame(session: Session, boardgame_id: int) -> Union[
boardgame_classes.BoardGame, boardgame_classes.BoardGameExpansion]: boardgame_classes.BoardGame, boardgame_classes.BoardGameExpansion]:
@ -104,6 +142,7 @@ def add_play(session: Session, play: play_classes.Play):
session.add(play) session.add(play)
session.commit() session.commit()
session.refresh(play)
def add_multiple_plays(session: Session, play_list: list[play_classes.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.add(play)
session.commit() session.commit()
[session.refresh(play) for play in play_list]
def get_plays(session: Session, ) -> list[play_classes.Play]: def get_plays(session: Session, ) -> list[play_classes.Play]:
statement = select(play_classes.Play) statement = select(play_classes.Play)