Merge db_creation

This commit is contained in:
Yarne Coppens 2024-08-08 18:44:50 +02:00
commit b98d19f9ec
8 changed files with 173 additions and 51 deletions

BIN
db/database.db Normal file

Binary file not shown.

View file

@ -1,6 +1,7 @@
from pydantic import BaseModel, HttpUrl
from datetime import date from datetime import date
from enum import Enum from enum import Enum
from sqlmodel import Field, SQLModel
class BoardgameType(Enum): class BoardgameType(Enum):
BOARDGAME = 'boardgame' BOARDGAME = 'boardgame'
@ -11,36 +12,55 @@ class BoardgameType(Enum):
WISHLISTBOARDGAMEEXPANSION = 'wishlistboardgameexpansion' WISHLISTBOARDGAMEEXPANSION = 'wishlistboardgameexpansion'
class BoardGame(BaseModel): class BoardGameBase(SQLModel):
id: int
name: str name: str
description: str description: str
image_url : HttpUrl weight: float
thumbnail_url : HttpUrl image_url : str
thumbnail_url : str
year_published: int year_published: int
min_players: int min_players: int
max_players: int max_players: int
min_playing_time: int min_playing_time: int
max_playing_time: int max_playing_time: int
min_age: int min_age: int
all_expansion_ids: list[int]
type: BoardgameType = BoardgameType.BOARDGAME
class BoardGameExpansion(BoardGame): model_config = {
type: BoardgameType = BoardgameType.BOARDGAMEEXPANSION 'validate_assignment':True
}
class OwnedBoardGame(BoardGame): class OwnedBoardGameBase(BoardGameBase):
price_paid: float price_paid: float
acquisition_date: date acquisition_date: date
acquired_from: str acquired_from: str
class WishlistBoardGameBase(BoardGameBase):
wishlist_priority: int
class BoardGame(BoardGameBase, table=True):
id: int = Field(primary_key=True)
type: BoardgameType = BoardgameType.BOARDGAME
class BoardGameExpansion(BoardGameBase, table=True):
id: int = Field(primary_key=True)
expansion_for: int = Field(default=None, foreign_key="boardgame.id")
type: BoardgameType = BoardgameType.BOARDGAMEEXPANSION
class OwnedBoardGame(OwnedBoardGameBase, table=True):
id: int = Field(primary_key=True)
type: BoardgameType = BoardgameType.OWNEDBOARDGAME type: BoardgameType = BoardgameType.OWNEDBOARDGAME
class OwnedBoardGameExpansion(OwnedBoardGame): class OwnedBoardGameExpansion(OwnedBoardGameBase, table=True):
id: int = Field(primary_key=True)
expansion_for: int = Field(default=None, foreign_key="boardgame.id")
type: BoardgameType = BoardgameType.OWNEDBOARDGAMEEXPANSION type: BoardgameType = BoardgameType.OWNEDBOARDGAMEEXPANSION
class WishlistBoardGame(BoardGame): class WishlistBoardGame(WishlistBoardGameBase, table=True):
wishlist_priority: int id: int = Field(primary_key=True)
type: BoardgameType = BoardgameType.WISHLISTBOARDGAME type: BoardgameType = BoardgameType.WISHLISTBOARDGAME
class WishlistBoardGameExpansion(WishlistBoardGame): class WishlistBoardGameExpansion(WishlistBoardGameBase, table=True):
id: int = Field(primary_key=True)
expansion_for: int = Field(default=None, foreign_key="boardgame.id")
type: BoardgameType = BoardgameType.WISHLISTBOARDGAMEEXPANSION type: BoardgameType = BoardgameType.WISHLISTBOARDGAMEEXPANSION

View file

@ -2,6 +2,10 @@ import os
ROOT_PATH = project_root = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) ROOT_PATH = project_root = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
SECRETS_FILE_PATH = ROOT_PATH + '/secrets/auth.yaml' SECRETS_FILE_PATH = ROOT_PATH + '/secrets/auth.yaml'
DATABASE_FILE_PATH = ROOT_PATH + '/db/database.db'
DATABASE_FILE_PROJECT_PATH = f"/db/database.db"
SQLITE_URL = f"sqlite://{DATABASE_FILE_PROJECT_PATH}"
BGG_MAX_THING_BOARDGAMES = 20 BGG_MAX_THING_BOARDGAMES = 20
BGG_PLAY_PAGE_SIZE = 100 BGG_PLAY_PAGE_SIZE = 100

View file

@ -1,4 +1,5 @@
from typing import Union from typing import Union
from fastapi import FastAPI from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
from contextlib import asynccontextmanager from contextlib import asynccontextmanager
@ -34,23 +35,21 @@ def read_root():
@app.get("/boardgame/{boardgame_id}", response_model=boardgame_classes.BoardGame) @app.get("/boardgame/{boardgame_id}", response_model=boardgame_classes.BoardGame)
def get_boardgame_by_id(boardgame_id: int): def get_boardgame_by_id(boardgame_id: int):
requested_boardgame: boardgame_classes.BoardGame = bgg_connection.get_boardgame(boardgame_id) requested_boardgame: boardgame_classes.BoardGame = data_connection.get_boardgame(boardgame_id)
return requested_boardgame return requested_boardgame
@app.get("/owned", response_model=list[boardgame_classes.OwnedBoardGame]) @app.get("/owned", response_model=list[Union[boardgame_classes.OwnedBoardGame, boardgame_classes.OwnedBoardGameExpansion]])
def get_owned_collection(): def get_owned_collection():
requested_collection: list[boardgame_classes.OwnedBoardGame] = bgg_connection.get_user_owned_collection() return data_connection.get_user_owned_collection()
return requested_collection
@app.get("/wishlist", response_model=list[boardgame_classes.WishlistBoardGame]) @app.get("/wishlist", response_model=list[Union[boardgame_classes.WishlistBoardGame, boardgame_classes.WishlistBoardGameExpansion]])
def get_wishlist_collection(): def get_wishlist_collection():
requested_collection: list[boardgame_classes.WishlistBoardGame] = bgg_connection.get_user_wishlist_collection() return data_connection.get_user_wishlist_collection()
return requested_collection
@app.get("/plays", response_model=list[play_classes.Play]) @app.get("/plays", response_model=list[play_classes.Play])
def get_plays(): def get_plays():
requested_plays: list[play_classes.Play] = bgg_connection.get_plays() requested_plays: list[play_classes.Play] = data_connection.get_plays()
return requested_plays return requested_plays

View file

@ -5,6 +5,7 @@ import requests
from datetime import datetime from datetime import datetime
import time import time
import math import math
from typing import Union
from src.classes import boardgame_classes, play_classes from src.classes import boardgame_classes, play_classes
from src.modules import auth_manager from src.modules import auth_manager
@ -72,6 +73,7 @@ def convert_xml_to_boardgame(boardgame_xml: ET.Element) -> boardgame_classes.Boa
boardgame_dict = { boardgame_dict = {
"id" : int(boardgame_xml.get('id')), "id" : int(boardgame_xml.get('id')),
"name" : boardgame_xml.find('name').get('value'), "name" : boardgame_xml.find('name').get('value'),
"weight": boardgame_xml.find('statistics').find('ratings').find('averageweight').get('value'),
"description" : boardgame_xml.find('description').text, "description" : boardgame_xml.find('description').text,
"image_url" : boardgame_xml.find('image').text, "image_url" : boardgame_xml.find('image').text,
"thumbnail_url" : boardgame_xml.find('thumbnail').text, "thumbnail_url" : boardgame_xml.find('thumbnail').text,
@ -80,21 +82,22 @@ def convert_xml_to_boardgame(boardgame_xml: ET.Element) -> boardgame_classes.Boa
"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'))
"all_expansion_ids" : expansion_ids
} }
match boardgame_type: match boardgame_type:
case "boardgame": case "boardgame":
boardgame = boardgame_classes.BoardGame(**boardgame_dict) boardgame = boardgame_classes.BoardGame(**boardgame_dict)
case "boardgameexpansion": case "boardgameexpansion":
expansion_for = expansion_ids[0]
boardgame_dict['expansion_for'] = expansion_for
boardgame = boardgame_classes.BoardGameExpansion(**boardgame_dict) boardgame = boardgame_classes.BoardGameExpansion(**boardgame_dict)
return boardgame return boardgame
def convert_collection_xml_to_owned_boardgame(boardgame_extra_info: boardgame_classes.BoardGame, collection_boardgame_xml: ET.Element) -> boardgame_classes.OwnedBoardGame: def convert_collection_xml_to_owned_boardgame(boardgame_extra_info: boardgame_classes.BoardGame, collection_boardgame_xml: ET.Element) -> Union[boardgame_classes.OwnedBoardGame, boardgame_classes.OwnedBoardGameExpansion]:
boardgame_type = collection_boardgame_xml.get('subtype') boardgame_type = collection_boardgame_xml.get('subtype')
@ -121,18 +124,7 @@ def convert_collection_xml_to_owned_boardgame(boardgame_extra_info: boardgame_cl
} }
boardgame_dict = { boardgame_dict = {
"id" : boardgame_extra_info.id, **boardgame_extra_info.__dict__,
"name" : boardgame_extra_info.name,
"description" : boardgame_extra_info.description,
"image_url" : boardgame_extra_info.image_url,
"thumbnail_url" : boardgame_extra_info.thumbnail_url,
"year_published" : boardgame_extra_info.year_published,
"min_players" : boardgame_extra_info.min_players,
"max_players" : boardgame_extra_info.max_players,
"min_playing_time" : boardgame_extra_info.min_playing_time,
"max_playing_time" : boardgame_extra_info.max_playing_time,
"min_age" : boardgame_extra_info.min_age,
"all_expansion_ids" : boardgame_extra_info.all_expansion_ids,
**owned_boardgame_dict **owned_boardgame_dict
} }
@ -140,6 +132,7 @@ def convert_collection_xml_to_owned_boardgame(boardgame_extra_info: boardgame_cl
case "boardgame": case "boardgame":
boardgame = boardgame_classes.OwnedBoardGame(**boardgame_dict) boardgame = boardgame_classes.OwnedBoardGame(**boardgame_dict)
case "boardgameexpansion": case "boardgameexpansion":
boardgame_dict['expansion_for'] = boardgame_extra_info.expansion_for
boardgame = boardgame_classes.OwnedBoardGameExpansion(**boardgame_dict) boardgame = boardgame_classes.OwnedBoardGameExpansion(**boardgame_dict)
@ -157,18 +150,7 @@ def convert_collection_xml_to_wishlist_boardgame(boardgame_extra_info: boardgame
} }
boardgame_dict = { boardgame_dict = {
"id" : boardgame_extra_info.id, **boardgame_extra_info.__dict__,
"name" : boardgame_extra_info.name,
"description" : boardgame_extra_info.description,
"image_url" : boardgame_extra_info.image_url,
"thumbnail_url" : boardgame_extra_info.thumbnail_url,
"year_published" : boardgame_extra_info.year_published,
"min_players" : boardgame_extra_info.min_players,
"max_players" : boardgame_extra_info.max_players,
"min_playing_time" : boardgame_extra_info.min_playing_time,
"max_playing_time" : boardgame_extra_info.max_playing_time,
"min_age" : boardgame_extra_info.min_age,
"all_expansion_ids" : boardgame_extra_info.all_expansion_ids,
**wishlist_boardgame_dict **wishlist_boardgame_dict
} }
@ -176,6 +158,7 @@ def convert_collection_xml_to_wishlist_boardgame(boardgame_extra_info: boardgame
case "boardgame": case "boardgame":
boardgame = boardgame_classes.WishlistBoardGame(**boardgame_dict) boardgame = boardgame_classes.WishlistBoardGame(**boardgame_dict)
case "boardgameexpansion": case "boardgameexpansion":
boardgame_dict['expansion_for'] = boardgame_extra_info.expansion_for
boardgame = boardgame_classes.WishlistBoardGameExpansion(**boardgame_dict) boardgame = boardgame_classes.WishlistBoardGameExpansion(**boardgame_dict)

View file

@ -0,0 +1,53 @@
from typing import Union
from src.modules import bgg_connection, db_connection
from src.classes import boardgame_classes, play_classes
def get_boardgame(boardgame_id: int) -> boardgame_classes.BoardGame:
#Will check if it already exists in db, then it will get it from there
boardgame_in_db: list[boardgame_classes.BoardGame] = db_connection.get_base_boardgames(boardgame_id=boardgame_id)
to_return_boardgame = None
if len(boardgame_in_db) != 0:
to_return_boardgame = boardgame_in_db[0]
else:
to_return_boardgame = bgg_connection.get_boardgame(boardgame_id)
db_connection.add_boardgame(to_return_boardgame)
return to_return_boardgame
def get_user_owned_collection() -> list[Union[boardgame_classes.OwnedBoardGame, boardgame_classes.OwnedBoardGameExpansion]]:
owned_boardgames_from_db = db_connection.get_all_owned_boardgames()
owned_boardgame_expanions_from_db = db_connection.get_all_owned_boardgames_expansions()
boardgames_to_return = []
if len(owned_boardgames_from_db) == 0 and len(owned_boardgame_expanions_from_db) == 0:
owned_boardgames = bgg_connection.get_user_owned_collection()
for boardgame in owned_boardgames:
db_connection.add_boardgame(boardgame)
return owned_boardgames
else:
return owned_boardgames_from_db
def get_user_wishlist_collection() -> Union[list[boardgame_classes.WishlistBoardGame], list[boardgame_classes.WishlistBoardGameExpansion]]:
owned_boardgames_from_db = db_connection.get_all_wishlisted_boardgames
return bgg_connection.get_user_wishlist_collection()
def get_plays() -> list[play_classes.Play]:
return bgg_connection.get_plays()
def delete_database():
db_connection.delete_database()
def create_db_and_tables():
db_connection.create_db_and_tables()

View file

@ -0,0 +1,64 @@
from sqlmodel import create_engine, SQLModel, Session, select
from src.config import definitions
import os
from typing import Union
from src.classes import boardgame_classes
sqlite_url = definitions.SQLITE_URL
connect_args = {"check_same_thread": False}
engine = create_engine(sqlite_url, echo=True, connect_args=connect_args)
def add_boardgame(boardgame: Union[
boardgame_classes.BoardGame, boardgame_classes.BoardGameExpansion,
boardgame_classes.OwnedBoardGame, boardgame_classes.OwnedBoardGameExpansion,
boardgame_classes.WishlistBoardGame, boardgame_classes.WishlistBoardGameExpansion]):
with Session(engine) as session:
session.add(boardgame)
session.commit()
session.refresh(boardgame)
def get_base_boardgames(boardgame_id = None) -> list[boardgame_classes.BoardGame]:
with Session(engine) as session:
session.expire_on_commit = False
if boardgame_id == None:
statement = select(boardgame_classes.BoardGame)
else:
statement = select(boardgame_classes.BoardGame).where(boardgame_classes.BoardGame.id == boardgame_id)
results = session.exec(statement)
boardgame_list = results.all()
return boardgame_list
def get_all_owned_boardgames() -> list[boardgame_classes.OwnedBoardGame]:
with Session(engine) as session:
statement = select(boardgame_classes.OwnedBoardGame)
results = session.exec(statement)
boardgame_list = results.all()
return boardgame_list
def get_all_owned_boardgames_expansions() -> list[boardgame_classes.OwnedBoardGameExpansion]:
with Session(engine) as session:
statement = select(boardgame_classes.OwnedBoardGameExpansion)
results = session.exec(statement)
boardgame_list = results.all()
return boardgame_list
def get_all_wishlisted_boardgames() -> list[boardgame_classes.WishlistBoardGame]:
pass
def delete_database():
os.remove(definitions.DATABASE_FILE_PATH)
def create_db_and_tables():
SQLModel.metadata.create_all(engine)

View file

@ -11,6 +11,7 @@ client = TestClient(app)
def default_boardgame_test(to_test_boardgame: boardgame_classes.BoardGame): def default_boardgame_test(to_test_boardgame: boardgame_classes.BoardGame):
assert type(to_test_boardgame.id) == int assert type(to_test_boardgame.id) == int
assert type(to_test_boardgame.name) == str assert type(to_test_boardgame.name) == str
assert type(to_test_boardgame.weight) == float
assert type(to_test_boardgame.description) == str assert type(to_test_boardgame.description) == str
assert validators.url(str(to_test_boardgame.image_url)) assert validators.url(str(to_test_boardgame.image_url))
assert validators.url(str(to_test_boardgame.thumbnail_url)) assert validators.url(str(to_test_boardgame.thumbnail_url))
@ -20,8 +21,6 @@ def default_boardgame_test(to_test_boardgame: boardgame_classes.BoardGame):
assert type(to_test_boardgame.min_playing_time) == int assert type(to_test_boardgame.min_playing_time) == int
assert type(to_test_boardgame.max_playing_time) == int assert type(to_test_boardgame.max_playing_time) == int
assert type(to_test_boardgame.min_age) == int assert type(to_test_boardgame.min_age) == int
assert type(to_test_boardgame.all_expansion_ids) == list
assert type(to_test_boardgame.all_expansion_ids[0]) == int
assert type(to_test_boardgame.type) == boardgame_classes.BoardgameType assert type(to_test_boardgame.type) == boardgame_classes.BoardgameType