Remove mongo & fix tests

This commit is contained in:
stijndcl 2022-08-29 20:24:42 +02:00
parent 7b2109fb07
commit 8a4baf6bb8
56 changed files with 406 additions and 539 deletions

View file

@ -7,7 +7,7 @@ from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import selectinload
from database.crud import users
from database.schemas.relational import Birthday, User
from database.schemas import Birthday, User
__all__ = ["add_birthday", "get_birthday_for_user", "get_birthdays_on_day"]

View file

@ -5,7 +5,7 @@ from sqlalchemy.ext.asyncio import AsyncSession
from database.crud import users
from database.exceptions import currency as exceptions
from database.schemas.relational import Bank, NightlyData
from database.schemas import Bank, NightlyData
from database.utils.math.currency import (
capacity_upgrade_price,
interest_upgrade_price,

View file

@ -5,7 +5,7 @@ from sqlalchemy.ext.asyncio import AsyncSession
from database.exceptions.constraints import DuplicateInsertException
from database.exceptions.not_found import NoResultFoundException
from database.schemas.relational import CustomCommand, CustomCommandAlias
from database.schemas import CustomCommand, CustomCommandAlias
__all__ = [
"clean_name",

View file

@ -2,7 +2,7 @@ from sqlalchemy import func, select
from sqlalchemy.ext.asyncio import AsyncSession
from database.exceptions.not_found import NoResultFoundException
from database.schemas.relational import DadJoke
from database.schemas import DadJoke
__all__ = ["add_dad_joke", "get_random_dad_joke"]

View file

@ -6,7 +6,7 @@ from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import selectinload
from database.schemas.relational import Deadline, UforaCourse
from database.schemas import Deadline, UforaCourse
__all__ = ["add_deadline", "get_deadlines"]

View file

@ -1,59 +0,0 @@
import datetime
from typing import Union
from database.mongo_types import MongoDatabase
from database.schemas.mongo.game_stats import GameStats
__all__ = ["get_game_stats", "complete_wordle_game"]
from database.utils.datetime import today_only_date
async def get_game_stats(database: MongoDatabase, user_id: int) -> GameStats:
"""Get a user's game stats
If no entry is found, it is first created
"""
collection = database[GameStats.collection()]
stats = await collection.find_one({"user_id": user_id})
if stats is not None:
return GameStats(**stats)
stats = GameStats(user_id=user_id)
await collection.insert_one(stats.dict(by_alias=True))
return stats
async def complete_wordle_game(database: MongoDatabase, user_id: int, win: bool, guesses: int = 0):
"""Update the user's Wordle stats"""
stats = await get_game_stats(database, user_id)
update: dict[str, dict[str, Union[int, datetime.datetime]]] = {"$inc": {"wordle.games": 1}, "$set": {}}
if win:
update["$inc"]["wordle.wins"] = 1
update["$inc"][f"wordle.guess_distribution.{guesses - 1}"] = 1
# Update streak
today = today_only_date()
last_win = stats.wordle.last_win
update["$set"]["wordle.last_win"] = today
if last_win is None or (today - last_win).days > 1:
# Never won a game before or streak is over
update["$set"]["wordle.current_streak"] = 1
stats.wordle.current_streak = 1
else:
# On a streak: increase counter
update["$inc"]["wordle.current_streak"] = 1
stats.wordle.current_streak += 1
# Update max streak if necessary
if stats.wordle.current_streak > stats.wordle.max_streak:
update["$set"]["wordle.max_streak"] = stats.wordle.current_streak
else:
# Streak is over
update["$set"]["wordle.current_streak"] = 0
collection = database[GameStats.collection()]
await collection.update_one({"_id": stats.id}, update)

View file

@ -4,7 +4,7 @@ from sqlalchemy import func, select
from sqlalchemy.ext.asyncio import AsyncSession
from database.exceptions import NoResultFoundException
from database.schemas.relational import Link
from database.schemas import Link
__all__ = ["add_link", "edit_link", "get_all_links", "get_link_by_name"]

View file

@ -4,7 +4,7 @@ from sqlalchemy import select
from sqlalchemy.exc import IntegrityError
from sqlalchemy.ext.asyncio import AsyncSession
from database.schemas.relational import MemeTemplate
from database.schemas import MemeTemplate
__all__ = ["add_meme", "get_all_memes", "get_meme_by_name"]

View file

@ -5,7 +5,7 @@ from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from database.enums import TaskType
from database.schemas.relational import Task
from database.schemas import Task
from database.utils.datetime import LOCAL_TIMEZONE
__all__ = ["get_task_by_enum", "set_last_task_execution_time"]

View file

@ -3,7 +3,7 @@ import datetime
from sqlalchemy import delete, select
from sqlalchemy.ext.asyncio import AsyncSession
from database.schemas.relational import UforaAnnouncement, UforaCourse
from database.schemas import UforaAnnouncement, UforaCourse
__all__ = ["create_new_announcement", "get_courses_with_announcements", "remove_old_announcements"]

View file

@ -3,7 +3,7 @@ from typing import Optional
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from database.schemas.relational import UforaCourse, UforaCourseAlias
from database.schemas import UforaCourse, UforaCourseAlias
__all__ = ["get_all_courses", "get_course_by_name"]

View file

@ -3,7 +3,7 @@ from typing import Optional
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from database.schemas.relational import Bank, NightlyData, User
from database.schemas import Bank, NightlyData, User
__all__ = [
"get_or_add",

View file

@ -1,56 +1,45 @@
import datetime
from typing import Optional
from database.enums import TempStorageKey
from database.mongo_types import MongoDatabase
from database.schemas.mongo.temporary_storage import TemporaryStorage
from database.schemas.mongo.wordle import WordleGame
from database.utils.datetime import today_only_date
from sqlalchemy import delete, select
from sqlalchemy.ext.asyncio import AsyncSession
from database.schemas import WordleGuess, WordleWord
__all__ = [
"get_active_wordle_game",
"make_wordle_guess",
"start_new_wordle_game",
"set_daily_word",
"reset_wordle_games",
]
async def get_active_wordle_game(database: MongoDatabase, user_id: int) -> Optional[WordleGame]:
async def get_active_wordle_game(session: AsyncSession, user_id: int) -> list[WordleGuess]:
"""Find a player's active game"""
collection = database[WordleGame.collection()]
result = await collection.find_one({"user_id": user_id})
if result is None:
return None
return WordleGame(**result)
statement = select(WordleGuess).where(WordleGuess.user_id == user_id)
guesses = (await session.execute(statement)).scalars().all()
return guesses
async def start_new_wordle_game(database: MongoDatabase, user_id: int) -> WordleGame:
"""Start a new game"""
collection = database[WordleGame.collection()]
game = WordleGame(user_id=user_id)
await collection.insert_one(game.dict(by_alias=True))
return game
async def make_wordle_guess(database: MongoDatabase, user_id: int, guess: str):
async def make_wordle_guess(session: AsyncSession, user_id: int, guess: str):
"""Make a guess in your current game"""
collection = database[WordleGame.collection()]
await collection.update_one({"user_id": user_id}, {"$push": {"guesses": guess}})
guess_instance = WordleGuess(user_id=user_id, guess=guess)
session.add(guess_instance)
await session.commit()
async def get_daily_word(database: MongoDatabase) -> Optional[str]:
async def get_daily_word(session: AsyncSession) -> Optional[WordleWord]:
"""Get the word of today"""
collection = database[TemporaryStorage.collection()]
statement = select(WordleWord).where(WordleWord.day == datetime.date.today())
row = (await session.execute(statement)).scalar_one_or_none()
result = await collection.find_one({"key": TempStorageKey.WORDLE_WORD, "day": today_only_date()})
if result is None:
if row is None:
return None
return result["word"]
return row
async def set_daily_word(database: MongoDatabase, word: str, *, forced: bool = False) -> str:
async def set_daily_word(session: AsyncSession, word: str, *, forced: bool = False) -> str:
"""Set the word of today
This does NOT overwrite the existing word if there is one, so that it can safely run
@ -60,23 +49,28 @@ async def set_daily_word(database: MongoDatabase, word: str, *, forced: bool = F
Returns the word that was chosen. If one already existed, return that instead.
"""
collection = database[TemporaryStorage.collection()]
current_word = await get_daily_word(session)
current_word = None if forced else await get_daily_word(database)
if current_word is not None:
return current_word
if current_word is None:
current_word = WordleWord(word=word, day=datetime.date.today())
session.add(current_word)
await session.commit()
await collection.update_one(
{"key": TempStorageKey.WORDLE_WORD}, {"$set": {"day": today_only_date(), "word": word}}, upsert=True
)
# Remove all active games
await reset_wordle_games(session)
elif forced:
current_word.word = word
current_word.day = datetime.date.today()
session.add(current_word)
await session.commit()
# Remove all active games
await reset_wordle_games(database)
# Remove all active games
await reset_wordle_games(session)
return word
return current_word.word
async def reset_wordle_games(database: MongoDatabase):
async def reset_wordle_games(session: AsyncSession):
"""Reset all active games"""
collection = database[WordleGame.collection()]
await collection.drop()
statement = delete(WordleGuess)
await session.execute(statement)

View file

@ -0,0 +1,57 @@
from datetime import date
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from database.schemas import WordleStats
__all__ = ["get_wordle_stats", "complete_wordle_game"]
async def get_wordle_stats(session: AsyncSession, user_id: int) -> WordleStats:
"""Get a user's wordle stats
If no entry is found, it is first created
"""
statement = select(WordleStats).where(WordleStats.user_id == user_id)
stats = (await session.execute(statement)).scalar_one_or_none()
if stats is not None:
return stats
stats = WordleStats(user_id=user_id)
session.add(stats)
await session.commit()
await session.refresh(stats)
return stats
async def complete_wordle_game(session: AsyncSession, user_id: int, win: bool):
"""Update the user's Wordle stats"""
stats = await get_wordle_stats(session, user_id)
stats.games += 1
if win:
stats.wins += 1
# Update streak
today = date.today()
last_win = stats.last_win
stats.last_win = today
if last_win is None or (today - last_win).days > 1:
# Never won a game before or streak is over
stats.current_streak = 1
else:
# On a streak: increase counter
stats.current_streak += 1
# Update max streak if necessary
if stats.current_streak > stats.highest_streak:
stats.highest_streak = stats.current_streak
else:
# Streak is over
stats.current_streak = 0
session.add(stats)
await session.commit()