Skip to content

Commit

Permalink
redis donations sync(untested)
Browse files Browse the repository at this point in the history
  • Loading branch information
Furrior committed Feb 28, 2025
1 parent 3a5e8d0 commit 5d8dbb6
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 12 deletions.
1 change: 1 addition & 0 deletions app/core/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class Database(CustomBaseModel):

class Redis(CustomBaseModel):
connection_string: str = "redis://127.0.0.1:6379/0"
channel: str = "central"


class OAuth(CustomBaseModel):
Expand Down
10 changes: 8 additions & 2 deletions app/core/redis.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import redis
from typing import AsyncGenerator
import redis.asyncio as redis

from app.core.config import CONFIG

REDIS = redis.from_url(CONFIG.redis.connection_string)
REDIS_POOL = redis.ConnectionPool.from_url(CONFIG.redis.connection_string)


async def send_message(channel: str, message: str) -> None:
client = redis.Redis(connection_pool=REDIS_POOL)
await client.publish(f"{CONFIG.redis.channel}.{channel}", message)
10 changes: 3 additions & 7 deletions app/routes/v1/donate.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@

from app.database.models import Donation, Player
from app.deps import SessionDep, verify_bearer
from app.routes.v1.player import create_player, get_or_create_player_by_discord_id
from app.schemas.donate import NewDonationDiscord
from app.schemas.generic import PaginatedResponse, paginate_selection
from app.schemas.player import NewPlayer

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -65,13 +67,7 @@ async def create_donation_by_discord(session: SessionDep, new_donation: NewDonat
"""
Creating a new donation from any other identifier doesnt make much sense
"""
player = session.exec(
select(Player).where(Player.discord_id == new_donation.discord_id)
).first()

if player is None:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail="Player not found")
player = await get_or_create_player_by_discord_id(session, new_donation.discord_id)

donation = Donation(
player_id=player.id,
Expand Down
56 changes: 54 additions & 2 deletions app/routes/v1/player.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import datetime
import logging

from fastapi import APIRouter, Depends, HTTPException, Request, status
from fastapi import APIRouter, Depends, HTTPException, Request, status, BackgroundTasks
from fastapi.responses import RedirectResponse
from sqlalchemy import func
from sqlmodel import Session, select
Expand All @@ -11,7 +11,8 @@
from app.deps import BEARER_DEP_RESPONSES, SessionDep, verify_bearer
from app.fur_discord import DiscordOAuthClient
from app.schemas.generic import PaginatedResponse
from app.schemas.player import PlayerPatch
from app.schemas.player import NewPlayer, PlayerPatch
import app.core.redis as redis

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -96,6 +97,7 @@ async def callback(session: SessionDep, code: str, state: str) -> Player:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="Player already linked")

logger.debug("Linking a preexisting player %s to %s", link.discord_id, ckey)
link.ckey = ckey
else:
link = Player(ckey=ckey, discord_id=discord_id)
Expand All @@ -107,13 +109,31 @@ async def callback(session: SessionDep, code: str, state: str) -> Player:

logger.info("Linked %s to %s", link.ckey, link.discord_id)

await update_player_event(link)

return link

# endregion
# region # Players

player_router = APIRouter(prefix="/players", tags=["Player"])


async def get_or_create_player_by_discord_id(session: SessionDep,
discord_id: str) -> Player:
result = session.exec(select(Player).where(
Player.discord_id == discord_id)).first()

if result is None:
player = Player(discord_id=discord_id)
session.add(player)
session.commit()
session.refresh(player)
return player

return result


@player_router.get(
"/discord/{discord_id}",
status_code=status.HTTP_200_OK,
Expand Down Expand Up @@ -167,6 +187,29 @@ async def get_players(session: SessionDep, request: Request, page: int = 1, page
)


@player_router.post("", status_code=status.HTTP_201_CREATED, responses=BEARER_DEP_RESPONSES, dependencies=[Depends(verify_bearer)])
async def create_player(session: SessionDep, new_player: NewPlayer) -> Player:
"""
Used internally and for force linking players manually
"""
try:
await get_player_by_discord_id(session, new_player.discord_id)
await get_player_by_ckey(session, new_player.ckey)
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="Player already exists")
except HTTPException as e:
if e.status_code != status.HTTP_404_NOT_FOUND:
raise e

player = Player(**new_player.model_dump())
session.add(player)
session.commit()
session.refresh(player)
logger.info("Force linked %s to %s", player.ckey, player.discord_id)
await update_player_event(player)
return player


@player_router.get(
"/{id}",
status_code=status.HTTP_200_OK,
Expand Down Expand Up @@ -195,7 +238,16 @@ async def update_player(session: SessionDep, id: int, player_patch: PlayerPatch)

session.commit()
session.refresh(player)
logger.info("Player updated: %s", player.model_dump_json())
await update_player_event(player)
return player


# endregion

# region Events

async def update_player_event(player: Player) -> None:
await redis.send_message("link", player.model_dump_json())

# endregion
6 changes: 5 additions & 1 deletion app/schemas/player.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,9 @@


class PlayerPatch(BaseModel):
ckey: str | None = None
discord_id: str | None = None
ckey: str | None = None

class NewPlayer(BaseModel):
discord_id: str
ckey: str | None = None

0 comments on commit 5d8dbb6

Please sign in to comment.