From fb5995c88fcc7a6399f533317ab9c2cbb27c8776 Mon Sep 17 00:00:00 2001 From: Yarne Coppens Date: Fri, 6 Sep 2024 09:18:03 +0200 Subject: [PATCH] Added preordered games endpoint --- src/classes/boardgame_classes.py | 24 +++++++++++++++++ src/main.py | 12 +++++++++ src/modules/bgg_connection.py | 45 ++++++++++++++++++++++++++++++++ src/modules/data_connection.py | 13 +++++++++ src/modules/db_connection.py | 9 +++++++ 5 files changed, 103 insertions(+) diff --git a/src/classes/boardgame_classes.py b/src/classes/boardgame_classes.py index 40484bb..348679d 100644 --- a/src/classes/boardgame_classes.py +++ b/src/classes/boardgame_classes.py @@ -12,6 +12,8 @@ class BoardgameType(Enum): OWNEDBOARDGAMEEXPANSION = 'ownedboardgameexpansion' WISHLISTBOARDGAME = 'wishlistboardgame' WISHLISTBOARDGAMEEXPANSION = 'wishlistboardgameexpansion' + PREORDEREDBOARDGAME = 'preorderedboargame' + PREORDEREDBOARDGAMEEXPANSION = 'preorderedboargameexpansion' class BoardGameBase(SQLModel): @@ -43,6 +45,8 @@ class BoardGame(BoardGameBase, table=True): wishlist_info: Optional["WishlistInfo"] = Relationship(back_populates="boardgame") + preordered_info: Optional["PreorderedInfo"] = Relationship(back_populates="boardgame") + plays: list["Play"] = Relationship(back_populates='boardgame') model_config = { @@ -56,6 +60,7 @@ class BoardGamePublic(BoardGameBase): expansion_info: Optional["ExpansionInfoPublicNoGame"] owned_info: Optional["OwnedInfoPublicNoGame"] wishlist_info: Optional["WishlistInfoPublicNoGame"] + preordered_info: Optional["PreorderedInfoPublicNoGame"] plays: list["PlayPublicNoGame"] class BoardGamePublicNoPlays(BoardGameBase): @@ -65,6 +70,7 @@ class BoardGamePublicNoPlays(BoardGameBase): expansion_info: Optional["ExpansionInfoPublicNoGame"] owned_info: Optional["OwnedInfoPublicNoGame"] wishlist_info: Optional["WishlistInfoPublicNoGame"] + preordered_info: Optional["PreorderedInfoPublicNoGame"] class ExpansionInfo(SQLModel, table=True): @@ -129,6 +135,24 @@ class WishlistInfoPublicNoGame(SQLModel): wishlist_priority: int +class PreorderedInfo(SQLModel, table=True): + id: Optional[int] = Field(default=None, primary_key=True) + arrival_date: date + + boardgame_id: int | None = Field(default=None, foreign_key="boardgame.id") + boardgame: BoardGame = Relationship( + #for one-on-one relationship + sa_relationship_kwargs={'uselist': False}, + back_populates="preordered_info" + ) + +class PreorderedInfoPublic(SQLModel): + arrival_date: date + boardgame: BoardGame + +class PreorderedInfoPublicNoGame(SQLModel): + arrival_date: date + from src.classes.play_classes import Play, PlayPublicNoGame from src.classes.people_classes import Designer, DesignerPublicNoGames, Artist, ArtistPublicNoGames BoardGame.model_rebuild() \ No newline at end of file diff --git a/src/main.py b/src/main.py index 60305cb..6aa94f7 100644 --- a/src/main.py +++ b/src/main.py @@ -29,6 +29,7 @@ def refresh_data(): data_connection.get_user_collection(session) data_connection.get_user_owned_collection(session) data_connection.get_user_wishlist_collection(session) + data_connection.get_user_preordered_collection(session) data_connection.get_plays(session) print('DONE') @@ -142,6 +143,17 @@ def get_wishlist_collection(priority: int = 0, query: BoardgameFilterParams = De return to_return_boardgames +@app.get("/preordered", response_model=list[boardgame_classes.BoardGamePublicNoPlays]) +def get_preordered_collection(query: BoardgameFilterParams = Depends(), session: Session = Depends(get_session)): + + to_return_boardgames = data_connection.get_user_preordered_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("/plays", response_model=list[play_classes.PlayPublic]) def get_plays(query: PlayFilterParams = Depends(), boardgame_id: int = -1, session: Session = Depends(get_session)): diff --git a/src/modules/bgg_connection.py b/src/modules/bgg_connection.py index bc94087..0d165e3 100644 --- a/src/modules/bgg_connection.py +++ b/src/modules/bgg_connection.py @@ -196,6 +196,35 @@ def convert_collection_xml_to_wishlist_boardgame(boardgame_extra_info: boardgame return boardgame +def convert_collection_xml_to_preordered_boardgame(boardgame_extra_info: boardgame_classes.BoardGame, collection_boardgame_xml: ET.Element) -> boardgame_classes.BoardGame: + + date_string = collection_boardgame_xml.find('privateinfo').get('acquisitiondate') + if date_string == '': + date_string = '2020-01-01' + + acquisition_date = datetime.strptime(date_string, '%Y-%m-%d').date() + + preordered_boardgame_dict = { + "arrival_date" : acquisition_date + } + + preordered_info = boardgame_classes.PreorderedInfo.model_validate(preordered_boardgame_dict) + + boardgame_extra_info.preordered_info = preordered_info + + boardgame_version_info = collection_boardgame_xml.find('version') + + if boardgame_version_info != None: + boardgame_extra_info_item = boardgame_version_info.find('item') + boardgame_extra_info.name = collection_boardgame_xml.find('name').text if boardgame_extra_info_item.find('name') != None else boardgame_extra_info.name + boardgame_extra_info.image_url = boardgame_extra_info_item.find('image').text if boardgame_extra_info_item.find('image') != None else boardgame_extra_info.image_url + boardgame_extra_info.thumbnail_url = boardgame_extra_info_item.find('thumbnail').text if boardgame_extra_info_item.find('thumbnail') != None else boardgame_extra_info.thumbnail_url + boardgame_extra_info.year_published = boardgame_extra_info_item.find('yearpublished').get('value') if boardgame_extra_info_item.find('yearpublished') != None else boardgame_extra_info.year_published + + boardgame = boardgame_extra_info + + return boardgame + def convert_playplayer_xml_to_playplayer(playplayer_xml: ET.Element) -> play_classes.PlayPlayer: score = playplayer_xml.get('score') @@ -280,6 +309,10 @@ def get_boardgames_from_collection_url(collection_url: str, boardgame_type: boar boardgame = convert_collection_xml_to_wishlist_boardgame(boardgame_extra, boardgame_item) case boardgame_classes.BoardgameType.WISHLISTBOARDGAMEEXPANSION: boardgame = convert_collection_xml_to_wishlist_boardgame(boardgame_extra, boardgame_item) + case boardgame_classes.BoardgameType.PREORDEREDBOARDGAME: + boardgame = convert_collection_xml_to_preordered_boardgame(boardgame_extra, boardgame_item) + case boardgame_classes.BoardgameType.PREORDEREDBOARDGAMEEXPANSION: + boardgame = convert_collection_xml_to_preordered_boardgame(boardgame_extra, boardgame_item) boardgame.type = boardgame_type collection_list.append(boardgame) current_index += 1 @@ -320,6 +353,18 @@ def get_user_wishlist_collection() -> list[boardgame_classes.BoardGame]: return wishlisted_boardgames +def get_user_preordered_collection() -> list[boardgame_classes.BoardGame]: + url_no_expanions = 'https://boardgamegeek.com/xmlapi2/collection?username={}&preordered=1&stats=1&excludesubtype=boardgameexpansion&showprivate=1&version=1'.format(auth_manager.username) + url_only_expansions = 'https://boardgamegeek.com/xmlapi2/collection?username={}&preordered=1&stats=1&subtype=boardgameexpansion&showprivate=1&version=1'.format(auth_manager.username) + + preordered_boardgames = get_boardgames_from_collection_url(url_no_expanions, boardgame_classes.BoardgameType.PREORDEREDBOARDGAME) + preordered_boardgame_expansions = get_boardgames_from_collection_url(url_only_expansions, boardgame_classes.BoardgameType.PREORDEREDBOARDGAMEEXPANSION) + + preordered_boardgames += preordered_boardgame_expansions + + + return preordered_boardgames + def get_plays() -> list[play_classes.Play]: diff --git a/src/modules/data_connection.py b/src/modules/data_connection.py index 7e39320..daa6bca 100644 --- a/src/modules/data_connection.py +++ b/src/modules/data_connection.py @@ -86,6 +86,19 @@ def get_user_wishlist_collection(session: Session, wishlist_priority: int = 0) - wishlisted_boardgames_from_db = list(filter(lambda game: game.wishlist_info.wishlist_priority == wishlist_priority, wishlisted_boardgames_from_db)) return wishlisted_boardgames_from_db + +def get_user_preordered_collection(session: Session) -> list[boardgame_classes.BoardGame]: + with critical_function_lock: + preordered_boardgames_from_db = db_connection.get_preordered_boardgames(session) + + if len(preordered_boardgames_from_db) == 0: + preordered_boardgames = bgg_connection.get_user_preordered_collection() + db_connection.upsert_multiple_boardgames(session, preordered_boardgames) + + preordered_boardgames_from_db = db_connection.get_preordered_boardgames(session) + + + return preordered_boardgames_from_db def get_plays(session: Session) -> list[play_classes.Play]: diff --git a/src/modules/db_connection.py b/src/modules/db_connection.py index ede9fe9..258ed25 100644 --- a/src/modules/db_connection.py +++ b/src/modules/db_connection.py @@ -218,6 +218,15 @@ def get_wishlist_boardgames(session: Session) -> list[boardgame_classes.BoardGam return wishlisted_boardgames +def get_preordered_boardgames(session: Session) -> list[boardgame_classes.BoardGame]: + statement = select(boardgame_classes.PreorderedInfo) + results = session.exec(statement) + + preordered_boardgames = [preordered_info.boardgame for preordered_info in results.all()] + + return preordered_boardgames + + def add_play(session: Session, play: play_classes.Play): with critical_function_lock: