""" Routes - Heroes """ import json from flask import ( Blueprint, Response, request ) from flask_jwt_extended import ( jwt_required, get_jwt_identity ) from database.models import ( PowerstatsModel, BiographyModel, AppearanceModel, WorkModel, ConnectionModel, ImageModel, HeroeModel, UserModel ) from mongoengine.errors import ( FieldDoesNotExist, NotUniqueError, DoesNotExist, ValidationError, InvalidQueryError ) from utils.errors import ( heroe_already_exists_error, updating_heroe_error, internal_server_error, schema_validation_error, not_data_found ) from utils.decorators import superuser from utils.strings import capitalize_each from bson.objectid import ObjectId heroes = Blueprint("heroes", __name__) @heroes.route('/heroes', methods=['POST']) @jwt_required() @superuser def create_heroe(): """Receive data for create heroe""" try: user_id = get_jwt_identity() user = UserModel.objects.get(id=user_id) powerstats = PowerstatsModel( intelligence=request.json['powerstats']['intelligence'], strength=request.json['powerstats']['strength'], speed=request.json['powerstats']['speed'], durability=request.json['powerstats']['durability'], power=request.json['powerstats']['power'], combat=request.json['powerstats']['combat'] ) biography = BiographyModel( fullname=request.json['biography']['full-name'], alteregos=request.json['biography']['alter-egos'], aliases=request.json['biography']['aliases'], placeofbirth=request.json['biography']['place-of-birth'], firstappearance=request.json['biography']['first-appearance'], publisher=request.json['biography']['publisher'], alignment=request.json['biography']['alignment'] ) appearance = AppearanceModel( gender=request.json['appearance']['gender'], race=request.json['appearance']['race'], height=request.json['appearance']['height'], weight=request.json['appearance']['weight'], eyecolor=request.json['appearance']['eye-color'], haircolor=request.json['appearance']['hair-color'] ) work = WorkModel( occupation=request.json['work']['occupation'], base=request.json['work']['base'] ) connections = ConnectionModel( groupaffiliation=request.json['connections']['group-affiliation'], relatives=request.json['connections']['relatives'] ) image = ImageModel( url=request.json['image']['url'] ) heroe = HeroeModel( name=capitalize_each(request.json['name']), powerstats=powerstats, biography=biography, appearance=appearance, work=work, connections=connections, image=image, added_by=user ).save() # update user collection user.update(push__heroes=heroe) user.save() except (FieldDoesNotExist, ValidationError) as e: return schema_validation_error(e) except NotUniqueError as e: return heroe_already_exists_error(e) except Exception as e: return internal_server_error(e) else: data = { '_id': str(heroe.id), "name": heroe.name, } return Response( response=json.dumps(data), status=201, mimetype="applications/json" ) @heroes.route('/heroes', methods=['GET']) @jwt_required() def get_some_heroes(): """Get all heroes""" try: heroe = HeroeModel.objects() if len(heroe) > 0: response = heroe.exclude('added_by').to_json() else: raise DoesNotExist except DoesNotExist: return not_data_found() except Exception as e: return internal_server_error(e) else: return Response( response, status=200, mimetype="application/json" ) @heroes.route('/heroes/', methods=['GET']) @jwt_required() def get_some_heroe(id): """Get heroe by id""" try: if ObjectId.is_valid(id): heroe = HeroeModel.objects(id=id) else: raise DoesNotExist if len(heroe) > 0: data = heroe.exclude('added_by').to_json() else: raise DoesNotExist except DoesNotExist: return not_data_found() except Exception as e: return internal_server_error(e) else: return Response( response=(data), status=200, mimetype="application/json" ) @heroes.route('/heroes//powerstats', methods=['GET']) @jwt_required() def get_powerstats_heroe(id): """Get heroe by id""" try: if ObjectId.is_valid(id): heroe = HeroeModel.objects.get(id=id).powerstats else: raise DoesNotExist if len(heroe) > 0: data = heroe.to_json() else: raise DoesNotExist except DoesNotExist: return not_data_found() except Exception as e: return internal_server_error(e) else: return Response( response=(data), status=200, mimetype="application/json" ) @heroes.route('/heroes//biography', methods=['GET']) @jwt_required() def get_biography_heroe(id): """Get heroe by id""" try: if ObjectId.is_valid(id): heroe = HeroeModel.objects.get(id=id).biography else: raise DoesNotExist if len(heroe) > 0: data = heroe.to_json() else: raise DoesNotExist except DoesNotExist: return not_data_found() except Exception as e: return internal_server_error(e) else: return Response( response=(data), status=200, mimetype="application/json" ) @heroes.route('/heroes//appearance', methods=['GET']) @jwt_required() def get_appearance_heroe(id): """Get heroe by id""" try: if ObjectId.is_valid(id): heroe = HeroeModel.objects.get(id=id).appearance else: raise DoesNotExist if len(heroe) > 0: data = heroe.to_json() else: raise DoesNotExist except DoesNotExist: return not_data_found() except Exception as e: return internal_server_error(e) else: return Response( response=(data), status=200, mimetype="application/json" ) @heroes.route('/heroes//work', methods=['GET']) @jwt_required() def get_work_heroe(id): """Get heroe by id""" try: if ObjectId.is_valid(id): heroe = HeroeModel.objects.get(id=id).work else: raise DoesNotExist if len(heroe) > 0: data = heroe.to_json() else: raise DoesNotExist except DoesNotExist: return not_data_found() except Exception as e: return internal_server_error(e) else: return Response( response=(data), status=200, mimetype="application/json" ) @heroes.route('/heroes//connections', methods=['GET']) @jwt_required() def get_connections_heroe(id): """Get heroe by id""" try: if ObjectId.is_valid(id): heroe = HeroeModel.objects.get(id=id).connections else: raise DoesNotExist if len(heroe) > 0: data = heroe.to_json() else: raise DoesNotExist except DoesNotExist: return not_data_found() except Exception as e: return internal_server_error(e) else: return Response( response=(data), status=200, mimetype="application/json" ) @heroes.route('/heroes//image', methods=['GET']) @jwt_required() def get_image_heroe(id): """Get heroe by id""" try: if ObjectId.is_valid(id): heroe = HeroeModel.objects.get(id=id).image else: raise DoesNotExist if len(heroe) > 0: data = heroe.to_json() else: raise DoesNotExist except DoesNotExist: return not_data_found() except Exception as e: return internal_server_error(e) else: return Response( response=(data), status=200, mimetype="application/json" ) @heroes.route('/heroes/search/', methods=['GET']) @jwt_required() def get_some_heroe_name(name): """Search heroe by name""" try: name = capitalize_each(name) heroe = HeroeModel.objects.filter(name=name) if len(heroe) > 0: data = heroe.exclude('added_by').to_json() else: raise DoesNotExist except DoesNotExist: return not_data_found() except Exception as e: return internal_server_error(e) else: return Response( response=(data), status=200, mimetype="application/json" ) @heroes.route('/heroes/', methods=['DELETE']) @jwt_required() @superuser def delete_some_heroe(id): """Delete heroe by id""" try: user_id = get_jwt_identity() if ObjectId.is_valid(id): heroe = HeroeModel.objects.get(id=id, added_by=user_id) heroe.delete() except DoesNotExist: return not_data_found() except Exception as e: return internal_server_error(e) else: _heroe = str(heroe.id) data = { "msg": f"Heroe: {_heroe}, was deleted" } return Response( response=json.dumps(data), status=200, mimetype="application/json" ) @heroes.route('/heroes/', methods=['PUT']) @jwt_required() @superuser def put_heroe(id): """Receive data for update heroe""" try: user_id = get_jwt_identity() heroe = HeroeModel.objects.get(id=id, added_by=user_id) powerstats = PowerstatsModel( intelligence=request.json['powerstats']['intelligence'], strength=request.json['powerstats']['strength'], speed=request.json['powerstats']['speed'], durability=request.json['powerstats']['durability'], power=request.json['powerstats']['power'], combat=request.json['powerstats']['combat'] ) biography = BiographyModel( fullname=request.json['biography']['full-name'], alteregos=request.json['biography']['alter-egos'], aliases=request.json['biography']['aliases'], placeofbirth=request.json['biography']['place-of-birth'], firstappearance=request.json['biography']['first-appearance'], publisher=request.json['biography']['publisher'], alignment=request.json['biography']['alignment'] ) appearance = AppearanceModel( gender=request.json['appearance']['gender'], race=request.json['appearance']['race'], height=request.json['appearance']['height'], weight=request.json['appearance']['weight'], eyecolor=request.json['appearance']['eye-color'], haircolor=request.json['appearance']['hair-color'] ) work = WorkModel( occupation=request.json['work']['occupation'], base=request.json['work']['base'] ) connections = ConnectionModel( groupaffiliation=request.json['connections']['group-affiliation'], relatives=request.json['connections']['relatives'] ) image = ImageModel( url=request.json['image']['url'] ) heroe.update( name=capitalize_each(request.json['name']), powerstats=powerstats, biography=biography, appearance=appearance, work=work, connections=connections, image=image ) except InvalidQueryError as e: return schema_validation_error(e) except DoesNotExist as e: return updating_heroe_error(e) except Exception as e: return internal_server_error(e) else: data = { '_id': str(heroe.id), "name": heroe.name, } return Response( response=json.dumps(data), status=201, mimetype="applications/json" )