2021-10-18 15:49:47 -04:00
|
|
|
from api.models.pokemon_owned import pokemon_owned_schema, pokemon_owned_schemas, PokemonOwned
|
|
|
|
from api.app import db
|
2021-10-19 00:06:08 -04:00
|
|
|
from api.util.fetch import *
|
|
|
|
from api.util.parse_args import parse_limit, parse_offset, ParsingException, parse_json_obj
|
2021-10-18 15:49:47 -04:00
|
|
|
from .errors import ParsingError, FetchError, ConflictingResources
|
|
|
|
from aiohttp import ClientSession
|
2021-10-18 23:26:16 -04:00
|
|
|
import asyncio
|
2021-10-18 15:49:47 -04:00
|
|
|
from sqlalchemy.exc import IntegrityError
|
|
|
|
|
|
|
|
def post_pokemon_owned(trainer_id):
|
|
|
|
try:
|
|
|
|
json = parse_json_obj()
|
|
|
|
pokemon_id = json["pokemon_id"]
|
|
|
|
name = json["name"]
|
|
|
|
level = json["level"]
|
|
|
|
except ParsingException as e:
|
|
|
|
return ParsingError(e.message)
|
|
|
|
except KeyError:
|
|
|
|
return ParsingError("Missing JSON object fields")
|
|
|
|
|
|
|
|
pokemon = PokemonOwned(
|
|
|
|
name=name,
|
|
|
|
level=level,
|
|
|
|
pokemon_id=pokemon_id,
|
|
|
|
trainer_id=trainer_id
|
|
|
|
)
|
|
|
|
|
|
|
|
try:
|
|
|
|
set_pokemon_data(pokemon)
|
|
|
|
|
|
|
|
db.session.add(pokemon)
|
|
|
|
db.session.commit()
|
2021-10-18 23:26:16 -04:00
|
|
|
except NotFound as e:
|
2021-10-18 15:49:47 -04:00
|
|
|
return FetchError(e.message)
|
|
|
|
except IntegrityError:
|
|
|
|
return ConflictingResources("Trainer already has another pokemon with the same name")
|
|
|
|
|
|
|
|
return (pokemon_owned_schema.dump(pokemon), 201)
|
|
|
|
|
|
|
|
async def get_pokemons_owned(trainer_id):
|
|
|
|
try:
|
|
|
|
limit = parse_limit()
|
|
|
|
offset = parse_offset()
|
|
|
|
except ParsingException as e:
|
|
|
|
return ParsingError(e.message)
|
|
|
|
|
|
|
|
try:
|
|
|
|
trainer = get_trainer_fail(trainer_id)
|
2021-10-18 16:42:26 -04:00
|
|
|
except NotFound:
|
2021-10-18 15:49:47 -04:00
|
|
|
return "", 404
|
|
|
|
|
|
|
|
pokemons = trainer.pokemons_list.limit(limit).offset(offset).all()
|
|
|
|
|
|
|
|
async with ClientSession() as session:
|
|
|
|
tasks = []
|
|
|
|
for pokemon in pokemons:
|
2021-10-18 23:26:16 -04:00
|
|
|
task = asyncio.create_task(async_set_pokemon_data(session, pokemon))
|
2021-10-18 15:49:47 -04:00
|
|
|
tasks.append(task)
|
|
|
|
try:
|
2021-10-18 23:26:16 -04:00
|
|
|
await asyncio.gather(*tasks)
|
|
|
|
except NotFound as e:
|
|
|
|
for task in tasks:
|
|
|
|
task.cancel()
|
2021-10-18 15:49:47 -04:00
|
|
|
return FetchError(e.message)
|
|
|
|
|
2021-10-18 23:26:16 -04:00
|
|
|
# workaround pra bug do aiohttp, que pode gerar avisos de conexões abertas
|
|
|
|
# ver documentação: https://docs.aiohttp.org/en/stable/client_advanced.html#graceful-shutdown
|
|
|
|
# será arrumado na versão 4.0.0, que ainda não saiu
|
|
|
|
# issue no github: https://github.com/aio-libs/aiohttp/issues/1925
|
|
|
|
await asyncio.sleep(0.250)
|
|
|
|
|
2021-10-18 15:49:47 -04:00
|
|
|
return pokemon_owned_schemas.dumps(pokemons)
|
2021-10-18 16:42:26 -04:00
|
|
|
|
|
|
|
def get_pokemon_owned(trainer_id, pokemon_id):
|
|
|
|
try:
|
|
|
|
trainer = get_trainer_fail(trainer_id)
|
|
|
|
pokemon = get_pokemon_fail(trainer, pokemon_id)
|
|
|
|
set_pokemon_data(pokemon)
|
|
|
|
return pokemon_owned_schema.dump(pokemon)
|
|
|
|
except NotFound:
|
|
|
|
return "", 404
|
|
|
|
except HTTPError as e:
|
|
|
|
return FetchError(e.message)
|
2021-10-18 23:26:16 -04:00
|
|
|
except NotFound as e:
|
|
|
|
return ParsingError(e.message)
|
2021-10-18 16:59:57 -04:00
|
|
|
|
|
|
|
def delete_pokemon_owned(trainer, pokemon_id):
|
|
|
|
try:
|
|
|
|
pokemon = get_pokemon_fail(trainer, pokemon_id)
|
|
|
|
set_pokemon_data(pokemon)
|
|
|
|
db.session.delete(pokemon)
|
|
|
|
db.session.commit()
|
|
|
|
return pokemon_owned_schema.dump(pokemon)
|
|
|
|
except NotFound:
|
|
|
|
return "", 404
|
|
|
|
except HTTPError as e:
|
|
|
|
return FetchError(e.message)
|