from fastapi import APIRouter, Depends, HTTPException, Response from typing import Optional import logging import pydantic from pandas import DataFrame from ..db_engine import Event, model_to_dict, fn, DoesNotExist from ..dependencies import oauth2_scheme, valid_token router = APIRouter(prefix="/api/v2/events", tags=["events"]) class EventModel(pydantic.BaseModel): name: str short_desc: str long_desc: str url: Optional[str] = None thumbnail: Optional[str] = None active: Optional[bool] = False @router.get("") async def v1_events_get( name: Optional[str] = None, in_desc: Optional[str] = None, active: Optional[bool] = None, csv: Optional[bool] = None, limit: Optional[int] = 100, ): all_events = Event.select().order_by(Event.id) if name is not None: all_events = all_events.where(fn.Lower(Event.name) == name.lower()) if in_desc is not None: all_events = all_events.where( (fn.Lower(Event.short_desc).contains(in_desc.lower())) | (fn.Lower(Event.long_desc).contains(in_desc.lower())) ) if active is not None: all_events = all_events.where(Event.active == active) total_count = all_events.count() if not csv else 0 all_events = all_events.limit(max(0, min(limit, 500))) if csv: data_list = [ ["id", "name", "short_desc", "long_desc", "url", "thumbnail", "active"] ] for line in all_events: data_list.append( [ line.id, line.name, line.short_desc, line.long_desc, line.url, line.thumbnail, line.active, ] ) return_val = DataFrame(data_list).to_csv(header=False, index=False) return Response(content=return_val, media_type="text/csv") else: return_val = {"count": total_count, "events": []} for x in all_events: return_val["events"].append(model_to_dict(x)) return return_val @router.get("/{event_id}") async def v1_events_get_one(event_id, csv: Optional[bool] = False): try: this_event = Event.get_by_id(event_id) except DoesNotExist: raise HTTPException( status_code=404, detail=f"No event found with id {event_id}" ) if csv: data_list = [ ["id", "name", "short_desc", "long_desc", "url", "thumbnail", "active"], [ this_event.id, this_event.name, this_event.short_desc, this_event.long_desc, this_event.url, this_event.thumbnail, this_event.active, ], ] return_val = DataFrame(data_list).to_csv(header=False, index=False) return Response(content=return_val, media_type="text/csv") else: return_val = model_to_dict(this_event) return return_val @router.post("") async def v1_events_post(event: EventModel, token: str = Depends(oauth2_scheme)): if not valid_token(token): logging.warning("Bad Token: [REDACTED]") raise HTTPException( status_code=401, detail="You are not authorized to post events. This event has been logged.", ) dupe_event = Event.get_or_none(Event.name == event.name) if dupe_event: raise HTTPException( status_code=400, detail=f"There is already an event using {event.name}" ) this_event = Event( name=event.name, short_desc=event.short_desc, long_desc=event.long_desc, url=event.url, thumbnail=event.thumbnail, active=event.active, ) saved = this_event.save() if saved == 1: return_val = model_to_dict(this_event) return return_val else: raise HTTPException( status_code=418, detail="Well slap my ass and call me a teapot; I could not save that cardset", ) @router.patch("/{event_id}") async def v1_events_patch( event_id, name: Optional[str] = None, short_desc: Optional[str] = None, long_desc: Optional[str] = None, url: Optional[str] = None, thumbnail: Optional[str] = None, active: Optional[bool] = None, token: str = Depends(oauth2_scheme), ): if not valid_token(token): logging.warning("Bad Token: [REDACTED]") raise HTTPException( status_code=401, detail="You are not authorized to patch events. This event has been logged.", ) try: this_event = Event.get_by_id(event_id) except DoesNotExist: raise HTTPException( status_code=404, detail=f"No event found with id {event_id}" ) if name is not None: this_event.name = name if short_desc is not None: this_event.short_desc = short_desc if long_desc is not None: this_event.long_desc = long_desc if url is not None: this_event.url = url if thumbnail is not None: this_event.thumbnail = thumbnail if active is not None: this_event.active = active if this_event.save() == 1: return_val = model_to_dict(this_event) return return_val else: raise HTTPException( status_code=418, detail="Well slap my ass and call me a teapot; I could not save that event", ) @router.delete("/{event_id}") async def v1_events_delete(event_id, token: str = Depends(oauth2_scheme)): if not valid_token(token): logging.warning("Bad Token: [REDACTED]") raise HTTPException( status_code=401, detail="You are not authorized to delete events. This event has been logged.", ) try: this_event = Event.get_by_id(event_id) except DoesNotExist: raise HTTPException( status_code=404, detail=f"No event found with id {event_id}" ) count = this_event.delete_instance() if count == 1: raise HTTPException( status_code=200, detail=f"Event {event_id} has been deleted" ) else: raise HTTPException(status_code=500, detail=f"Event {event_id} was not deleted")