"""Validation schemas description.""" from marshmallow import EXCLUDE from marshmallow import fields from marshmallow import pre_load from marshmallow import Schema from marshmallow import validate from marshmallow import validates_schema from marshmallow import ValidationError from asset_transcoder.constants import asset_status from asset_transcoder.constants import asset_types from asset_transcoder.constants import asset_upload from asset_transcoder.constants import urls def _validate_object_types(object_types): for object_type in object_types: if object_type not in asset_upload.OBJECT_TYPES: raise ValidationError('Invalid object type passed in {}.'.format(object_type)) class GetAssetsByIdsAndTypesSchema(Schema): """Get Assets validation schema.""" object_ids = fields.List(fields.String(), required=True) object_types = fields.List(fields.String(), validate=_validate_object_types, required=True) signed_url_policy = fields.String(required=False, validate=validate.OneOf(urls.URL_POLICIES)) signed_url_duration = fields.Int(required=False, validate=validate.Range(min=10, max=240)) @pre_load def _split_names(self, in_data, **kwargs): object_ids = in_data['object_ids'].split(',') object_types = in_data['object_types'].split(',') return { 'object_types': object_types, 'object_ids': object_ids, 'signed_url_policy': in_data.get('signed_url_policy', urls.SIGNED_URL), 'signed_url_duration': in_data.get('signed_url_duration', urls.DEFAULT_SIGNED_URL_DURATION) } @validates_schema def _validates_same_arity(self, data, **kwargs): if len(data['object_ids']) != len(data['object_types']): raise ValidationError('object_ids and object_types arent the same size') class Meta: """Allow unknown fields to exclude from payload before processing.""" unknown = EXCLUDE class GetAssetsByIdsAndTypeSchema(Schema): """Get Assets validation schema.""" object_ids = fields.List(fields.String(), required=True) signed_url_policy = fields.String(required=False, validate=validate.OneOf(urls.URL_POLICIES)) signed_url_duration = fields.Int(required=False, validate=validate.Range(min=10, max=120)) @pre_load def _split_names(self, in_data, **kwargs): object_ids = in_data['object_ids'].split(',') return { 'object_ids': object_ids, 'signed_url_policy': in_data.get('signed_url_policy', urls.SIGNED_URL), 'signed_url_duration': in_data.get('signed_url_duration', urls.DEFAULT_SIGNED_URL_DURATION) } class Meta: """Allow unknown fields to exclude from payload before processing.""" unknown = EXCLUDE class GetAssetByIdAndTypeSchema(Schema): """Get Asset validation schema.""" @pre_load def _normalize_asset_type(self, in_data, **kwargs): out_data = in_data.copy() out_data['asset_type'] = in_data.getlist('asset_type') return out_data object_id = fields.Integer(required=True) object_type = fields.String(required=True, validate=validate.OneOf( (asset_upload.OBJECT_TYPE_PODCAST, asset_upload.OBJECT_TYPE_EPISODE))) asset_type = fields.List(fields.String(required=True, validate=validate.OneOf( (asset_types.TYPE_FILE_TIF, asset_types.TYPE_FILE_JPG, asset_types.TYPE_FILE_WAV)))) @validates_schema def validate_asset_type(self, data, **kwargs): """Validate asset_type field.""" if data.get('object_type') == asset_upload.OBJECT_TYPE_PODCAST: if data.get('asset_type') != [asset_types.TYPE_FILE_TIF, asset_types.TYPE_FILE_JPG]: raise ValidationError( 'Invalid for object_type: podcast. It must be [TIF, JPG]', 'asset_type') else: if data.get('asset_type') != [asset_types.TYPE_FILE_WAV]: raise ValidationError('Invalid for object_type: episode. It must be [WAV]', 'asset_type') class Meta: """Allow unknown fields to exclude from payload before processing.""" unknown = EXCLUDE class AssetUploadPayloadSchema(Schema): """Asset upload validation schema.""" object_id = fields.String(required=True, allow_none=True) object_type = fields.String(required=True) filename = fields.String(required=True) original_filename = fields.String(required=True) asset_type = fields.String(required=True) class Meta: """Allow unknown fields to exclude from payload before processing.""" unknown = EXCLUDE class AssetDeletePayloadSchema(Schema): """Asset delete validation schema.""" object_id = fields.String(required=True) object_type = fields.String(required=True) asset_type = fields.String(required=True, validate=validate.OneOf(('artwork', 'audio'))) class Meta: """Allow unknown fields to exclude from payload before processing.""" unknown = EXCLUDE class FinalAssetSchema(Schema): """Final asset validation schema.""" key = fields.String(required=True) container = fields.String(required=False) duration = fields.Int(required=False) asset_type = fields.String(required=False, validate=validate.OneOf(asset_types.ASSET_TYPES)) asset_subtype = fields.String(required=False, allow_none=True, validate=validate.OneOf(asset_types.ASSET_SUBTYPES)) class PostAssetFinalSchema(Schema): """Post asset final validation schema.""" filename = fields.String(required=True) status = fields.String(required=True, validate=validate.OneOf(asset_status.PROCESSING_VALID_STATUSES)) errors = fields.Dict(required=True, allow_none=True) timestamp = fields.String(required=True) final_assets = fields.List(fields.Nested(FinalAssetSchema()), required=True) class Meta: """Allow unknown fields to exclude from payload before processing.""" unknown = EXCLUDE class PostAssetGeneralStatusSchema(Schema): """Post asset general status validation schema.""" filename = fields.String(required=True) status = fields.String(required=True, validate=validate.OneOf(asset_status.PROCESSING_VALID_STATUSES)) errors = fields.Dict(required=False, allow_none=True) timestamp = fields.String(required=True) class Meta: """Allow unknown fields to exclude from payload before processing.""" unknown = EXCLUDE class CommitAssetSchema(Schema): """Commit asset validation schema.""" object_id = fields.String(required=True) class Meta: """Allow unknown fields to exclude from payload before processing.""" unknown = EXCLUDE class GetAssetsStatusSchema(Schema): """Get status validation schema.""" signed_url_policy = fields.String( required=False, validate=validate.OneOf(urls.URL_POLICIES), default=urls.SIGNED_URL) signed_url_duration = fields.Int(required=False, default=urls.DEFAULT_SIGNED_URL_DURATION) class Meta: """Allow unknown fields to exclude from payload before processing.""" unknown = EXCLUDE class EpisodesAudioAssetsSchema(Schema): """Episodes Audio Assets validation schema.""" original_episode_id = fields.Int(required=True) episode_id = fields.Int(required=True) class ReplicateEpisodesAudioAssetsSchema(Schema): """Replicate Episodes Audio Assets validation schema.""" objects = fields.List(fields.Nested(EpisodesAudioAssetsSchema()), required=True, validate=validate.Length(min=1)) class Meta: """Allow unknown fields to exclude from payload before processing.""" unknown = EXCLUDE class PodcastArtworkAssetSchema(Schema): """Podcast artwork asset validation schema.""" original_podcast_id = fields.Int(required=True) podcast_id = fields.Int(required=True)