Add event management endpoints
- Implemented endpoints for creating, retrieving, and managing events. - Added `EventSchema` for event serialization and deserialization. - Updated `Event` model to include relationships with `PlayerEvent` and `Team`. - Modified `Player` and `Team` models to include relationships with `Event`. - Added new file `events.py` to handle event-related API routes.master
parent
3394f2271e
commit
ea030e012d
|
@ -0,0 +1,117 @@
|
|||
#! /usr/bin/env python3
|
||||
# vim:fenc=utf-8
|
||||
#
|
||||
# Copyright © 2024 sandvich <sandvich@archtop>
|
||||
#
|
||||
# Distributed under terms of the MIT license.
|
||||
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
from flask import Blueprint, abort
|
||||
from spectree import Response
|
||||
from models.player_event import PlayerEvent
|
||||
from models.player import Player
|
||||
from spec import BaseModel, spec
|
||||
from middleware import assert_team_authority, requires_authentication, requires_team_membership
|
||||
from models.event import Event, EventSchema
|
||||
from models.player_team import PlayerTeam
|
||||
from app_db import db
|
||||
|
||||
|
||||
api_events = Blueprint("events", __name__, url_prefix="/events")
|
||||
|
||||
@api_events.get("/<int:event_id>")
|
||||
@spec.validate(
|
||||
resp=Response(
|
||||
HTTP_200=EventSchema,
|
||||
),
|
||||
operation_id="get_event",
|
||||
)
|
||||
def get_event(event_id: int):
|
||||
event = db.session.query(Event).filter(Event.id == event_id).one_or_none()
|
||||
|
||||
if not event:
|
||||
abort(404)
|
||||
|
||||
return EventSchema.from_model(event).dict(by_alias=True)
|
||||
|
||||
@api_events.get("/team/id/<int:team_id>")
|
||||
@spec.validate(
|
||||
resp=Response(
|
||||
HTTP_200=list[EventSchema],
|
||||
),
|
||||
operation_id="get_team_events",
|
||||
)
|
||||
def get_team_events(team_id: int):
|
||||
events = db.session.query(
|
||||
Event
|
||||
).filter(
|
||||
Event.team_id == team_id
|
||||
).all()
|
||||
|
||||
def map_to_schema(event: Event):
|
||||
return EventSchema.from_model(event).dict(by_alias=True)
|
||||
|
||||
return list(map(map_to_schema, events))
|
||||
|
||||
@api_events.get("/user/id/<int:user_id>")
|
||||
def get_user_events(user_id: int):
|
||||
raise NotImplementedError()
|
||||
|
||||
class CreateEventJson(BaseModel):
|
||||
name: str
|
||||
description: str
|
||||
start_time: datetime
|
||||
player_ids: list[int]
|
||||
|
||||
@api_events.post("/team/id/<int:team_id>")
|
||||
@spec.validate(
|
||||
resp=Response(
|
||||
HTTP_200=EventSchema,
|
||||
)
|
||||
)
|
||||
@requires_authentication
|
||||
@requires_team_membership
|
||||
def create_event(player_team: PlayerTeam, json: CreateEventJson, **_):
|
||||
event = Event()
|
||||
event.team_id = player_team.team_id
|
||||
event.name = json.name
|
||||
event.description = json.description
|
||||
event.start_time = json.start_time
|
||||
|
||||
db.session.add(event)
|
||||
db.session.flush()
|
||||
db.session.refresh(event)
|
||||
|
||||
players_teams = db.session.query(
|
||||
PlayerTeam
|
||||
).join(
|
||||
Player
|
||||
).where(
|
||||
PlayerTeam.team_id == player_team.team_id
|
||||
).where(
|
||||
PlayerTeam.player_id.in_(json.player_ids)
|
||||
).all()
|
||||
|
||||
for player_team in players_teams:
|
||||
player = player_team.player
|
||||
player_event = PlayerEvent()
|
||||
player_event.player_id = player.steam_id
|
||||
player_event.event_id = event.id
|
||||
db.session.add(player_event)
|
||||
|
||||
db.session.commit()
|
||||
|
||||
return EventSchema.from_model(event).dict(by_alias=True), 200
|
||||
|
||||
@api_events.patch("/<int:event_id>/players")
|
||||
@requires_authentication
|
||||
@requires_team_membership
|
||||
def set_event_players(player_team: PlayerTeam, event_id: int, **_):
|
||||
assert_team_authority(player_team, None)
|
||||
|
||||
# merge players into event
|
||||
db.session.query(Event).filter(Event.id == event_id).update({"players": []})
|
||||
|
||||
raise NotImplementedError()
|
|
@ -1,10 +1,12 @@
|
|||
from datetime import datetime
|
||||
from sqlalchemy.orm import mapped_column, relationship
|
||||
from sqlalchemy.orm.attributes import Mapped
|
||||
from sqlalchemy.orm.properties import ForeignKey
|
||||
from sqlalchemy.types import TIMESTAMP, Integer, String, Text
|
||||
from sqlalchemy.sql import func
|
||||
from sqlalchemy_utc import UtcDateTime
|
||||
import app_db
|
||||
import spec
|
||||
|
||||
|
||||
class Event(app_db.BaseModel):
|
||||
|
@ -14,10 +16,30 @@ class Event(app_db.BaseModel):
|
|||
name: Mapped[str] = mapped_column(String(255), nullable=False)
|
||||
description: Mapped[str] = mapped_column(Text, nullable=True)
|
||||
start_time: Mapped[datetime] = mapped_column(UtcDateTime, nullable=False)
|
||||
team_id: Mapped[int] = mapped_column(Integer, nullable=False)
|
||||
team_id: Mapped[int] = mapped_column(ForeignKey("teams.id"), nullable=False)
|
||||
created_at: Mapped[datetime] = mapped_column(TIMESTAMP, server_default=func.now())
|
||||
|
||||
team: Mapped["Team"] = relationship("Team", back_populates="events")
|
||||
players: Mapped["PlayerEvent"] = relationship("PlayerEvent", back_populates="event")
|
||||
|
||||
class EventSchema(spec.BaseModel):
|
||||
id: int
|
||||
team_id: int
|
||||
name: str
|
||||
description: str
|
||||
start_time: datetime
|
||||
created_at: datetime
|
||||
|
||||
@classmethod
|
||||
def from_model(cls, model: Event) -> "EventSchema":
|
||||
return cls(
|
||||
id=model.id,
|
||||
name=model.name,
|
||||
description=model.description,
|
||||
start_time=model.start_time,
|
||||
team_id=model.team_id,
|
||||
created_at=model.created_at,
|
||||
)
|
||||
|
||||
from models.team import Team
|
||||
from models.player_event import PlayerEvent
|
||||
|
|
|
@ -15,6 +15,7 @@ class Player(app_db.BaseModel):
|
|||
|
||||
teams: Mapped[list["PlayerTeam"]] = relationship(back_populates="player")
|
||||
auth_sessions: Mapped[list["AuthSession"]] = relationship(back_populates="player")
|
||||
events: Mapped[list["PlayerEvent"]] = relationship(back_populates="player")
|
||||
|
||||
created_at: Mapped[datetime] = mapped_column(TIMESTAMP, server_default=func.now())
|
||||
|
||||
|
@ -28,4 +29,5 @@ class PlayerSchema(spec.BaseModel):
|
|||
|
||||
|
||||
from models.auth_session import AuthSession
|
||||
from models.player_event import PlayerEvent
|
||||
from models.player_team import PlayerTeam
|
||||
|
|
|
@ -19,6 +19,7 @@ class Team(app_db.BaseModel):
|
|||
players: Mapped[list["PlayerTeam"]] = relationship(back_populates="team")
|
||||
invites: Mapped[list["TeamInvite"]] = relationship(back_populates="team")
|
||||
integrations: Mapped[list["TeamIntegration"]] = relationship(back_populates="team")
|
||||
events: Mapped[list["Event"]] = relationship(back_populates="team")
|
||||
|
||||
created_at: Mapped[datetime] = mapped_column(TIMESTAMP, server_default=func.now())
|
||||
|
||||
|
@ -42,3 +43,4 @@ class TeamSchema(spec.BaseModel):
|
|||
from models.player_team import PlayerTeam
|
||||
from models.team_integration import TeamIntegration
|
||||
from models.team_invite import TeamInvite
|
||||
from models.event import Event
|
||||
|
|
Loading…
Reference in New Issue