77from collections import defaultdict
88
99from django .conf import settings
10- from django .contrib .auth .models import User
1110
1211import debug # pyflakes:ignore
1312
1413from ietf .stats .models import AffiliationAlias , AffiliationIgnoredEnding , CountryAlias , MeetingRegistration
1514from ietf .name .models import CountryName
16- from ietf .person .models import Person , Email , Alias
17- from ietf .person .name import unidecode_name
15+ from ietf .person .models import Person , Email
1816from ietf .utils .log import log
1917
18+ import logging
19+ logger = logging .getLogger ('django' )
20+
2021
2122def compile_affiliation_ending_stripping_regexp ():
2223 parts = []
@@ -250,7 +251,7 @@ def get_meeting_registration_data(meeting):
250251 raise RuntimeError ("Could not decode response from registrations API: '%s...'" % (response .content [:64 ], ))
251252
252253 records = MeetingRegistration .objects .filter (meeting_id = meeting .pk ).select_related ('person' )
253- meeting_registrations = {r .email :r for r in records }
254+ meeting_registrations = {( r .email , r . reg_type ) :r for r in records }
254255 for registration in decoded :
255256 person = None
256257 # capture the stripped registration values for later use
@@ -259,11 +260,15 @@ def get_meeting_registration_data(meeting):
259260 affiliation = registration ['Company' ].strip ()
260261 country_code = registration ['Country' ].strip ()
261262 address = registration ['Email' ].strip ()
262- if address in meeting_registrations :
263- object = meeting_registrations [address ]
263+ reg_type = registration ['RegType' ].strip ()
264+ if (address , reg_type ) in meeting_registrations :
265+ object = meeting_registrations .pop ((address , reg_type ))
264266 created = False
265267 else :
266- object = MeetingRegistration .objects .create (meeting_id = meeting .pk , email = address )
268+ object = MeetingRegistration .objects .create (
269+ meeting_id = meeting .pk ,
270+ email = address ,
271+ reg_type = reg_type )
267272 created = True
268273
269274 if (object .first_name != first_name [:200 ] or
@@ -286,75 +291,31 @@ def get_meeting_registration_data(meeting):
286291 person = emails .first ().person
287292 # Create a new Person object
288293 else :
289- try :
290- # Normalize all-caps or all-lower entries. Don't touch
291- # others, there might be names properly spelled with
292- # internal uppercase letters.
293- if ( ( first_name == first_name .upper () or first_name == first_name .lower () )
294- and ( last_name == last_name .upper () or last_name == last_name .lower () ) ):
295- first_name = first_name .capitalize ()
296- last_name = last_name .capitalize ()
297- regname = "%s %s" % (first_name , last_name )
298- # if there are any unicode characters decode the string to ascii
299- ascii_name = unidecode_name (regname )
300-
301- # Create a new user object if it does not exist already
302- # if the user already exists do not try to create a new one
303- users = User .objects .filter (username = address )
304- if users .exists ():
305- user = users .first ()
306- else :
307- # Create a new user.
308- user = User .objects .create (
309- first_name = first_name [:30 ],
310- last_name = last_name [:30 ],
311- username = address ,
312- email = address ,
313- )
314-
315- try :
316- person = user .person
317- except Person .DoesNotExist :
318- aliases = Alias .objects .filter (name = regname )
319- if aliases .exists ():
320- person = aliases .first ().person
321- else :
322- # Create the new Person object.
323- person = Person .objects .create (
324- name = regname ,
325- ascii = ascii_name ,
326- user = user ,
327- )
328-
329- # Create an associated Email address for this Person
330- try :
331- email = Email .objects .get (person = person , address = address [:64 ])
332- except Email .DoesNotExist :
333- email = Email .objects .create (person = person , address = address [:64 ], origin = 'registration: ietf-%s' % meeting .number )
334-
335- # If this is the only email address, set primary to true.
336- # If the person already existed (found through Alias) and
337- # had email addresses, we don't do this.
338- if Email .objects .filter (person = person ).count () == 1 :
339- email .primary = True
340- email .save ()
341- except :
342- debug .show ('first_name' )
343- debug .show ('last_name' )
344- debug .show ('regname' )
345- debug .show ('user' )
346- debug .show ('aliases' )
347- raise
294+ logger .error ("No Person record for registration. email={}" .format (address ))
348295 # update the person object to an actual value
349296 object .person = person
350297 object .save ()
351298
352299 if created :
353300 num_created += 1
354301 num_processed += 1
302+
303+ # handle deleted registrations, if count is reasonable
304+ # any registrations left in meeting_registrations no longer exist in reg
305+ # so must have been deleted
306+ if 0 < len (meeting_registrations ) < 5 :
307+ for r in meeting_registrations :
308+ try :
309+ MeetingRegistration .objects .get (meeting = meeting ,email = r [0 ],reg_type = r [1 ]).delete ()
310+ logger .info ('Removing deleted registration. email={}, reg_type={}' .format (r [0 ], r [1 ]))
311+ except MeetingRegistration .DoesNotExist :
312+ pass
355313 else :
356314 raise RuntimeError ("Bad response from registrations API: %s, '%s'" % (response .status_code , response .content ))
357- num_total = MeetingRegistration .objects .filter (meeting_id = meeting .pk ).count ()
315+ num_total = MeetingRegistration .objects .filter (
316+ meeting_id = meeting .pk ,
317+ attended = True ,
318+ reg_type__in = ['onsite' , 'remote' ]).count ()
358319 if meeting .attendees is None or num_total > meeting .attendees :
359320 meeting .attendees = num_total
360321 meeting .save ()
0 commit comments