diff --git a/src/core/models/schedules.py b/src/core/models/schedules.py index 658c56ce1df319fa699e8fcad854cafbf7309513..85ff87e28236ce0e23633e3eb1bb42f49b1fb055 100644 --- a/src/core/models/schedules.py +++ b/src/core/models/schedules.py @@ -127,20 +127,21 @@ class ScheduleSource(models.Model): if not name: raise ValueError('You need to provide a name for the speaker.') - if mail_guid is None and addresses is None: - raise ValueError('You need to provide at least mail_guid or addresses (better: both).') - if mail_guid and not isinstance(mail_guid, UUID): mail_guid = UUID(mail_guid) - speaker_username = '_speaker_' + str(mail_guid or sha1('\n'.join(sorted(addresses)))) + if mail_guid: + speaker_username = '_speaker_' + str(mail_guid) + elif addresses: + speaker_username = '_speaker_' + sha1('\n'.join(sorted(addresses)).encode('utf-8')).hexdigest() + else: + speaker_username = '_speaker_' + sha1(name.encode('utf-8')).hexdigest() # try to find by the username if candidate := PlatformUser.objects.filter(username=speaker_username, user_type=PlatformUser.Type.SPEAKER).first(): return candidate, False - # basically, this is a hail-mary-type attempt: we try to find a PlatformUser who - # has a verified email matching the given mail_guid or any of the supplied addresses + # we try to find a PlatformUser who has a verified email matching the given mail_guid or any of the supplied addresses candidates = [] # type: List[PlatformUser] for cm in self.conference.users.select_related('user').filter(user__user_type__in=PlatformUser.PERSON_TYPES).iterator(): # type: ConferenceMember for addr in cm.user.get_verified_mail_addresses(): @@ -159,6 +160,11 @@ class ScheduleSource(models.Model): if len(candidates) > 1: raise ValueError('Multiple candidate speakers found: ' + '; '.join(x.pk for x in candidates)) + # hail mary attempt: see if we have an imported speaker with the same name + candidates = self.conference.users.select_related('user').filter(user__user_type=PlatformUser.Type.SPEAKER, user__display_name=name).all() + if len(candidates) == 1: + return candidates[0], False + # the expected case: nothing found, create a new one name_split = name.split(' ') user_kwargs = { @@ -260,7 +266,7 @@ class ScheduleSource(models.Model): hints['room_name'] = item.get('room') hints['speaker_lookup'] = from_dict_args.get('speaker_lookup') elif item_type == 'speaker': - hints['name'] = item.get('public_name') or item.get('name') + hints['name'] = item.get('full_public_name') or item.get('public_name') or item.get('name') hints['addresses'] = item.get('addresses') mapping, new_mapping = self.get_or_create_mapping( @@ -456,11 +462,13 @@ class ScheduleSource(models.Model): ``` """ + # for the source id use the provided id, uuid or guid field (in order) + speaker_id = speaker_info.get('id') or speaker_info.get('uuid') or speaker_info.get('guid') + # sanity check: verify that required attributes are present - if any(x not in speaker_info for x in ['id', 'public_name']): - raise ValueError('Missing required attribute in speaker_info.') + if not speaker_info: + raise ValueError('Missing required attribute in speaker_info: id/uuid/guid') - speaker_id = speaker_info.get('id') try: action = self._load_dataitem( activity=activity,