"""Validation logic for Performance rights """ import json from voluptuous import Any from voluptuous import MultipleInvalid from voluptuous import Schema from bulkperformancerights.logic import user from bulkperformancerights.models import country def validate_lines(lines, user_type, user_id): """Validate a set of lines for a user Args: lines (iterable): iterable list of lines user_type (str): type of user user_id (str): id of user Return: (tuple): list of valid rows, list of invalid rows """ invalid_rows = [] valid_rows = [] user_owned_tracks = user.tracks_owned(user_type, user_id) valid_countries = country.get_all_valid_countries() for line in lines: line_dict = json.loads(line.decode('utf-8')) validation_res = validate_line(user_owned_tracks, valid_countries, user_type, user_id, line_dict) invalid_columns = validation_res.get('invalid_columns') if len(invalid_columns) > 0: # format the status message according to our template if invalid_columns.get('Orchard Track Unique ID'): line_dict['Status'] = 'Invalid track - Does not exist' else: line_dict['Status'] = 'Invalid Entry - {}'.format( ','.join(list(invalid_columns.keys()))) invalid_rows.append(json.dumps(line_dict)) else: # no errors? append to list for update valid_rows.append(line_dict) return valid_rows, invalid_rows def validate_line( user_owned_tracks, valid_countries, user_type, user_id, line_dict): """Validate a single json json_line A 'line' is deemed valid if at least one of the required fields on the track is valid and the user owns that track country of recording(required): list of countries from models.country master rights ownership(required): Y/N nationality of 1st Producer(required): same as country of recording Args: user_owned_tracks (list): list of tracks the user owns valid_countries (list): list of valid countries user_type (str): type of user user_id (str): id of user line_dict (dict): dict representing a single row of data to validate Return: (dict): Example: { filename: 'foo.xlsx', row: 1, invalid_columns: { 'Master Rights': 'Yep' } } """ invalid_columns = {} track_id = line_dict.get('Orchard Track Unique ID') if track_id is None: invalid_columns['Orchard Track Unique ID'] = track_id return { 'filename': line_dict.get('filename'), 'row': line_dict.get('row'), 'invalid_columns': invalid_columns} # If a track trying to be updated is not owned by the user, fail hard unique_track_id = int(track_id) if unique_track_id not in user_owned_tracks: invalid_columns['Orchard Track Unique ID'] = unique_track_id return {'filename': line_dict.get('filename'), 'row': line_dict.get('row'), 'invalid_columns': invalid_columns} master_rights_schema = Schema(Any('Yes', 'No')) producer_nationality_schema = Schema(Any(*valid_countries)) country_of_origin_schema = Schema(Any(*valid_countries)) checkers = {'Master Rights': master_rights_schema, 'Nationality of 1st Producer': producer_nationality_schema, 'Country of Recording': country_of_origin_schema} for column in checkers.keys(): try: column_value = line_dict.get(column) checkers[column](column_value) except MultipleInvalid: if column_value is not None: invalid_columns[column] = column_value return {'filename': line_dict.get('filename'), 'row': line_dict.get('row'), 'invalid_columns': invalid_columns}