"""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 request from oto import response from oto.adaptors.flask import flaskify from owsrequest.constants import headers as owsrequest_headers from product_workflow import config from product_workflow.api import app from product_workflow.constants import error from product_workflow.logic import hello from product_workflow.logic import meta_update_queue from product_workflow.logic import metadata_queue from product_workflow.logic import product_submission from product_workflow.logic import rejection_notes from product_workflow.logic import release_approval_queue from product_workflow.logic import release_correction from product_workflow.logic import release_correction_detail from product_workflow.utils import handler_util from product_workflow.validation import json_schema @app.route(config.HEALTH_CHECK, methods=['GET']) def health(): """Check the health of the application.""" return flaskify(hello.health_check()) @app.route( '/release-approval//rejections', methods=['GET']) @json_schema.validate_request_headers def get_rejection_notes(release_approval_id): """Get all of the rejection notes for the given id.""" return flaskify(rejection_notes.get_rejection_notes(release_approval_id)) @app.route('/release-approval/rejections', methods=['PUT']) @json_schema.validate_request_headers @json_schema.validate_request_body def update_rejections(): """Update properties for a set of rejections.""" rejections_data = request.get_json() return flaskify( rejection_notes.update_rejection_notes( rejections_data.get('rejections'))) @app.route('/product//release-approval', methods=['GET']) @json_schema.validate_request_headers def get_last_release_approval_for_product(product_id): """Get the last release_approval_queue record for a product.""" return flaskify( release_approval_queue.get_last_approval( product_id)) @app.route('/product//release-approval', methods=['POST']) @json_schema.validate_request_headers @json_schema.validate_request_body def create_release_approval_for_product(product_id): """Create a new release_approval_queue record for a product.""" approval_data = request.get_json() return flaskify( release_approval_queue.create_release_approval_queue_record( product_id, approval_data)) @app.route('/product//submission', methods=['POST']) @json_schema.validate_request_headers @json_schema.validate_request_body def submit_product_by_id(product_id): """Create a new release_approval_queue record for a product.""" submit_data = request.get_json() account_id = submit_data.get('account_id') account_type = submit_data.get('account_type') if not account_id or not account_type: valid_identity = handler_util.is_identity_authorized( submit_data.get('identity_id')) if not valid_identity: return flaskify(response.create_error_response( error.ERROR_CODE_BAD_REQUEST, error.ERROR_CODE_AUTHORIZATION)) return flaskify( product_submission.submit_digital_product( product_id, submit_data)) @app.route('/product//correction', methods=['GET']) @json_schema.validate_request_headers def get_last_release_correction_for_product(product_id): """Get the last release_correction record for a product.""" return flaskify(release_correction.get_last_correction(product_id)) @app.route('/correction/', methods=['GET']) @json_schema.validate_request_headers def get_correction(release_correction_id): """Get a release_correction record by id.""" return flaskify(release_correction.get_correction(release_correction_id)) @app.route('/product//correction', methods=['POST']) @json_schema.validate_request_headers @json_schema.validate_request_body def create_correction_for_product(product_id): """Create a release_correction record for a product.""" correction_data = request.get_json() return flaskify( release_correction.create_release_correction_record( product_id, correction_data)) @app.route( '/correction//details', methods=['POST']) @json_schema.validate_request_headers @json_schema.validate_request_body def upsert_correction_details(release_correction_id): """Create the correction details for the given id and details.""" correction_details_data = request.get_json() return flaskify( release_correction_detail.upsert_correction_details_records( release_correction_id, correction_details_data)) @app.route('/correction/', methods=['PUT']) @json_schema.validate_request_headers @json_schema.validate_request_body def update_release_correction(release_correction_id): """Update properties for a release correction.""" correction_data = request.get_json() return flaskify(release_correction.update_release_correction_record( release_correction_id, correction_data )) @app.route( '/correction/', methods=['DELETE'] ) @json_schema.validate_request_headers def delete_correction_for_product(release_correction_id): """Delete an active correction that is in active state.""" return flaskify( release_correction.delete_release_correction(release_correction_id)) @app.route('/product//approve', methods=['POST']) def approve_product(product_id): """Apply correction lyrics value while approving release.""" return flaskify( release_approval_queue.approve_product(product_id)) @app.errorhandler(500) def exception_handler(error): """Raise error when there is an uncaught exception. 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.route('/product//lyrics', methods=['GET']) def get_track_lyrics_for_product(product_id): """Get track lyrics response for a product. Args: product_id (int): id of the product Returns: flask.Response: on success, 200 status with JSON body containing whether lyrics present for tracks are in active correction or in ows-lyrics for a product. """ return flaskify( release_correction.get_lyrics_by_product_id(product_id)) @app.route('/product//lyrics/', methods=['GET']) def get_lyrics_for_track(product_id, track_id): """Get lyrics response data for given track_id and product_id. Args: product_id (int): id of the product track_id (int): id of the track Returns: flask.Response: on success, 200 status with JSON body containing lyrics present for given track from correction or ows-lyrics. """ return flaskify( release_correction.get_lyrics_by_track_id(product_id, track_id)) @app.route('/product//unsubmit', methods=['POST']) @json_schema.validate_request_headers def unsubmit_product_by_id(product_id): """Unsubmit a digital product by deleting it's latest release approval queue.""" submit_data = request.get_json() return flaskify(product_submission.unsubmit_digital_product(product_id, submit_data)) @app.route('/product//process_metadata_queue', methods=['POST']) def process_metadata(product_id): """Process the metadata queue.""" metadata_queue.process() return flaskify(response.Response(status=200)) @app.route('/product//metadata_queue', methods=['POST']) @json_schema.validate_request_body def create_metadata_update(product_id): """Create meta update for a given product id. Args: product_id (str): Product id to create scheduled update for. Returns: flask.response: Response containing success message. """ orchard_identity_id = request.headers.get( owsrequest_headers.ORCHARD_IDENTITY_ID) if not orchard_identity_id: return flaskify(response.create_error_response( error.ERROR_CODE_BAD_REQUEST, error.ERROR_CODE_AUTHORIZATION)) return flaskify(meta_update_queue.create_meta_update_queue( product_id, request.get_json()))