"""Application Handlers. Requests are redirected to handlers, which are responsible for getting information from the URL and passing it down to the logic layer. The way each layer talks to each other is through Response objects which defines the type status of the data and the data itself. Please note: the Orchard uses the term handlers over views as convention for clarity See: oto.response for more details. """ from flask import g from flask import jsonify from flask import request from oto import response from oto.adaptors.flask import flaskify from owsrequest import flask_request from product_digital_marketing import config from product_digital_marketing import exceptions from product_digital_marketing.api import app from product_digital_marketing.constants import header from product_digital_marketing.logic import highlight_logic from product_digital_marketing.logic import highlight_projection_logic from product_digital_marketing.logic import territory_logic from product_digital_marketing.schemas import highlight_projections_schema from product_digital_marketing.schemas import highlight_schema from product_digital_marketing.utils import handlers as handlers_utils @app.route(config.HEALTH_CHECK, methods=['GET']) def health(): """Check the health of the application.""" return jsonify({'status': 'ok'}) @app.errorhandler(500) def exception_handler(error): """Handle error when uncaught exception is raised. Default exception handler. Note: Exception will also be sent to Sentry if config.SENTRY is set. Returns: flask.Response: A 500 response with JSON 'code' & 'message' payload. """ message = ( 'The server encountered an internal error ' 'and was unable to complete your request.') g.log.exception(error) return flaskify(response.create_fatal_response(message)) @app.errorhandler(exceptions.RequestError) def handle_request_error(exc): """Handle request and validation errors.""" return exc.make_flask_response() @app.route('/marketing/', methods=['GET']) def get_marketing_highlight(product_id): """Fetch product marketing highlight. Args: product_id (int): Product id. Returns: flask.Response: on successful, 200 status with JSON body. """ headers_response = flask_request.verify_grass_headers(request) if not headers_response: return flaskify(headers_response) ownership_response = flask_request.verify_grass_ownership( request, handlers_utils.check_product_ownership, product_id=product_id) if not ownership_response: return flaskify(ownership_response) return flaskify( highlight_logic.get_marketing_highlight_by_product_id(product_id)) @app.route('/marketing/', methods=['POST']) def upsert_marketing_highlight(product_id): """Create or update marketing highlights for a product. Args: product_id (int): Product id. Returns: flask.Response: on successful, 200 status with JSON body. """ headers_response = flask_request.verify_grass_headers(request) if not headers_response: return flaskify(headers_response) ownership_response = flask_request.verify_grass_ownership( request, handlers_utils.check_product_ownership, product_id=product_id) if not ownership_response: return flaskify(ownership_response) highlight_data = handlers_utils.parse_request_json( schema=highlight_schema.HighlightPostSchema) orchard_user_id = '' if header.ORCHARD_USER_ID in request.headers: orchard_user_id = request.headers[header.ORCHARD_USER_ID] return flaskify(highlight_logic.upsert_marketing_highlight( product_id, highlight_data, orchard_user_id)) @app.route('/marketing//projections', methods=['POST']) def upsert_marketing_highlight_projection(product_id): """Create product marketing highlight_projections. Args: product_id (int): Product id. Returns: flask.Response: on successful, 200 status with JSON body. """ headers_response = flask_request.verify_grass_headers(request) if not headers_response: return flaskify(headers_response) ownership_response = flask_request.verify_grass_ownership( request, handlers_utils.check_product_ownership, product_id=product_id) if not ownership_response: return flaskify(ownership_response) highlight_projection_data = handlers_utils.parse_request_json( schema=highlight_projections_schema.HighlightProjectionsPostItems ) orchard_user_id = '' if header.ORCHARD_USER_ID in request.headers: orchard_user_id = request.headers[header.ORCHARD_USER_ID] return flaskify( highlight_projection_logic.upsert_marketing_highlight_projections( product_id, highlight_projection_data, orchard_user_id)) @app.route('/marketing/territories', methods=['GET']) def get_marketing_territories(): """Fetch product marketing territories. Returns: flask.Response: on successful, 200 status with JSON body. """ headers_response = flask_request.verify_grass_headers(request) if not headers_response: return flaskify(headers_response) return flaskify( territory_logic.get_marketing_territories()) @app.route('/public/marketing/territories', methods=['GET']) def get_public_marketing_territories(): """Fetch product marketing territories. Returns: flask.Response: on successful, 200 status with JSON body. """ headers = {'Cache-Control': 'max-age=86400'} headers_response = flask_request.verify_grass_headers(request) if not headers_response: return flaskify(headers_response) return flaskify( territory_logic.get_marketing_territories(), headers) @app.route( '/marketing//projection/', methods=['DELETE']) def delete_marketing_projection(product_id, projection_id): """Delete projection for product. Args: product_id (int): Product id. projection_id (int): Product id. Returns: flask.Response: on successful, 200 status with JSON body. """ headers_response = flask_request.verify_grass_headers(request) if not headers_response: return flaskify(headers_response) ownership_response = flask_request.verify_grass_ownership( request, handlers_utils.check_product_ownership, product_id=product_id) if not ownership_response: return flaskify(ownership_response) return flaskify(highlight_projection_logic.delete_highlight_projection( product_id, projection_id)) @app.route( '/marketing//copy/', methods=['POST'] ) def copy_marketing(source_product_id, target_product_id): """Copy marketing data for newly created digital product. Returns: flask.Response: on successful, 201 status. """ return flaskify( highlight_logic.copy_marketing(source_product_id, target_product_id))