from datetime import datetime from fastapi import APIRouter, Depends, HTTPException, Response from typing import Optional import logging import pydantic from pandas import DataFrame from ..db_engine import db, Paperdex, model_to_dict, Player, Cardset, Team 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/paperdex', tags=['paperdex'] ) class PaperdexModel(pydantic.BaseModel): team_id: int player_id: int created: Optional[int] = int(datetime.timestamp(datetime.now())*1000) @router.get('') async def get_paperdex( team_id: Optional[int] = None, player_id: Optional[int] = None, created_after: Optional[int] = None, cardset_id: Optional[int] = None, created_before: Optional[int] = None, flat: Optional[bool] = False, csv: Optional[bool] = None): all_dex = Paperdex.select().join(Player).join(Cardset).order_by(Paperdex.id) if all_dex.count() == 0: db.close() raise HTTPException(status_code=404, detail=f'There are no paperdex to filter') if team_id is not None: all_dex = all_dex.where(Paperdex.team_id == team_id) if player_id is not None: all_dex = all_dex.where(Paperdex.player_id == player_id) if cardset_id is not None: all_sets = Cardset.select().where(Cardset.id == cardset_id) all_dex = all_dex.where(Paperdex.player.cardset.id == cardset_id) if created_after is not None: # Convert milliseconds timestamp to datetime for PostgreSQL comparison created_after_dt = datetime.fromtimestamp(created_after / 1000) all_dex = all_dex.where(Paperdex.created >= created_after_dt) if created_before is not None: # Convert milliseconds timestamp to datetime for PostgreSQL comparison created_before_dt = datetime.fromtimestamp(created_before / 1000) all_dex = all_dex.where(Paperdex.created <= created_before_dt) # if all_dex.count() == 0: # db.close() # raise HTTPException(status_code=404, detail=f'No paperdex found') if csv: data_list = [['id', 'team_id', 'player_id', 'created']] for line in all_dex: data_list.append( [ line.id, line.team.id, line.player.player_id, line.created ] ) 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_dex.count(), 'paperdex': []} for x in all_dex: return_val['paperdex'].append(model_to_dict(x, recurse=not flat)) db.close() return return_val @router.get('/{paperdex_id}') async def get_one_paperdex(paperdex_id, csv: Optional[bool] = False): try: this_dex = Paperdex.get_by_id(paperdex_id) except Exception: db.close() raise HTTPException(status_code=404, detail=f'No paperdex found with id {paperdex_id}') if csv: data_list = [ ['id', 'team_id', 'player_id', 'created'], [this_dex.id, this_dex.team.id, this_dex.player.id, this_dex.created] ] 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_dex) db.close() return return_val @router.post('') async def post_paperdex(paperdex: PaperdexModel, 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 paperdex. This event has been logged.' ) dupe_dex = Paperdex.get_or_none(Paperdex.team_id == paperdex.team_id, Paperdex.player_id == paperdex.player_id) if dupe_dex: return_val = model_to_dict(dupe_dex) db.close() return return_val this_dex = Paperdex( team_id=paperdex.team_id, player_id=paperdex.player_id, created=datetime.fromtimestamp(paperdex.created / 1000) ) saved = this_dex.save() if saved == 1: return_val = model_to_dict(this_dex) db.close() return return_val else: raise HTTPException( status_code=418, detail='Well slap my ass and call me a teapot; I could not save that dex' ) @router.patch('/{paperdex_id}') async def patch_paperdex( paperdex_id, team_id: Optional[int] = None, player_id: Optional[int] = None, created: Optional[int] = 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 paperdex. This event has been logged.' ) try: this_dex = Paperdex.get_by_id(paperdex_id) except Exception: db.close() raise HTTPException(status_code=404, detail=f'No paperdex found with id {paperdex_id}') if team_id is not None: this_dex.team_id = team_id if player_id is not None: this_dex.player_id = player_id if created is not None: this_dex.created = datetime.fromtimestamp(created / 1000) if this_dex.save() == 1: return_val = model_to_dict(this_dex) db.close() return return_val else: raise HTTPException( status_code=418, detail='Well slap my ass and call me a teapot; I could not save that rarity' ) @router.delete('/{paperdex_id}') async def delete_paperdex(paperdex_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 rewards. This event has been logged.' ) try: this_dex = Paperdex.get_by_id(paperdex_id) except Exception: db.close() raise HTTPException(status_code=404, detail=f'No paperdex found with id {paperdex_id}') count = this_dex.delete_instance() db.close() if count == 1: raise HTTPException(status_code=200, detail=f'Paperdex {this_dex} has been deleted') else: raise HTTPException(status_code=500, detail=f'Paperdex {this_dex} was not deleted') @router.post('/wipe-ai') async def wipe_ai_paperdex(token: str = Depends(oauth2_scheme)): if not valid_token(token): logging.warning(f'Bad Token: {token}') db.close() raise HTTPException( status_code=401, detail='Unauthorized' ) g_teams = Team.select().where(Team.abbrev.contains('Gauntlet')) count = Paperdex.delete().where(Paperdex.team << g_teams).execute() return f'Deleted {count} records'