def verify_upload_person_task(data): """ Verify that uploaded data is correct. Show errors by populating ``errors`` dictionary item. This function changes ``data`` in place. """ errors_occur = False for item in data: errors = [] info = [] event = item.get('event', None) existing_event = None if event: try: existing_event = Event.objects.get(slug=event) except Event.DoesNotExist: errors.append('Event with slug {0} does not exist.' .format(event)) role = item.get('role', None) existing_role = None if role: try: existing_role = Role.objects.get(name=role) except Role.DoesNotExist: errors.append('Role with name {0} does not exist.' .format(role)) except Role.MultipleObjectsReturned: errors.append('More than one role named {0} exists.' .format(role)) # check if the user exists, and if so: check if existing user's # personal and family names are the same as uploaded email = item.get('email', None) personal = item.get('personal', None) family = item.get('family', None) person_id = item.get('existing_person_id', None) person = None if person_id: try: person = Person.objects.get(id=int(person_id)) except (ValueError, TypeError, Person.DoesNotExist): person = None info.append('Could not match selected person. New record will ' 'be created.') else: info.append('Existing record for person will be used.') if not email and not person: info.append('It\'s highly recommended to add an email address.') if person: # force details from existing record item['personal'] = personal = person.personal item['family'] = family = person.family item['email'] = email = person.email item['username'] = person.username item['person_exists'] = True else: # force a newly created username if not item.get('username'): item['username'] = create_username(personal, family) item['person_exists'] = False info.append('Person and task will be created.') # let's check if there's someone else named this way similar_persons = Person.objects.filter( Q(personal=personal, family=family) | Q(email=email) & ~Q(email='') & Q(email__isnull=False) ) # need to cast to list, otherwise it won't JSON-ify item['similar_persons'] = list(similar_persons.values( 'id', 'personal', 'middle', 'family', 'email', 'username', )) if existing_event and person and existing_role: # person, their role and a corresponding event exist, so # let's check if the task exists try: Task.objects.get(event=existing_event, person=person, role=existing_role) except Task.DoesNotExist: info.append('Task will be created.') else: info.append('Task already exists.') # let's check what Person model validators want to say try: p = Person(personal=personal, family=family, email=email, username=item['username']) p.clean_fields(exclude=['password']) except ValidationError as e: for k, v in e.message_dict.items(): errors.append('{}: {}'.format(k, v)) if not role: errors.append('Must have a role.') if not event: errors.append('Must have an event.') if errors: errors_occur = True item['errors'] = errors if info: item['info'] = info return errors_occur
def verify_upload_person_task(data, match=False): """ Verify that uploaded data is correct. Show errors by populating `errors` dictionary item. This function changes `data` in place. If `match` provided, it will try to match with first similar person. """ errors_occur = False for item in data: errors = [] info = [] event = item.get("event", None) existing_event = None if event: try: existing_event = Event.objects.get(slug=event) except Event.DoesNotExist: errors.append( 'Event with slug "{0}" does not exist.'.format(event)) except Event.MultipleObjectsReturned: errors.append( 'More than one event named "{0}" exists.'.format(event)) role = item.get("role", None) existing_role = None if role: try: existing_role = Role.objects.get(name=role) except Role.DoesNotExist: errors.append( 'Role with name "{0}" does not exist.'.format(role)) except Role.MultipleObjectsReturned: errors.append( 'More than one role named "{0}" exists.'.format(role)) # check if the user exists, and if so: check if existing user's # personal and family names are the same as uploaded email = item.get("email", "") personal = item.get("personal", "") family = item.get("family", "") person_id = item.get("existing_person_id", None) person = None # try to match with first similar person if match is True: try: person = Person.objects.get(email=email) except (Person.DoesNotExist, Person.MultipleObjectsReturned): person = None else: info.append("Existing record for person will be used.") person_id = person.pk elif person_id: try: person = Person.objects.get(id=int(person_id)) except (ValueError, TypeError, Person.DoesNotExist): person = None info.append("Could not match selected person. New record will " "be created.") else: info.append("Existing record for person will be used.") elif not person_id: try: Person.objects.get(email=email) except (Person.DoesNotExist, Person.MultipleObjectsReturned): pass else: errors.append("Person with this email address already exists.") try: if item.get("username"): Person.objects.get(username=item.get("username")) except Person.DoesNotExist: pass else: errors.append("Person with this username already exists.") if not email and not person: info.append("It's highly recommended to add an email address.") if person: # force details from existing record item["personal"] = personal = person.personal item["family"] = family = person.family item["email"] = email = person.email item["username"] = person.username item["existing_person_id"] = person_id item["person_exists"] = True else: # force a newly created username if not item.get("username"): item["username"] = create_username(personal, family) item["person_exists"] = False info.append("Person and task will be created.") # let's check if there's someone else named this way similar_persons = Person.objects.filter( Q(personal=personal, family=family) | Q(email=email) & ~Q(email="") & Q(email__isnull=False)) # need to cast to list, otherwise it won't JSON-ify item["similar_persons"] = list( zip( similar_persons.values_list("id", flat=True), map(lambda x: str(x), similar_persons), )) if existing_event and person and existing_role: # person, their role and a corresponding event exist, so # let's check if the task exists try: Task.objects.get(event=existing_event, person=person, role=existing_role) except Task.DoesNotExist: info.append("Task will be created.") else: info.append("Task already exists.") # let's check what Person model validators want to say try: p = Person(personal=personal, family=family, email=email, username=item["username"]) p.clean_fields(exclude=["password"]) except ValidationError as e: for k, v in e.message_dict.items(): errors.append("{}: {}".format(k, v)) if not role: errors.append("Must have a role.") if not event: errors.append("Must have an event.") item["errors"] = errors if errors: errors_occur = True item["info"] = info return errors_occur
def verify_upload_person_task(data): """ Verify that uploaded data is correct. Show errors by populating ``errors`` dictionary item. This function changes ``data`` in place. """ errors_occur = False for item in data: errors = [] info = [] event = item.get('event', None) existing_event = None if event: try: existing_event = Event.objects.get(slug=event) except Event.DoesNotExist: errors.append('Event with slug {0} does not exist.' .format(event)) role = item.get('role', None) existing_role = None if role: try: existing_role = Role.objects.get(name=role) except Role.DoesNotExist: errors.append('Role with name {0} does not exist.' .format(role)) except Role.MultipleObjectsReturned: errors.append('More than one role named {0} exists.' .format(role)) # check if the user exists, and if so: check if existing user's # personal and family names are the same as uploaded email = item.get('email', None) personal = item.get('personal', None) family = item.get('family', None) person = None if email: try: # check if first and last name matches person in the database person = Person.objects.get(email__iexact=email) for which, actual, uploaded in ( ('personal', person.personal, personal), ('family', person.family, family) ): if (actual == uploaded) or (not actual and not uploaded): pass else: errors.append('{0} mismatch: database "{1}" ' 'vs uploaded "{2}".' .format(which, actual, uploaded)) except Person.DoesNotExist: # in this case we need to add a new person pass else: if existing_event and person and existing_role: # person, their role and a corresponding event exist, so # let's check if the task exists try: Task.objects.get(event=existing_event, person=person, role=existing_role) except Task.DoesNotExist: info.append('Task will be created.') else: info.append('Task already exists.') else: info.append('It\'s highly recommended to add an email address.') if person: # force username from existing record item['username'] = person.username item['person_exists'] = True else: # force a newly created username if not item.get('username'): item['username'] = create_username(personal, family) item['person_exists'] = False info.append('Person and task will be created.') try: # let's check if there's someone else named this way similar_person = Person.objects.get(personal=personal, family=family) except Person.DoesNotExist: pass except Person.MultipleObjectsReturned: persons = [ str(person) for person in Person.objects.filter(personal=personal, family=family) ] info.append('There\'s a couple of matching persons in the ' 'database: {}. ' 'Use email to merge.'.format(', '.join(persons))) else: info.append('There\'s a matching person in the database: {}. ' 'Use their email to merge.'.format(similar_person)) # let's check what Person model validators want to say try: p = Person(personal=personal, family=family, email=email, username=item['username']) p.clean_fields(exclude=['password']) except ValidationError as e: for k, v in e.message_dict.items(): errors.append('{}: {}'.format(k, v)) if not role: errors.append('Must have a role.') if not event: errors.append('Must have an event.') if errors: errors_occur = True item['errors'] = errors if info: item['info'] = info return errors_occur