Skip to content

Commit 7b1224e

Browse files
committed
Merged in ^/personal/sbirkholz/meeting_registration_more_fixes, which adds creation of missing person records when importing meeting registration data. Tweaked the resulting code some.
- Legacy-Id: 14092
2 parents 2928f0c + 8b5a639 commit 7b1224e

2 files changed

Lines changed: 111 additions & 10 deletions

File tree

ietf/stats/tests.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from requests import Response
66

77
from django.urls import reverse as urlreverse
8+
from django.contrib.auth.models import User
89

910
from ietf.utils.test_data import make_test_data, make_review_data
1011
from ietf.utils.test_utils import login_testing_unauthorized, TestCase, unicontent
@@ -13,11 +14,12 @@
1314
from ietf.submit.models import Submission
1415
from ietf.doc.models import Document, DocAlias, State, RelatedDocument, NewRevisionDocEvent
1516
from ietf.meeting.factories import MeetingFactory
16-
from ietf.person.models import Person
17+
from ietf.person.models import Person, Email
1718
from ietf.name.models import FormalLanguageName, DocRelationshipName, CountryName
1819
from ietf.stats.models import MeetingRegistration, CountryAlias
1920
from ietf.stats.utils import get_meeting_registration_data
2021

22+
2123
class StatisticsTests(TestCase):
2224
def test_stats_index(self):
2325
url = urlreverse(ietf.stats.views.stats_index)
@@ -200,3 +202,25 @@ def test_get_meeting_registration_data(self, mock_get):
200202
get_meeting_registration_data(meeting)
201203
query = MeetingRegistration.objects.filter(first_name='John',last_name='Smith',country_code='US')
202204
self.assertTrue(query.count(), 1)
205+
self.assertTrue(isinstance(query[0].person,Person))
206+
207+
@patch('requests.get')
208+
def test_get_meeting_registration_data_user_exists(self, mock_get):
209+
response = Response()
210+
response.status_code = 200
211+
response._content = '[{"LastName":"Smith","FirstName":"John","Company":"ABC","Country":"US","Email":"john.doe@example.us"}]'
212+
email = "john.doe@example.us"
213+
user = User.objects.create(username=email)
214+
user.save()
215+
216+
mock_get.return_value = response
217+
meeting = MeetingFactory(type_id='ietf', date=datetime.date(2016,7,14), number="96")
218+
get_meeting_registration_data(meeting)
219+
query = MeetingRegistration.objects.filter(first_name='John',last_name='Smith',country_code='US')
220+
emails = Email.objects.filter(address=email)
221+
self.assertTrue(query.count(), 1)
222+
self.assertTrue(isinstance(query[0].person, Person))
223+
self.assertTrue(len(emails)>=1)
224+
self.assertEqual(query[0].person, emails[0].person)
225+
226+

ietf/stats/utils.py

Lines changed: 86 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66

77
from ietf.stats.models import AffiliationAlias, AffiliationIgnoredEnding, CountryAlias, MeetingRegistration
88
from ietf.name.models import CountryName
9+
from ietf.person.models import Person, Email, Alias
10+
from django.contrib.auth.models import User
11+
from unidecode import unidecode
12+
913

1014
def compile_affiliation_ending_stripping_regexp():
1115
parts = []
@@ -226,23 +230,96 @@ def get_meeting_registration_data(meeting):
226230
else:
227231
raise RuntimeError("Could not decode response from registrations API: '%s...'" % (response.content[:64], ))
228232

233+
234+
# for each user identified in the Registration system
235+
# Create a DataTracker MeetingRegistration object
229236
for registration in decoded:
237+
person = None
238+
# capture the stripped registration values for later use
239+
first_name = registration['FirstName'].strip()
240+
last_name = registration['LastName'].strip()
241+
affiliation = registration['Company'].strip()
242+
country_code = registration['Country'].strip()
243+
address = registration['Email'].strip()
230244
object, created = MeetingRegistration.objects.get_or_create(
231245
meeting_id=meeting.pk,
232-
first_name=registration['FirstName'].strip(),
233-
last_name=registration['LastName'].strip(),
234-
affiliation=registration['Company'].strip(),
235-
country_code=registration['Country'].strip(),
236-
email=registration['Email'].strip(),
246+
first_name=first_name,
247+
last_name=last_name,
248+
affiliation=affiliation,
249+
country_code=country_code,
250+
email=address,
237251
)
252+
253+
# Add a Person object to MeetingRegistration object
254+
# if valid email is available
255+
if object and not object.person and address:
256+
# If the person already exists do not try to create a new one
257+
emails = Email.objects.filter(address=address)
258+
# there can only be on Email object with a unique email address (primary key)
259+
if emails.exists():
260+
person = emails.first().person
261+
# Create a new Person object
262+
else:
263+
# Normalize all-caps or all-lower entries. Don't touch
264+
# others, there might be names properly spelled with
265+
# internal uppercase letters.
266+
if ( ( first_name == first_name.upper() or first_name == first_name.lower() )
267+
and ( last_name == last_name.upper() or last_name == last_name.lower() ) ):
268+
first_name = first_name.capitalize()
269+
last_name = last_name.capitalize()
270+
regname = "%s %s" % (first_name, last_name)
271+
# if there are any unicode characters decode the string to ascii
272+
ascii_name = unidecode(regname).strip()
273+
274+
# Create a new user object if it does not exist already
275+
# if the user already exists do not try to create a new one
276+
users = User.objects.filter(username=address)
277+
if users.exists():
278+
user = users.first()
279+
else:
280+
# Create a new user.
281+
user = User.objects.create(
282+
first_name=first_name,
283+
last_name=last_name,
284+
username=address,
285+
email=address,
286+
)
287+
user.save()
288+
289+
aliases = Alias.objects.filter(name=regname)
290+
if aliases.exists():
291+
person = aliases.first().person
292+
else:
293+
# Create the new Person object.
294+
person = Person.objects.create(
295+
name=regname,
296+
ascii=ascii_name,
297+
affiliation=affiliation,
298+
user=user,
299+
)
300+
person.save()
301+
302+
# Create an associated Email address for this Person
303+
email = Email.objects.create(
304+
person=person,
305+
address=address,
306+
)
307+
308+
# If this is the only email address, set primary to true.
309+
# If the person already existed (found through Alias) and
310+
# had email addresses, we don't do this.
311+
if Email.objects.filter(person=person).count() == 1:
312+
email.primary = True
313+
email.save()
314+
315+
# update the person object to an actual value
316+
object.person = person
317+
object.save()
318+
238319
if created:
239320
num_created += 1
240321
num_processed += 1
241322
else:
242323
raise RuntimeError("Bad response from registrations API: %s, '%s'" % (response.status_code, response.content))
243324
num_total = MeetingRegistration.objects.filter(meeting_id=meeting.pk).count()
244325
return num_created, num_processed, num_total
245-
246-
247-
248-

0 commit comments

Comments
 (0)