"""Handler for video single metadata updates.""" from switchboard_consumer.constants.exceptions import \ ParticipantHandlerError, ParticipantHandlerGraphQLError from switchboard_consumer.constants.product_metadata_update import \ CANNOT_RELEASE_CORRECT_VIDEO_PRODUCT, \ CANNOT_RELEASE_CORRECT_VIDEO_PRODUCT_CODE from switchboard_consumer.constants.validation import REJECT_RESPONSE, \ VALIDATION_CODE from switchboard_consumer.formatters.errors import format_exception, \ format_generic_error, format_graphql_errors from switchboard_consumer.formatters.product import format_result_id from switchboard_consumer.formatters.video_single_product import \ format_video_single_create_input, format_video_single_update_input from switchboard_consumer.logic.participant.video_single_participant_handler \ import VideoSingleParticipantHandler from switchboard_consumer.logic.product_metadata_update import ProductHandler from switchboard_consumer.logic.validation.video_single_product import validate from switchboard_consumer.utils.message import create_processing_result def enrich_validation_errors(fn): def inner(self): results = fn(self) if results: results[-1]['errors'].extend(self.validation_errors) return results return inner class VideoSingleHandler(ProductHandler): """Handles video single metadata update.""" def validate(self): """Check if product body is correct.""" body_validation_errors = validate.validate_video_single_product( self.swb_product_data ) response_types = [body_validation_error['response'] for body_validation_error in body_validation_errors] if REJECT_RESPONSE in response_types: self.processing_results.append(create_processing_result( self.message.ids, self.message, errors=body_validation_errors)) return False self.validation_errors.extend(body_validation_errors) return True def process_participants(self): """Process product participants.""" try: participant_handler = VideoSingleParticipantHandler( self.logger, self.orchard_client, self.message, self.swb_product_data, self.vendor_id, self.subaccount_id) processing_results, artists = participant_handler.process() self.processing_results.extend(processing_results) self.artists = artists return True except ParticipantHandlerGraphQLError as e: self.processing_results.append(create_processing_result( self.message.ids, self.message, errors=e.raw_errors)) return False except ParticipantHandlerError as e: self.processing_results.append(create_processing_result( self.message.ids, self.message, exception=format_exception(e))) return False def validate_channel_selection_before_create(self, payload): """Validate channel selection before create.""" if not payload.get('channelSelection'): self.validation_errors.append({ 'code': VALIDATION_CODE, 'message': 'VEVO channel can not be empty'}) return available_channels = ( self.orchard_client.get_project_available_channels( payload['projectId'], payload['accountId'], payload['subaccountId'], self.message.correlation_id)) return self._process_channel_selection_data( available_channels, payload) def validate_channel_selection_before_update(self, payload): """Validate channel selection before update.""" if not payload.get('channelSelection'): self.validation_errors.append({ 'code': VALIDATION_CODE, 'message': 'VEVO channel can not be empty'}) return available_channels = ( self.orchard_client.get_product_available_channels( payload['productId'], self.message.correlation_id)) return self._process_channel_selection_data( available_channels, payload) def _process_channel_selection_data(self, channels_response, payload): if isinstance(channels_response, dict) and channels_response.get( 'errors'): self.validation_errors.append({ 'code': VALIDATION_CODE, 'message': 'Failed to validate VEVO channel'}) return channel = payload['channelSelection'] available_channels_names = [ channel['channelName'] for channel in channels_response] if channel not in available_channels_names: self.validation_errors.append({ 'code': VALIDATION_CODE, 'message': f'''Channel {channel} is not available'''}) return False return True def create_product(self): """Create new Orchard product.""" payload = format_video_single_create_input( self.swb_product_data, self.artists) if not self.validate_channel_selection_before_create(payload): payload['channelSelection'] = None create_result = self.orchard_client.create_video_single_product( payload, self.message.correlation_id) if create_result.get('errors'): errors = create_result['errors'] self.logger.error( 'Problem inserting product. - {}'.format(errors)) self.processing_results.append(create_processing_result( self.message.ids, self.message, errors=format_graphql_errors(errors))) return False product_id = create_result['productId'] self.product_id = product_id self.logger.info( f'''Product inserted into Orchard with id: {product_id}''') original_id = self.message.sending_system_local_id result_ids = format_result_id(product_id, original_id) self.processing_results.append(create_processing_result( self.message.ids + result_ids, self.message)) return True def update_in_progress_product(self, product_id): """Update existing Orchard product.""" payload = format_video_single_update_input( self.swb_product_data, self.artists) if not self.validate_channel_selection_before_update(payload): payload['channelSelection'] = None update_result = self.orchard_client.update_video_single_product( payload, self.message.correlation_id) if update_result.get('errors'): errors = update_result['errors'] self.logger.error( f'''Problem updating product. - {errors}''') self.processing_results.append(create_processing_result( self.message.ids, self.message, errors=format_graphql_errors(errors))) return False product_id = update_result['productId'] self.logger.info( f'''Product updated in Orchard with id: {product_id}''') original_id = self.message.sending_system_local_id result_ids = format_result_id(product_id, original_id) self.processing_results.append(create_processing_result( self.message.ids + result_ids, self.message)) return True def update_via_release_correction(self, product_id): """Handle update of completed product.""" self.logger.info(CANNOT_RELEASE_CORRECT_VIDEO_PRODUCT) self.processing_results.append(create_processing_result( self.message.ids, self.message, errors=[format_generic_error( CANNOT_RELEASE_CORRECT_VIDEO_PRODUCT, CANNOT_RELEASE_CORRECT_VIDEO_PRODUCT_CODE )] )) return False @enrich_validation_errors def process(self): """Process product.""" return super(VideoSingleHandler, self).process()