"""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 import status from oto.adaptors.flask import flaskify from owsrequest import flask_request from promo_player import config from promo_player.api import app from promo_player.constants import error from promo_player.logic import product from promo_player.logic import promo_player from promo_player.logic import promo_player_track from promo_player.logic import track @app.route(config.HEALTH_CHECK, methods=['GET']) def health(): """Check the health of the application.""" return jsonify({'status': 'ok'}) @app.route('/product//player', methods=['POST']) def create_promo_player(product_id): """Create a new promo player. Args: product_id (int): the product ID Returns: flask.Response: containing the created promo player dict. """ ownership = flask_request.verify_grass_ownership( request, product.is_owner, product_id) if not ownership: return flaskify(ownership) account_type, account_id = flask_request.get_grass_headers(request) data = request.get_json(silent=True, force=True) or {} data['product_id'] = int(product_id) if account_id: data['vendor_id'] = int(account_id) return flaskify(promo_player.create(data)) @app.route('/player', methods=['POST']) def create_promo_player_without_product_id(): """Create a new promo player. Returns: flask.Response: containing the created promo player dict. """ account_type, account_id = flask_request.get_grass_headers(request) data = request.get_json(silent=True, force=True) or {} if account_id: data['vendor_id'] = int(account_id) return flaskify(promo_player.create(data)) @app.route('/player//track/', methods=['POST']) def create_promo_player_track(promo_player_id, track_id): """Create a new promo player track. Args: promo_player_id (int): the promo player ID track_id (int): the track ID Returns: flask.Response: containing the created promo player track dict. """ ownership = flask_request.verify_grass_ownership( request, track.is_owner, track_id) if not ownership: return flaskify(ownership) data = request.get_json(silent=True, force=True) or {} data['promo_player_id'] = int(promo_player_id) data['track_id'] = int(track_id) return flaskify(promo_player_track.create(data)) @app.route('/product//player', methods=['GET']) def get_active_promo_player_by_product_id(product_id): """Get the active promo player for a product. Args: product_id (int): the product ID Returns: flask.Response: containing the promo player dict. """ ownership = flask_request.verify_grass_ownership( request, product.is_owner, product_id) if not ownership: return flaskify(ownership) return flaskify(promo_player.get_active_by_product_id(int(product_id))) @app.route('/product//player/', methods=['PUT']) def update_promo_player(product_id, promo_player_id): """Update an existing promo player. Args: product_id (int): the product ID promo_player_id (int): the promo player ID Returns: flask.Response: containing the updated promo player dict. """ ownership = flask_request.verify_grass_ownership( request, product.is_owner, product_id) if not ownership: return flaskify(ownership) data = request.get_json(silent=True, force=True) or {} data['promo_player_id'] = int(promo_player_id) data['product_id'] = int(product_id) return flaskify(promo_player.update(data)) @app.route('/player/', methods=['PUT']) def update_promo_player_without_product(promo_player_id): """Update an existing promo player. Args: promo_player_id (int): the promo player ID Returns: flask.Response: containing the updated promo player dict. """ data = request.get_json(silent=True, force=True) or {} data['promo_player_id'] = int(promo_player_id) return flaskify(promo_player.update(data)) @app.route('/player//track/', methods=['PUT']) def update_promo_player_track(promo_player_id, track_id): """Update a promo player track. Args: promo_player_id (int): the promo player ID track_id (int): the track ID Returns: flask.Response: containing the updated promo player track dict. """ ownership = flask_request.verify_grass_ownership( request, track.is_owner, track_id) if not ownership: return flaskify(ownership) data = request.get_json(silent=True, force=True) or {} data['promo_player_id'] = int(promo_player_id) data['track_id'] = int(track_id) return flaskify(promo_player_track.update(data)) @app.route('/player//track/', methods=['DELETE']) def delete_promo_player_track(promo_player_id, track_id): """Delete a promo player track. Args: promo_player_id (int): the promo player ID track_id (int): the track ID Returns: flask.Response: containing the deleted promo player track dict. """ ownership = flask_request.verify_grass_ownership( request, track.is_owner, track_id) if not ownership: return flaskify(ownership) return flaskify(promo_player_track.delete( int(promo_player_id), int(track_id))) @app.route('/product//players', methods=['GET']) def get_promo_players_by_product_id(product_id): """Get all the promo players associated with the specified product. Args: product_id (int): the product ID Returns: flask.Response: containing a dict with the list of promo players. """ ownership = flask_request.verify_grass_ownership( request, product.is_owner, product_id) if not ownership: return flaskify(ownership) return flaskify(promo_player.get_by_product_id(int(product_id))) @app.route('/players', methods=['GET']) def get_promo_players_by_vendor_id(): """Get all the promo players for the requesting vendor. Returns: flask.Response: containing a dict with the list of promo players. """ account_type, account_id = flask_request.get_grass_headers(request) if not account_type or not account_id: return flaskify(response.create_error_response( code=error.ERROR_CODE_BAD_GRASS_REQUEST, message=error.ERROR_MESSAGE_MISSING_GRASS_HEADERS, status=status.BAD_REQUEST)) return flaskify(promo_player.get_by_vendor_id(int(account_id))) @app.route('/player/code/', methods=['GET']) def get_promo_player_by_code(code): """Get a promo player by code. Args: code (string): the promo player unique code. Returns: flask.Response: containing the promo player dict. """ return flaskify(promo_player.get_by_code(code)) @app.route('/admin/product//players', methods=['DELETE']) def delete_promo_players_by_product_id(product_id): """Delete all the promo players associated with the specified product. Args: product_id (int): the product ID Returns: flask.Response: containing a dict with the list of delete items. """ ownership = flask_request.verify_grass_ownership( request, product.is_owner, product_id) if not ownership: return flaskify(ownership) return flaskify(promo_player.delete_by_product_id(int(product_id))) @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))