More and more refactors
This commit is contained in:
parent
81e9eb154b
commit
d074074b03
@ -97,7 +97,9 @@ def create_high_score(
|
|||||||
db.add(db_high_score)
|
db.add(db_high_score)
|
||||||
db.commit()
|
db.commit()
|
||||||
db.refresh(db_high_score)
|
db.refresh(db_high_score)
|
||||||
return Score(score_value=db_high_score.score_value, time=str(db_high_score.time))
|
return Score(
|
||||||
|
score_value=db_high_score.score_value, time=str(db_high_score.time)
|
||||||
|
)
|
||||||
|
|
||||||
old_high_score = (
|
old_high_score = (
|
||||||
db.query(HighScore)
|
db.query(HighScore)
|
||||||
@ -112,6 +114,8 @@ def create_high_score(
|
|||||||
db.delete(old_high_score)
|
db.delete(old_high_score)
|
||||||
return add_to_db()
|
return add_to_db()
|
||||||
else:
|
else:
|
||||||
return Score(score_value=old_high_score.score_value, time=str(old_high_score.time))
|
return Score(
|
||||||
|
score_value=old_high_score.score_value, time=str(old_high_score.time)
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
return add_to_db()
|
return add_to_db()
|
||||||
|
|||||||
@ -0,0 +1,84 @@
|
|||||||
|
from fastapi import HTTPException
|
||||||
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
|
from src.enums import CourseEnum
|
||||||
|
from src.models import CourseProgress, LearnableProgress, User
|
||||||
|
from src.schemas.learnableprogress import SavedLearnableProgress
|
||||||
|
|
||||||
|
|
||||||
|
def create_learnable(
|
||||||
|
db: Session, user: User, course: CourseEnum, learnable: SavedLearnableProgress
|
||||||
|
):
|
||||||
|
"""Create a new learnable"""
|
||||||
|
if learnable.index < 0:
|
||||||
|
raise HTTPException(status_code=400, detail="Negative index not allowed")
|
||||||
|
|
||||||
|
if learnable.in_use is None:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=400, detail="Please indicate whether the learnable is in use"
|
||||||
|
)
|
||||||
|
|
||||||
|
if len(learnable.name) < 1:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=400, detail="No name was provided for the learnable"
|
||||||
|
)
|
||||||
|
|
||||||
|
potential_duplicate = (
|
||||||
|
db.query(LearnableProgress)
|
||||||
|
.filter(LearnableProgress.name == learnable.name)
|
||||||
|
.first()
|
||||||
|
)
|
||||||
|
|
||||||
|
if potential_duplicate:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=400, detail="No duplicate learnable names allowed"
|
||||||
|
)
|
||||||
|
|
||||||
|
db_course = (
|
||||||
|
db.query(CourseProgress)
|
||||||
|
.filter(
|
||||||
|
CourseProgress.owner_id == user.user_id, CourseProgress.course == course
|
||||||
|
)
|
||||||
|
.first()
|
||||||
|
)
|
||||||
|
|
||||||
|
db_learnable = LearnableProgress(
|
||||||
|
index=learnable.index,
|
||||||
|
in_use=learnable.in_use,
|
||||||
|
name=learnable.name,
|
||||||
|
progress=0.0,
|
||||||
|
course_progress_id=db_course.course_progress_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
db.add(db_learnable)
|
||||||
|
db.commit()
|
||||||
|
|
||||||
|
|
||||||
|
def patch_learnable(db: Session, user: User, learnable: SavedLearnableProgress):
|
||||||
|
"""Patch an existing learnable"""
|
||||||
|
db_learnable = (
|
||||||
|
db.query(LearnableProgress)
|
||||||
|
.filter(LearnableProgress.name == learnable.name)
|
||||||
|
.first()
|
||||||
|
)
|
||||||
|
|
||||||
|
if not db_learnable:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=400, detail="Learnable with provided name not found"
|
||||||
|
)
|
||||||
|
|
||||||
|
if learnable.index < -1:
|
||||||
|
raise HTTPException(status_code=400, detail="Invalid learnable index")
|
||||||
|
elif learnable.index > -1:
|
||||||
|
db_learnable.index = learnable.index
|
||||||
|
|
||||||
|
if learnable.in_use is not None:
|
||||||
|
db_learnable.in_use = learnable.in_use
|
||||||
|
|
||||||
|
if len(learnable.name) > 0:
|
||||||
|
db_learnable.name = learnable.name
|
||||||
|
|
||||||
|
# TODO: chek progress semantics
|
||||||
|
|
||||||
|
db.add(db_learnable)
|
||||||
|
db.commit()
|
||||||
@ -2,16 +2,14 @@ from fastapi import HTTPException
|
|||||||
from passlib.context import CryptContext
|
from passlib.context import CryptContext
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
from src.models import User
|
|
||||||
from src.crud.highscores import (get_highest_high_scores,
|
from src.crud.highscores import (get_highest_high_scores,
|
||||||
get_most_recent_high_scores)
|
get_most_recent_high_scores)
|
||||||
from src.schemas.users import UserCreate
|
|
||||||
from src.enums import CourseEnum, MinigameEnum
|
from src.enums import CourseEnum, MinigameEnum
|
||||||
from src.models import CourseProgress, LearnableProgress
|
from src.models import CourseProgress, LearnableProgress, User
|
||||||
from src.schemas.highscores import SavedMinigameProgress
|
|
||||||
from src.schemas.courseprogress import SavedCourseProgress
|
from src.schemas.courseprogress import SavedCourseProgress
|
||||||
|
from src.schemas.highscores import SavedMinigameProgress
|
||||||
from src.schemas.learnableprogress import SavedLearnableProgress
|
from src.schemas.learnableprogress import SavedLearnableProgress
|
||||||
from src.schemas.users import SavedUser
|
from src.schemas.users import SavedUser, UserCreate
|
||||||
|
|
||||||
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
|
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
|
||||||
|
|
||||||
@ -28,7 +26,7 @@ def check_empty_fields(username: str, password: str, avatar_index: int):
|
|||||||
|
|
||||||
def patch_user(db: Session, username: str, user: UserCreate):
|
def patch_user(db: Session, username: str, user: UserCreate):
|
||||||
"""Changes the username and/or the password of a User"""
|
"""Changes the username and/or the password of a User"""
|
||||||
#check_empty_fields(user.username, user.password, user.avatar_index)
|
# check_empty_fields(user.username, user.password, user.avatar_index)
|
||||||
db_user = get_user_by_username(db, username)
|
db_user = get_user_by_username(db, username)
|
||||||
potential_duplicate = get_user_by_username(db, user.username)
|
potential_duplicate = get_user_by_username(db, user.username)
|
||||||
if potential_duplicate:
|
if potential_duplicate:
|
||||||
@ -46,6 +44,8 @@ def patch_user(db: Session, username: str, user: UserCreate):
|
|||||||
|
|
||||||
if user.avatar_index > -1:
|
if user.avatar_index > -1:
|
||||||
db_user.avatar_index = user.avatar_index
|
db_user.avatar_index = user.avatar_index
|
||||||
|
elif user.avatar_index < -1:
|
||||||
|
raise HTTPException(status_code=400, detail="Invalid avatar index")
|
||||||
|
|
||||||
db_user.playtime += user.playtime
|
db_user.playtime += user.playtime
|
||||||
db.commit()
|
db.commit()
|
||||||
|
|||||||
18
src/enums.py
18
src/enums.py
@ -2,24 +2,6 @@ from fastapi_utils.enums import StrEnum
|
|||||||
from sqlalchemy.types import Enum, TypeDecorator
|
from sqlalchemy.types import Enum, TypeDecorator
|
||||||
|
|
||||||
|
|
||||||
class StrEnumType(TypeDecorator):
|
|
||||||
impl = Enum
|
|
||||||
|
|
||||||
def __init__(self, enum_class, **kw):
|
|
||||||
self.enum_class = enum_class
|
|
||||||
super().__init__(enum_class, **kw)
|
|
||||||
|
|
||||||
def process_bind_param(self, value, dialect):
|
|
||||||
if value is None:
|
|
||||||
return None
|
|
||||||
return value.value
|
|
||||||
|
|
||||||
def process_result_value(self, value, dialect):
|
|
||||||
if value is None:
|
|
||||||
return None
|
|
||||||
return self.enum_class(value)
|
|
||||||
|
|
||||||
|
|
||||||
class MinigameEnum(StrEnum):
|
class MinigameEnum(StrEnum):
|
||||||
SpellingBee = "SpellingBee"
|
SpellingBee = "SpellingBee"
|
||||||
Hangman = "Hangman"
|
Hangman = "Hangman"
|
||||||
|
|||||||
26
src/main.py
26
src/main.py
@ -9,10 +9,11 @@ sys.path.append("..")
|
|||||||
from src.crud import authentication as crud_authentication
|
from src.crud import authentication as crud_authentication
|
||||||
from src.crud import courseprogress as crud_courseprogress
|
from src.crud import courseprogress as crud_courseprogress
|
||||||
from src.crud import highscores as crud_highscores
|
from src.crud import highscores as crud_highscores
|
||||||
|
from src.crud import learnableprogress as crud_learnables
|
||||||
from src.crud import users as crud_users
|
from src.crud import users as crud_users
|
||||||
from src.database import Base, engine, get_db
|
from src.database import Base, engine, get_db
|
||||||
from src.enums import CourseEnum, MinigameEnum
|
from src.enums import CourseEnum, MinigameEnum
|
||||||
from src.schemas import courseprogress, highscores, users
|
from src.schemas import courseprogress, highscores, learnableprogress, users
|
||||||
|
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
|
|
||||||
@ -23,6 +24,7 @@ Base.metadata.create_all(bind=engine)
|
|||||||
async def root():
|
async def root():
|
||||||
return {"message": "Hello world!"}
|
return {"message": "Hello world!"}
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@app.get("/allusers", response_model=List[users.SavedUser])
|
@app.get("/allusers", response_model=List[users.SavedUser])
|
||||||
async def read_users(db: Session = Depends(get_db)):
|
async def read_users(db: Session = Depends(get_db)):
|
||||||
@ -38,6 +40,7 @@ async def read_user(
|
|||||||
return crud_users.get_user_by_username(db, current_user_name)
|
return crud_users.get_user_by_username(db, current_user_name)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
@app.patch("/users")
|
@app.patch("/users")
|
||||||
async def patch_current_user(
|
async def patch_current_user(
|
||||||
user: users.UserCreate,
|
user: users.UserCreate,
|
||||||
@ -123,3 +126,24 @@ async def patch_course_progress(
|
|||||||
return crud_courseprogress.patch_course_progress(
|
return crud_courseprogress.patch_course_progress(
|
||||||
db, current_user, course, course_progress
|
db, current_user, course, course_progress
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@app.post("/learnables/{course}")
|
||||||
|
async def create_learnable(
|
||||||
|
course: CourseEnum,
|
||||||
|
learnable: learnableprogress.SavedLearnableProgress,
|
||||||
|
current_user_name: str = Depends(crud_authentication.get_current_user_name),
|
||||||
|
db: Session = Depends(get_db),
|
||||||
|
):
|
||||||
|
current_user = crud_users.get_user_by_username(db, current_user_name)
|
||||||
|
crud_learnables.create_learnable(db, current_user, course, learnable)
|
||||||
|
|
||||||
|
|
||||||
|
@app.patch("/learnables")
|
||||||
|
async def create_learnable(
|
||||||
|
learnable: learnableprogress.SavedLearnableProgress,
|
||||||
|
current_user_name: str = Depends(crud_authentication.get_current_user_name),
|
||||||
|
db: Session = Depends(get_db),
|
||||||
|
):
|
||||||
|
current_user = crud_users.get_user_by_username(db, current_user_name)
|
||||||
|
crud_learnables.patch_learnable(db, current_user, learnable)
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
|
from typing import List
|
||||||
|
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
from src.enums import CourseEnum
|
from src.enums import CourseEnum
|
||||||
from src.schemas.learnableprogress import SavedLearnableProgress
|
from src.schemas.learnableprogress import SavedLearnableProgress
|
||||||
from typing import List
|
|
||||||
|
|
||||||
|
|
||||||
class CourseProgressBase(BaseModel):
|
class CourseProgressBase(BaseModel):
|
||||||
@ -30,4 +31,4 @@ class SavedCourseProgress(BaseModel):
|
|||||||
learnables: List[SavedLearnableProgress]
|
learnables: List[SavedLearnableProgress]
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
orm_mode = True
|
orm_mode = True
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
|
from typing import List
|
||||||
|
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
from src.enums import MinigameEnum
|
from src.enums import MinigameEnum
|
||||||
from typing import List
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class HighScoreBase(BaseModel):
|
class HighScoreBase(BaseModel):
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
|
||||||
class SavedLearnableProgress(BaseModel):
|
class SavedLearnableProgress(BaseModel):
|
||||||
index: int
|
index: int = -1
|
||||||
in_use: bool
|
in_use: bool = None
|
||||||
name: str
|
name: str = ""
|
||||||
progress: float
|
progress: float = -1.0
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
from pydantic import BaseModel
|
|
||||||
from typing import List
|
from typing import List
|
||||||
from src.schemas.highscores import SavedMinigameProgress
|
|
||||||
|
from pydantic import BaseModel
|
||||||
|
|
||||||
from src.schemas.courseprogress import SavedCourseProgress
|
from src.schemas.courseprogress import SavedCourseProgress
|
||||||
|
from src.schemas.highscores import SavedMinigameProgress
|
||||||
|
|
||||||
|
|
||||||
class UserBase(BaseModel):
|
class UserBase(BaseModel):
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import random
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from src.enums import MinigameEnum
|
from src.enums import MinigameEnum
|
||||||
from tests.base import client, password, avatar_index, register_user
|
from tests.base import avatar_index, client, password, register_user
|
||||||
from tests.config.database import clear_db
|
from tests.config.database import clear_db
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,6 @@ patched_password = "New password"
|
|||||||
patched_avatar_index = 2
|
patched_avatar_index = 2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_patch_user():
|
async def test_patch_user():
|
||||||
"""Test the patching of a user's username, password and avatar"""
|
"""Test the patching of a user's username, password and avatar"""
|
||||||
@ -62,7 +61,7 @@ async def test_patch_user_with_empty_fields():
|
|||||||
"username": "",
|
"username": "",
|
||||||
"password": patched_password,
|
"password": patched_password,
|
||||||
"avatar_index": patched_avatar_index,
|
"avatar_index": patched_avatar_index,
|
||||||
"playtime": 0.0
|
"playtime": 0.0,
|
||||||
},
|
},
|
||||||
headers=headers,
|
headers=headers,
|
||||||
)
|
)
|
||||||
@ -74,7 +73,7 @@ async def test_patch_user_with_empty_fields():
|
|||||||
"username": username,
|
"username": username,
|
||||||
"password": patched_password,
|
"password": patched_password,
|
||||||
"avatar_index": -1,
|
"avatar_index": -1,
|
||||||
"playtime": 0.0
|
"playtime": 0.0,
|
||||||
},
|
},
|
||||||
headers=headers,
|
headers=headers,
|
||||||
)
|
)
|
||||||
@ -86,7 +85,7 @@ async def test_patch_user_with_empty_fields():
|
|||||||
"username": username,
|
"username": username,
|
||||||
"password": "",
|
"password": "",
|
||||||
"avatar_index": patched_avatar_index,
|
"avatar_index": patched_avatar_index,
|
||||||
"playtime": 0.0
|
"playtime": 0.0,
|
||||||
},
|
},
|
||||||
headers=headers,
|
headers=headers,
|
||||||
)
|
)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user