from fastapi import APIRouter, Depends, HTTPException, Response from typing import Optional import logging import pydantic from pandas import DataFrame from ..db_engine import db, Event, model_to_dict, fn from ..dependencies import oauth2_scheme, valid_token, LOG_DATA logging.basicConfig( filename=LOG_DATA['filename'], format=LOG_DATA['format'], level=LOG_DATA['log_level'] ) 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): 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) 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) db.close() return Response(content=return_val, media_type='text/csv') else: return_val = {'count': all_events.count(), 'events': []} for x in all_events: return_val['events'].append(model_to_dict(x)) db.close() 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 Exception: db.close() 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) db.close() return Response(content=return_val, media_type='text/csv') else: return_val = model_to_dict(this_event) db.close() return return_val @router.post('') async def v1_events_post(event: EventModel, token: str = Depends(oauth2_scheme)): if not valid_token(token): logging.warning(f'Bad Token: {token}') db.close() 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: db.close() 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) db.close() return return_val else: db.close() 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(f'Bad Token: {token}') db.close() 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 Exception: db.close() 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) db.close() return return_val else: db.close() 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(f'Bad Token: {token}') db.close() 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 Exception: db.close() raise HTTPException(status_code=404, detail=f'No event found with id {event_id}') count = this_event.delete_instance() db.close() 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')