def _create_registrations(self, expected_stats): """ Create different numbers of registrations on each of the chosen registration dates so we can be sure that a count was assigned to the correct date. """ msg_type_str = self._msg_type_to_str(SMS.REGISTRATION) expected_stats['message_stats'][msg_type_str] = dict() # Accumulators for by-center and total number of registrations expected_stats['by_center'][self.rc_1.center_id]['registrations'] = 0 expected_stats['by_center'][self.rc_2.center_id]['registrations'] = 0 expected_stats['by_center'][self.rc_3.center_id]['registrations'] = 0 expected_stats['by_center'][self.rc_4.center_id]['registrations'] = 0 expected_stats['by_center'][self.copy_of_rc_1.center_id]['registrations'] = '' expected_stats['by_center'][self.rc_5.center_id]['registrations'] = 0 expected_stats['message_stats'][msg_type_str]['total'] = 0 for i, reg_date in enumerate(self.registration_dates): regs_on_date = i + 1 for j in range(regs_on_date): citizen = CitizenFactory() s = SMS(from_number='12345', to_number='12345', citizen=citizen, direction=INCOMING, message='my reg message', msg_type=SMS.REGISTRATION, message_code=MESSAGE_1, carrier=self.carrier_1, creation_date=reg_date) s.full_clean() s.save() r = Registration(citizen=citizen, registration_center=self.rc_1, archive_time=None, sms=s, creation_date=reg_date, modification_date=reg_date) r.full_clean() r.save() expected_stats['by_center'][self.rc_1.center_id]['registrations'] += 1 expected_stats['message_stats'][msg_type_str]['total'] += regs_on_date # Capture the count on "yesterday" (reported on SMS page) if self.yesterday_date == reg_date.date(): expected_stats['message_stats'][msg_type_str][self.yesterday_date_dm] = \ regs_on_date
def _create_sms_messages(self, expected_stats): """ Create SMS messages of a certain type at different times "yesterday". The times should have the same date in local TZ but different dates when the TZ is bungled somewhere. By making them "yesterday", the counts will show up in the SMS page in the yesterday column. """ msg_type = SMS.INVALID_CENTRE_CODE_LENGTH msg_type_str = self._msg_type_to_str(msg_type) expected_stats['message_stats'][msg_type_str] = dict() num_staff_messages = 8 for msg_hour in range(num_staff_messages): msg_time = self.yesterday_date_dt.replace(hour=msg_hour, minute=23) s = SMS(from_number=self.staff_phone_number, to_number='12345', citizen=self.citizen_1, direction=INCOMING, message='my message', msg_type=msg_type, message_code=MESSAGE_1, carrier=self.carrier_1, creation_date=msg_time) s.full_clean() s.save() expected_stats['message_stats'][msg_type_str][self.yesterday_date_dt.strftime('%d/%m')] = \ num_staff_messages expected_stats['message_stats'][msg_type_str][ 'total'] = num_staff_messages expected_stats['phone_history'][self.staff_phone_number] = { 'message_count': num_staff_messages, }
def _create_sms_messages(self, expected_stats): """ Create SMS messages of a certain type at different times "yesterday". The times should have the same date in local TZ but different dates when the TZ is bungled somewhere. By making them "yesterday", the counts will show up in the SMS page in the yesterday column. """ msg_type = SMS.INVALID_CENTRE_CODE_LENGTH msg_type_str = self._msg_type_to_str(msg_type) expected_stats['message_stats'][msg_type_str] = dict() num_staff_messages = 8 for msg_hour in range(num_staff_messages): msg_time = self.yesterday_date_dt.replace(hour=msg_hour, minute=23) s = SMS(from_number=self.staff_phone_number, to_number='12345', citizen=self.citizen_1, direction=INCOMING, message='my message', msg_type=msg_type, message_code=MESSAGE_1, carrier=self.carrier_1, creation_date=msg_time) s.full_clean() s.save() expected_stats['message_stats'][msg_type_str][self.yesterday_date_dt.strftime('%d/%m')] = \ num_staff_messages expected_stats['message_stats'][msg_type_str]['total'] = num_staff_messages expected_stats['phone_history'][self.staff_phone_number] = { 'message_count': num_staff_messages, }
def _create_registrations(self, expected_stats): """ Create different numbers of registrations on each of the chosen registration dates so we can be sure that a count was assigned to the correct date. """ msg_type_str = self._msg_type_to_str(SMS.REGISTRATION) expected_stats['message_stats'][msg_type_str] = dict() # Accumulators for by-center and total number of registrations expected_stats['by_center'][self.rc_1.center_id]['registrations'] = 0 expected_stats['by_center'][self.rc_2.center_id]['registrations'] = 0 expected_stats['by_center'][self.rc_3.center_id]['registrations'] = 0 expected_stats['by_center'][self.rc_4.center_id]['registrations'] = 0 expected_stats['by_center'][ self.copy_of_rc_1.center_id]['registrations'] = '' expected_stats['by_center'][self.rc_5.center_id]['registrations'] = 0 expected_stats['message_stats'][msg_type_str]['total'] = 0 for i, reg_date in enumerate(self.registration_dates): regs_on_date = i + 1 for j in range(regs_on_date): citizen = CitizenFactory() s = SMS(from_number='12345', to_number='12345', citizen=citizen, direction=INCOMING, message='my reg message', msg_type=SMS.REGISTRATION, message_code=MESSAGE_1, carrier=self.carrier_1, creation_date=reg_date) s.full_clean() s.save() r = Registration(citizen=citizen, registration_center=self.rc_1, archive_time=None, sms=s, creation_date=reg_date, modification_date=reg_date) r.full_clean() r.save() expected_stats['by_center'][ self.rc_1.center_id]['registrations'] += 1 expected_stats['message_stats'][msg_type_str][ 'total'] += regs_on_date # Capture the count on "yesterday" (reported on SMS page) if self.yesterday_date == reg_date.date(): expected_stats['message_stats'][msg_type_str][self.yesterday_date_dm] = \ regs_on_date
def create(center_without_office=False, num_copy_centers=DEFAULT_NUM_COPY_CENTERS, num_registrations=DEFAULT_NUM_REGISTRATIONS, num_registration_dates=DEFAULT_NUM_REGISTRATION_DATES, num_daily_reports=DEFAULT_NUM_DAILY_REPORTS, num_registration_centers=DEFAULT_NUM_REGISTRATION_CENTERS, num_subconstituencies=DEFAULT_NUM_SUBCONSTITUENCIES, use_existing_infra=False, num_inactive_centers_per_election=DEFAULT_NUM_INACTIVE_PER_ELECTION, num_no_reg_centers=DEFAULT_NUM_NO_REG_CENTERS, election_dates=()): assert settings.ENVIRONMENT not in ('production', 'testing') delete(delete_infra=not use_existing_infra) empty_report_store() # Remove any old data from Redis # Figure out ~10% of "normal" centers... fraction_of_normal_centers = \ max(1, int(0.1 * num_registration_centers)) if num_registration_centers else 0 # If numbers of some weird center types weren't specified, use a small # fraction of normal centers. if num_copy_centers == DEFAULT_NUM_COPY_CENTERS: num_copy_centers = fraction_of_normal_centers if num_no_reg_centers == DEFAULT_NUM_NO_REG_CENTERS: num_no_reg_centers = fraction_of_normal_centers carrier = BackendFactory() if election_dates: elections = [ ElectionFactory(polling_start_time=election_date.replace(hour=8), polling_end_time=election_date.replace(hour=20)) for election_date in election_dates ] else: election_date = PAST_DAY.replace(hour=8, microsecond=123456) election = ElectionFactory( polling_start_time=election_date, polling_end_time=election_date.replace(hour=20)) elections = (election, ) if not use_existing_infra: OfficeFactory() ConstituencyFactory(name_english='first') SubConstituencyFactory(name_english='Benghazi') offices = Office.objects.all() copy_centers = [] no_reg_centers = [] staff_phones = [] if use_existing_infra: # Pick centers that support registrations at random. centers = RegistrationCenter.objects.filter(reg_open=True)\ .exclude(center_type=RegistrationCenter.Types.COPY)\ .order_by('?')[:num_registration_centers] if num_copy_centers: # user wants some, but there might not be any copy_centers = RegistrationCenter.objects.\ filter(reg_open=True, center_type=RegistrationCenter.Types.COPY)\ .order_by('?')[:num_copy_centers] if num_no_reg_centers: # user wants some, but there might not be any no_reg_centers = RegistrationCenter.objects.\ filter(reg_open=False).order_by('?')[:num_no_reg_centers] # why like this? sliced queries and/or list all_kinds_of_centers = \ list(centers) + list(copy_centers) + list(no_reg_centers) else: subconstituencies = SubConstituency.objects.exclude( pk=SPLIT_CENTER_SUBCONSTITUENCY_ID) subconstituencies = subconstituencies[:num_subconstituencies] centers = [] for i in range(num_registration_centers): constituency = Constituency.objects.filter(name_english='first')[0] subconstituency = random.choice(subconstituencies) rc = RegistrationCenter(name='polling-center-%d' % i, center_id=CENTER_ID_MIN_INT_VALUE + i, constituency=constituency, subconstituency=subconstituency, office=random.choice(offices)) rc.full_clean() rc.save() centers.append(rc) for i in range(num_copy_centers): original = random.choice(centers) # XXX This doesn't handle accidentally making too many copies of the same # center, so make sure --num-centers is "big enough" w.r.t. --num-copy-centers. new_center_id = CENTER_ID_MIN_INT_VALUE + num_registration_centers + i copy = RegistrationCenter( name='Copy of %s' % original.name, center_id=new_center_id, constituency=original.constituency, subconstituency=original.subconstituency, office=original.office, center_type=RegistrationCenter.Types.COPY, copy_of=original) copy.full_clean() copy.save() copy_centers.append(copy) for i in range(num_no_reg_centers): constituency = Constituency.objects.filter(name_english='first')[0] subconstituency = random.choice(subconstituencies) center_id = CENTER_ID_MIN_INT_VALUE + num_registration_centers + num_copy_centers + i rc = RegistrationCenter(name='no-reg-polling-center-%d' % i, center_id=center_id, constituency=constituency, subconstituency=subconstituency, office=random.choice(offices), reg_open=False) rc.full_clean() rc.save() all_kinds_of_centers = centers + copy_centers + no_reg_centers if center_without_office: try: # by not specifying office and other infra, it will be "standalone" rc = RegistrationCenter(name='dummy-registration-center', center_id=UNUSED_CENTER_ID) rc.full_clean() rc.save() except ValidationError: pass # assume that it already exists for election in elections: num_daily_reports_on_election_day = int(round(0.9 * num_daily_reports)) centers_reported = set() for i in range(num_daily_reports_on_election_day): staff_phone_number = STAFF_PHONE_NUMBER_PATTERN % i from_center = random.choice(all_kinds_of_centers) ensure_staff_phone_exists( staff_phone_number, from_center, staff_phones, election.work_start_time + datetime.timedelta(minutes=5)) # split votes between two options number_of_votes = (random.randint(1, 100), random.randint(1, 100)) random_period_number = random.randint(FIRST_PERIOD_NUMBER, LAST_PERIOD_NUMBER) pr = PollingReport(election=election, phone_number=staff_phone_number, registration_center=from_center, period_number=random_period_number, num_voters=sum(number_of_votes), creation_date=election.polling_start_time) pr.full_clean() pr.save() s = SMS(from_number=staff_phone_number, to_number=POLLING_REPORT_PHONE_NUMBER, direction=INCOMING, message='my message', msg_type=SMS.POLLING_REPORT, message_code=MESSAGE_1, carrier=carrier, creation_date=election.polling_start_time) s.full_clean() s.save() if from_center in centers_reported: continue # can't send but one PreliminaryVoteCount from a center # send a corresponding vote count for option, votes_for_option in enumerate(number_of_votes, start=1): pvc = PreliminaryVoteCount( election=election, phone_number=staff_phone_number, registration_center=from_center, option=option, num_votes=votes_for_option, creation_date=election.polling_start_time) pvc.full_clean() pvc.save() s = SMS( from_number=staff_phone_number, to_number=PRELIMINARY_VOTE_COUNT_PHONE_NUMBER, # XXX no specific message type for PreliminaryVoteCount direction=INCOMING, message='my message', msg_type=SMS.POLLING_REPORT, message_code=MESSAGE_1, carrier=carrier, creation_date=election.polling_start_time) s.full_clean() s.save() centers_reported.add(from_center) # some daily reports on the day after for i in range(num_daily_reports - num_daily_reports_on_election_day): staff_phone_number = STAFF_PHONE_NUMBER_PATTERN % i rc = random.choice(all_kinds_of_centers) ensure_staff_phone_exists( staff_phone_number, rc, staff_phones, election.work_start_time + datetime.timedelta(minutes=5)) report_creation_date = election.polling_start_time + datetime.timedelta( days=1) pr = PollingReport( election=election, phone_number=staff_phone_number, registration_center=rc, period_number= LAST_PERIOD_NUMBER, # day after counts as last period num_voters=random.randint(1, 50), creation_date=report_creation_date) pr.full_clean() pr.save() s = SMS(from_number=staff_phone_number, to_number=POLLING_REPORT_PHONE_NUMBER, direction=INCOMING, message='my message', msg_type=SMS.POLLING_REPORT, message_code=MESSAGE_1, carrier=carrier, creation_date=election.polling_start_time) s.full_clean() s.save() # Tag some centers as inactive for the election. We may or may not pick some that # sent messages as being inactive. num_inactive_centers_per_election = \ min(num_inactive_centers_per_election, len(all_kinds_of_centers)) if num_inactive_centers_per_election: reordered = all_kinds_of_centers random.shuffle(reordered) for i in range(num_inactive_centers_per_election): inactive_on_election = CenterClosedForElection( registration_center=reordered[i], election=election) inactive_on_election.full_clean() inactive_on_election.save() tz = timezone(settings.TIME_ZONE) # construct a datetime that will change based on timezone discrepancies # 0-2am in Libya has a different date than the same time in UDT or EDT today_fragile = now().astimezone(tz).replace(hour=0, minute=59) # tz.normalize fixes up the date arithmetic when crossing DST boundaries creation_dates = \ [tz.normalize((today_fragile - datetime.timedelta(days=DAYS_BETWEEN_REGISTRATIONS * i)).astimezone(tz)) for i in range(num_registration_dates)] citizens = [] for i in range(num_registrations): # about 60% of registrations are for males, just as with actual data gender = MALE if random.randint(1, 100) <= 60 else FEMALE nat_id = '%d%011d' % (gender, i) creation_date = random.choice(creation_dates) modification_date = creation_date # Select voter ages from 18 years on up. voter_age = random.randint(18, 99) # If they were a certain age at any time yesterday, they are certainly that age at any time # today. yesterday = datetime.datetime.now().replace( tzinfo=tz) - datetime.timedelta(days=1) birth_date = datetime.date(yesterday.year - voter_age, yesterday.month, yesterday.day) civil_registry_id = random.randint(1, 99999999) citizen = CitizenFactory(civil_registry_id=civil_registry_id, national_id=nat_id, gender=gender, birth_date=birth_date) citizens.append(citizen) s = SMS(from_number=VOTER_PHONE_NUMBER_PATTERN % i, to_number=REGISTRATION_PHONE_NUMBER, citizen=citizen, direction=INCOMING, message='my reg message', msg_type=SMS.REGISTRATION, message_code=MESSAGE_1, carrier=carrier, creation_date=creation_date) s.full_clean() s.save() rc = random.choice(centers) confirmed = random.randint(1, 100) <= 80 # most are confirmed if confirmed: archive_time = None else: archive_time = random.choice(creation_dates) r = Registration(citizen=citizen, registration_center=rc, sms=s, archive_time=archive_time, creation_date=creation_date, modification_date=modification_date) r.full_clean() r.save() if num_registrations: # if any data being generated # generate a variety of sms messages for i in range(NUM_RANDOM_SMS_MESSAGES): sms_type = random.choice(SMS.MESSAGE_TYPES)[0] staff_phone = random.choice(staff_phones) s = SMS(from_number=staff_phone.phone_number, to_number=RANDOM_MESSAGE_PHONE_NUMBER, citizen=random.choice(citizens), direction=INCOMING, message='my long random message', msg_type=sms_type, message_code=MESSAGE_1, carrier=carrier, creation_date=random.choice(creation_dates)) s.full_clean() s.save() for election in elections: for rc in centers: i = random.randint(8888, 9999) staff_phone_number = STAFF_PHONE_NUMBER_PATTERN % i ensure_staff_phone_exists( staff_phone_number, rc, staff_phones, election.work_start_time + datetime.timedelta(minutes=5)) center_open = CenterOpen( election=election, phone_number=staff_phone_number, registration_center=rc, creation_date=election.polling_start_time.replace( hour=random.randint(0, 10), minute=23)) center_open.full_clean() center_open.save() s = SMS(from_number=staff_phone_number, to_number=ACTIVATE_PHONE_NUMBER, direction=INCOMING, message='my message', msg_type=SMS.ACTIVATE, message_code=MESSAGE_1, carrier=carrier, creation_date=election.polling_start_time) s.full_clean() s.save()
def create(center_without_office=False, num_copy_centers=DEFAULT_NUM_COPY_CENTERS, num_registrations=DEFAULT_NUM_REGISTRATIONS, num_registration_dates=DEFAULT_NUM_REGISTRATION_DATES, num_daily_reports=DEFAULT_NUM_DAILY_REPORTS, num_registration_centers=DEFAULT_NUM_REGISTRATION_CENTERS, num_subconstituencies=DEFAULT_NUM_SUBCONSTITUENCIES, use_existing_infra=False, num_inactive_centers_per_election=DEFAULT_NUM_INACTIVE_PER_ELECTION, num_no_reg_centers=DEFAULT_NUM_NO_REG_CENTERS, election_dates=()): assert settings.ENVIRONMENT not in ('production', 'testing') delete(delete_infra=not use_existing_infra) empty_report_store() # Remove any old data from Redis # Figure out ~10% of "normal" centers... fraction_of_normal_centers = \ max(1, int(0.1 * num_registration_centers)) if num_registration_centers else 0 # If numbers of some weird center types weren't specified, use a small # fraction of normal centers. if num_copy_centers == DEFAULT_NUM_COPY_CENTERS: num_copy_centers = fraction_of_normal_centers if num_no_reg_centers == DEFAULT_NUM_NO_REG_CENTERS: num_no_reg_centers = fraction_of_normal_centers carrier = BackendFactory() if election_dates: elections = [ ElectionFactory( polling_start_time=election_date.replace(hour=8), polling_end_time=election_date.replace(hour=20) ) for election_date in election_dates ] else: election_date = PAST_DAY.replace(hour=8, microsecond=123456) election = ElectionFactory( polling_start_time=election_date, polling_end_time=election_date.replace(hour=20) ) elections = (election,) if not use_existing_infra: OfficeFactory() ConstituencyFactory(name_english='first') SubConstituencyFactory(name_english='Benghazi') offices = Office.objects.all() copy_centers = [] no_reg_centers = [] staff_phones = [] if use_existing_infra: # Pick centers that support registrations at random. centers = RegistrationCenter.objects.filter(reg_open=True)\ .exclude(center_type=RegistrationCenter.Types.COPY)\ .order_by('?')[:num_registration_centers] if num_copy_centers: # user wants some, but there might not be any copy_centers = RegistrationCenter.objects.\ filter(reg_open=True, center_type=RegistrationCenter.Types.COPY)\ .order_by('?')[:num_copy_centers] if num_no_reg_centers: # user wants some, but there might not be any no_reg_centers = RegistrationCenter.objects.\ filter(reg_open=False).order_by('?')[:num_no_reg_centers] # why like this? sliced queries and/or list all_kinds_of_centers = \ list(centers) + list(copy_centers) + list(no_reg_centers) else: subconstituencies = SubConstituency.objects.exclude(pk=SPLIT_CENTER_SUBCONSTITUENCY_ID) subconstituencies = subconstituencies[:num_subconstituencies] centers = [] for i in range(num_registration_centers): constituency = Constituency.objects.filter(name_english='first')[0] subconstituency = random.choice(subconstituencies) rc = RegistrationCenter(name='polling-center-%d' % i, center_id=CENTER_ID_MIN_INT_VALUE+i, constituency=constituency, subconstituency=subconstituency, office=random.choice(offices)) rc.full_clean() rc.save() centers.append(rc) for i in range(num_copy_centers): original = random.choice(centers) # XXX This doesn't handle accidentally making too many copies of the same # center, so make sure --num-centers is "big enough" w.r.t. --num-copy-centers. new_center_id = CENTER_ID_MIN_INT_VALUE + num_registration_centers + i copy = RegistrationCenter(name='Copy of %s' % original.name, center_id=new_center_id, constituency=original.constituency, subconstituency=original.subconstituency, office=original.office, center_type=RegistrationCenter.Types.COPY, copy_of=original) copy.full_clean() copy.save() copy_centers.append(copy) for i in range(num_no_reg_centers): constituency = Constituency.objects.filter(name_english='first')[0] subconstituency = random.choice(subconstituencies) center_id = CENTER_ID_MIN_INT_VALUE + num_registration_centers + num_copy_centers + i rc = RegistrationCenter(name='no-reg-polling-center-%d' % i, center_id=center_id, constituency=constituency, subconstituency=subconstituency, office=random.choice(offices), reg_open=False) rc.full_clean() rc.save() all_kinds_of_centers = centers + copy_centers + no_reg_centers if center_without_office: try: # by not specifying office and other infra, it will be "standalone" rc = RegistrationCenter(name='dummy-registration-center', center_id=UNUSED_CENTER_ID) rc.full_clean() rc.save() except ValidationError: pass # assume that it already exists for election in elections: num_daily_reports_on_election_day = int(round(0.9 * num_daily_reports)) centers_reported = set() for i in range(num_daily_reports_on_election_day): staff_phone_number = STAFF_PHONE_NUMBER_PATTERN % i from_center = random.choice(all_kinds_of_centers) ensure_staff_phone_exists(staff_phone_number, from_center, staff_phones, election.work_start_time + datetime.timedelta(minutes=5)) # split votes between two options number_of_votes = (random.randint(1, 100), random.randint(1, 100)) random_period_number = random.randint(FIRST_PERIOD_NUMBER, LAST_PERIOD_NUMBER) pr = PollingReport(election=election, phone_number=staff_phone_number, registration_center=from_center, period_number=random_period_number, num_voters=sum(number_of_votes), creation_date=election.polling_start_time) pr.full_clean() pr.save() s = SMS(from_number=staff_phone_number, to_number=POLLING_REPORT_PHONE_NUMBER, direction=INCOMING, message='my message', msg_type=SMS.POLLING_REPORT, message_code=MESSAGE_1, carrier=carrier, creation_date=election.polling_start_time) s.full_clean() s.save() if from_center in centers_reported: continue # can't send but one PreliminaryVoteCount from a center # send a corresponding vote count for option, votes_for_option in enumerate(number_of_votes, start=1): pvc = PreliminaryVoteCount(election=election, phone_number=staff_phone_number, registration_center=from_center, option=option, num_votes=votes_for_option, creation_date=election.polling_start_time) pvc.full_clean() pvc.save() s = SMS(from_number=staff_phone_number, to_number=PRELIMINARY_VOTE_COUNT_PHONE_NUMBER, # XXX no specific message type for PreliminaryVoteCount direction=INCOMING, message='my message', msg_type=SMS.POLLING_REPORT, message_code=MESSAGE_1, carrier=carrier, creation_date=election.polling_start_time) s.full_clean() s.save() centers_reported.add(from_center) # some daily reports on the day after for i in range(num_daily_reports - num_daily_reports_on_election_day): staff_phone_number = STAFF_PHONE_NUMBER_PATTERN % i rc = random.choice(all_kinds_of_centers) ensure_staff_phone_exists(staff_phone_number, rc, staff_phones, election.work_start_time + datetime.timedelta(minutes=5)) report_creation_date = election.polling_start_time + datetime.timedelta(days=1) pr = PollingReport(election=election, phone_number=staff_phone_number, registration_center=rc, period_number=LAST_PERIOD_NUMBER, # day after counts as last period num_voters=random.randint(1, 50), creation_date=report_creation_date) pr.full_clean() pr.save() s = SMS(from_number=staff_phone_number, to_number=POLLING_REPORT_PHONE_NUMBER, direction=INCOMING, message='my message', msg_type=SMS.POLLING_REPORT, message_code=MESSAGE_1, carrier=carrier, creation_date=election.polling_start_time) s.full_clean() s.save() # Tag some centers as inactive for the election. We may or may not pick some that # sent messages as being inactive. num_inactive_centers_per_election = \ min(num_inactive_centers_per_election, len(all_kinds_of_centers)) if num_inactive_centers_per_election: reordered = all_kinds_of_centers random.shuffle(reordered) for i in range(num_inactive_centers_per_election): inactive_on_election = CenterClosedForElection( registration_center=reordered[i], election=election ) inactive_on_election.full_clean() inactive_on_election.save() tz = timezone(settings.TIME_ZONE) # construct a datetime that will change based on timezone discrepancies # 0-2am in Libya has a different date than the same time in UDT or EDT today_fragile = now().astimezone(tz).replace(hour=0, minute=59) # tz.normalize fixes up the date arithmetic when crossing DST boundaries creation_dates = \ [tz.normalize((today_fragile - datetime.timedelta(days=DAYS_BETWEEN_REGISTRATIONS * i)).astimezone(tz)) for i in range(num_registration_dates)] citizens = [] for i in range(num_registrations): # about 60% of registrations are for males, just as with actual data gender = MALE if random.randint(1, 100) <= 60 else FEMALE nat_id = '%d%011d' % (gender, i) creation_date = random.choice(creation_dates) modification_date = creation_date # Select voter ages from 18 years on up. voter_age = random.randint(18, 99) # If they were a certain age at any time yesterday, they are certainly that age at any time # today. yesterday = datetime.datetime.now().replace(tzinfo=tz) - datetime.timedelta(days=1) birth_date = datetime.date(yesterday.year - voter_age, yesterday.month, yesterday.day) civil_registry_id = random.randint(1, 99999999) citizen = CitizenFactory(civil_registry_id=civil_registry_id, national_id=nat_id, gender=gender, birth_date=birth_date) citizens.append(citizen) s = SMS(from_number=VOTER_PHONE_NUMBER_PATTERN % i, to_number=REGISTRATION_PHONE_NUMBER, citizen=citizen, direction=INCOMING, message='my reg message', msg_type=SMS.REGISTRATION, message_code=MESSAGE_1, carrier=carrier, creation_date=creation_date) s.full_clean() s.save() rc = random.choice(centers) confirmed = random.randint(1, 100) <= 80 # most are confirmed if confirmed: archive_time = None else: archive_time = random.choice(creation_dates) r = Registration(citizen=citizen, registration_center=rc, sms=s, archive_time=archive_time, creation_date=creation_date, modification_date=modification_date) r.full_clean() r.save() if num_registrations: # if any data being generated # generate a variety of sms messages for i in range(NUM_RANDOM_SMS_MESSAGES): sms_type = random.choice(SMS.MESSAGE_TYPES)[0] staff_phone = random.choice(staff_phones) s = SMS(from_number=staff_phone.phone_number, to_number=RANDOM_MESSAGE_PHONE_NUMBER, citizen=random.choice(citizens), direction=INCOMING, message='my long random message', msg_type=sms_type, message_code=MESSAGE_1, carrier=carrier, creation_date=random.choice(creation_dates)) s.full_clean() s.save() for election in elections: for rc in centers: i = random.randint(8888, 9999) staff_phone_number = STAFF_PHONE_NUMBER_PATTERN % i ensure_staff_phone_exists(staff_phone_number, rc, staff_phones, election.work_start_time + datetime.timedelta(minutes=5)) center_open = CenterOpen( election=election, phone_number=staff_phone_number, registration_center=rc, creation_date=election.polling_start_time.replace(hour=random.randint(0, 10), minute=23)) center_open.full_clean() center_open.save() s = SMS(from_number=staff_phone_number, to_number=ACTIVATE_PHONE_NUMBER, direction=INCOMING, message='my message', msg_type=SMS.ACTIVATE, message_code=MESSAGE_1, carrier=carrier, creation_date=election.polling_start_time) s.full_clean() s.save()