def full_registration(self, user): # if given choice to register online, choose pdf form if self.browser.get_form(id='state_ovr'): finish_form = self.browser.get_form(id='finish') self.browser.submit_form(finish_form) full_form = self.browser.get_form(id='full_registration') if full_form: # BUG, user.get(field, '') results in silent 400 errors, wtf? # full_form['title'].value = user.get('title', '') # print 'set title', full_form['title'].value # full_form['suffix'].value = user.get('suffix', '') # print 'set suffix', full_form['suffix'].value full_form['state_id_number'].value = user['state_id_number'] party_translated = get_party_from_list(user.get('political_party'), options_dict(full_form['political_party']).keys()) if not party_translated: party_translated = 'No party' full_form['political_party'].value = options_dict(full_form['political_party'])[party_translated] # why does the form require bool as string? full_form['us_citizen'].value = str(bool_to_int(user['us_citizen'])) self.browser.submit_form(full_form) else: errors_string = ','.join(self.parse_errors()) raise ValidationError(message='unable to get_form full_registration.', payload=errors_string)
def edit_voter_information(self, user, form): party_options = options_dict(form['editVoterForm:partyAffiliationId']) # do fuzzy match to political party options party = get_party_from_list(user['political_party'], party_options.keys()) # it is required. if we haven't found a match, defer to 'Unaffiliated' if not party: party = 'Unaffiliated' form['editVoterForm:partyAffiliationId'].value = party_options[party] if user['military_or_overseas']: form['editVoterForm:areUOCAVAId'].value = 'Y' form['editVoterForm:uocavaTypeId'].value = 'a' if user[ 'military_or_overseas'] == 'military' else 'c' else: form['editVoterForm:areUOCAVAId'].value = 'N' form['editVoterForm:uocavaBallotMethodId'].value = 'Mail' if user[ 'vote_by_mail'] else 'Email' # or 'Fax' # email, phone and gender are prefilled form['editVoterForm:emailId'].value = user['email'] form[ 'editVoterForm:receiveEmailCommunicationId'].checked = 'checked' if user[ 'email'] else '' if 'phone' in user: # strip country prefix form['editVoterForm:phoneId'].value = user['phone'].replace( '+1', '') gender_str = parse_gender(user['gender']) if gender_str is 'F': form['editVoterForm:genderSelectId'].value = '0' elif gender_str is 'M': form['editVoterForm:genderSelectId'].value = '1' else: raise ValidationError(message='parse_gender error', payload=user['gender']) form['editVoterForm:resAddress'].value = user['address'] form['editVoterForm:resCity'].value = user['city'] form['editVoterForm:resCounty'].value = options_dict( form['editVoterForm:resCounty'])[user['county']] form['editVoterForm:resZip'].value = user['zip'] self.browser.submit_form(form, submit=form['editVoterForm:j_idt114'])
def illinois_address(self, user): self.browser.open('https://ova.elections.il.gov/Step5.aspx') frm = self.browser.get_form() address_components = get_address_components(user['address'], user['city'], user['state'], user['zip']) frm['ctl00$MainContent$tbResidentStreetNumber'].value = address_components[ 'primary_number'] if 'street_predirection' in address_components: frm['ctl00$MainContent$ddlResidentStreetDirection'].value = options_dict( frm['ctl00$MainContent$ddlResidentStreetDirection'])[ address_components['street_predirection'].upper()] frm['ctl00$MainContent$tbResidentStreetName'].value = address_components[ 'street_name'] if 'street_suffix' in address_components: frm['ctl00$MainContent$ddlResidentStreetType'].value = options_dict( frm['ctl00$MainContent$ddlResidentStreetType'])[ address_components['street_suffix'].upper()] if 'street_postdirection' in address_components: frm['ctl00$MainContent$ddlResidentPostDirection'].value = options_dict( frm['ctl00$MainContent$ddlResidentPostDirection'])[ address_components['street_postdirection'].upper()] if user.get('address_unit' ) and not user.get('address_unit').lower() == "none": frm['ctl00$MainContent$tbResidentAptRmSuite'].value = user.get( 'address_unit') if 'secondary_designator' in address_components: try: frm['ctl00$MainContent$ddlResidentAptRmBoxSuite'].value = options_dict( frm['ctl00$MainContent$ddlResidentAptRmBoxSuite'])[ address_components['secondary_designator']] except: pass frm['ctl00$MainContent$tbResidentCity'].value = address_components[ 'city_name'] frm['ctl00$MainContent$tbResidentZip'].value = address_components[ 'zipcode'] self.browser.submit_form(frm, submit=frm['ctl00$MainContent$btnNext'])
def illinois_different_address(self, user): self.browser.open('https://ova.elections.il.gov/Step10b.aspx') frm = self.browser.get_form() if user["has_previous_address"]: address_components = get_address_components( user['previous_address'], user['previous_city'], user['previous_state'], user['previous_zip']) frm['ctl00$MainContent$tbFormerStreetNumber'].value = address_components[ 'primary_number'] if 'street_predirection' in address_components: frm['ctl00$MainContent$ddlFormerStreetDirection'].value = options_dict( frm['ctl00$MainContent$ddlFormerStreetDirection'])[ address_components['street_predirection'].upper()] frm['ctl00$MainContent$tbFormerStreetName'].value = address_components[ 'street_name'] if 'street_suffix' in address_components: frm['ctl00$MainContent$ddlFormerStreetType'].value = options_dict( frm['ctl00$MainContent$ddlFormerStreetType'])[ address_components['street_suffix'].upper()] if 'street_postdirection' in address_components: frm['ctl00$MainContent$ddlFormerPostDirection'].value = options_dict( frm['ctl00$MainContent$ddlFormerPostDirection'])[ address_components['street_postdirection'].upper()] frm['ctl00$MainContent$tbFormerCity'].value = address_components[ 'city_name'] frm['ctl00$MainContent$tbFormerZip'].value = address_components[ 'zipcode'] election_authority = self.determine_election_authority( address_components['city_name'], address_components['county_name']) frm['ctl00$MainContent$ddlCountySelect'].value = options_dict( frm['ctl00$MainContent$ddlCountySelect'])[election_authority] else: frm["ctl00$MainContent$rblFormerAddress"].value = "No" self.browser.submit_form(frm, submit=frm['ctl00$MainContent$btnNext'])
def illinois_election_authority(self, user): self.browser.open('https://ova.elections.il.gov/Step8.aspx') frm = self.browser.get_form() election_authority = self.determine_election_authority( user["city"], user["county"]) frm['ctl00$MainContent$ddlElectionAuthoritySelect'].value = options_dict( frm['ctl00$MainContent$ddlElectionAuthoritySelect'] )[election_authority] self.browser.submit_form(frm, submit=frm['ctl00$MainContent$btnNext'])
def voter_information(self, user, form): form['townId'].value = options_dict( form['townId'])[user['city'].upper()] form['firstName'].value = user['first_name'] form['lastName'].value = user['last_name'] (year, month, day) = split_date(user['date_of_birth']) form['Dob'].value = '/'.join([month, day, year]) form['DLNumber'].value = user['state_id_number'] form['email'].value = user['email']
def residence_address(self, user, form): # reassemble address_components to match street name dropdowns # in the browser this autofills, but we get to do it manually address_components = get_address_components(user['address'], user['city'], user['state'], user['zip']) form['streetNum'].value = address_components['primary_number'] full_street_name = get_street_name_from_components(address_components) form['streetName1'].value = options_dict( form['streetName1'])[full_street_name.upper()] street_value = form['streetName1'].value # look up postal city key and rural_flag from street_value postal_city = self.get_postal_city( street_value, address_components['county_name'])[0] rural_flag = postal_city['fl_Rural_Flag'] form['ruralcityFlag'].value = rural_flag.lower() if rural_flag == "Y": form['rural_city'].options = (postal_city['key'], ) form['rural_city'].value = str(postal_city['key']) else: # replace weird city selector with a regular input form.fields.pop('city') city_field = robobrowser.forms.fields.Input( '<input type="hidden" id="city" name="city"></input>') city_field.value = str(postal_city['key']) form.add_field(city_field) # of course, there's also a hidden cityName field to append city_name = robobrowser.forms.fields.Input( '<input type="hidden" id="cityName" name="cityName"></input>') city_name.value = address_components['city_name'].upper() form.add_field(city_name) form['state'].value = address_components['state_abbreviation'] form['zip5'].value = address_components['zipcode'] form['countyS3'].value = address_components['county_name'].upper() # update form action, this happens in javascript on validateForm form.action = 'regStep4.do' self.browser.submit_form(form, submit=form['next']) return form
def residence_address(self, user, form): # form is prefilled with info from DMV # overwrite with info from hellovote form['CurrentAddress.Address.Line1'] = user.get('address').upper() form['CurrentAddress.Address.Line2'] = user.get('address_unit', '') form['CurrentAddress.Address.City'] = user.get('city').upper() form['CurrentAddress.Address.ZipCode'] = user.get('zip') # try to match locality by county name locality = user.get('county').upper() locality_options = options_dict(form['CurrentAddress.Address.LocalityUId']) if locality in locality_options: form['CurrentAddress.Address.LocalityUId'] = locality_options[locality] else: locality = locality + " COUNTY" form['CurrentAddress.Address.LocalityUId'] = locality_options[locality] self.browser.submit_form(form)
def personal_information(self, user, form): form = self.browser.get_form("formId") # update form action, this happens in javascript on validateForm form.action = 'reqConsentAndDecline.do' if user.get('has_previous_address'): # change voter registration form['changeType'].value = 'CV' form['_addrChange'].checked = 'checked' # don't actually change registration here, do it later in general information else: # new voter registration form['changeType'].value = 'NV' if user.get('has_previous_name'): form['changeType'].value = 'CV' form['_nmChange'].checked = 'checked' (prev_first, prev_middle, prev_last) = split_name(user.get('previous_name')) form['preFirstName'].value = prev_first form['preLastName'].value = prev_last # county select from list form['county'].value = options_dict( form['county'])[user['county'].upper()] form['lastName'].value = user['last_name'].upper() form['firstName'].value = user['first_name'].upper() (year, month, day) = split_date(user['date_of_birth']) form['dobDate'].value = '/'.join([month, day, year]) form['ddsId'].value = user['state_id_number'] self.browser.submit_form(form, submit=form['next']) return form
def step2(self, form, user): # Eligibility form['IsUSCitizen'].value = bool_to_string(user['us_citizen']) if user['will_be_18']: form['RegistrationChoice'].value = '1' # I will be 18 or older by the next election. else: # other options: # form['RegistrationChoice'].value = '2' # I am a 16 or 17 years old and I would like to pre-register to vote. # don't handle this yet, needs update in votebot-api raise ValidationError(message='not eligible', payload={ 'will_be_18': user['will_be_18'], 'date_of_birth': user['date_of_birth'] }) prefix_options = options_dict(form['Prefix']) if 'name_prefix' in user: form['Prefix'].value = prefix_options.get(user['name_prefix']) form['FirstName'].value = user['first_name'] form['MiddleName'].value = user.get('middle_name') form['LastName'].value = user['last_name'] suffix_options = options_dict(form['Suffix']) if 'name_suffix' in user: form['Suffix'].value = suffix_options.get(user['name_suffix']) form['EmailAddress'].value = user.get('email', '') form['ConfirmEmail'].value = user.get('email', '') if user.get('phone'): phone = user.get('phone').replace('+1', '').replace('-', '') form['PhoneNumber'].value = phone # change of name if user.get('has_previous_name'): form['IsPreviouslyRegistered'].checked = 'checked' (prev_first, prev_middle, prev_last) = split_name(user.get('previous_name', '')) form['Previous.FirstName'] = prev_first form['Previous.MiddleName'] = prev_middle form['Previous.LastName'] = prev_last # change of address if user.get('has_previous_adress'): form['IsPreviouslyRegistered'].checked = 'checked' form['Previous.StreetAddress'] = user.get('previous_address', '') form['Previous.ApartmentLotNumber'] = user.get( 'previous_address_unit', '') form['Previous.City'] = user.get('previous_city', '') form['Previous.Zip'] = user.get('previous_zip', '') form['Previous.StateId'] = user.get('previous_state', '') # separate mailing address if user.get('has_separate_mailing_addresss'): form['IsDifferentMailingAddress'].checked = 'checked' mailing_components = get_address_from_freeform( user.get('separate_mailing_address')) form['Mailing.StreetAddress'] = get_street_address_from_components( mailing_components) form[ 'Mailing.ApartmentLotNumber'] = get_address_unit_from_components( mailing_components) form['Mailing.City'] = mailing_components('city_name') form['Mailing.State'] = mailing_components('state_abbreviation') form['Mailing.Zip'] = mailing_components('zipcode') (year, month, day) = split_date(user['date_of_birth'], padding=False) form['MonthOfBirth'].value = month form['DayOfBirth'].value = day form['YearOfBirth'].value = year # ID and last 4 of SSN (CA requires both!) if 'state_id_number' in user: form['CaliforniaID'].value = user.get('state_id_number') else: form['HasNoCaliforniaID'].value = bool_to_string(True) # we actually require this, so shouldn't get here, but just in case if user.get('ssn_last4') == "NONE": form['HasNoSSN'].value = bool_to_string(True) else: form['SSN4'].value = user.get('ssn_last4') # Home and Mailing Address form['Home.StreetAddress'].value = user['address'] form['Home.ApartmentLotNumber'].value = user.get('address_unit') form['Home.City'].value = user['city'] form['Home.Zip'].value = user['zip'] county_options = options_dict(form['Home.CountyId']) try: form['Home.CountyId'].value = county_options.get( user['county'].strip().upper()) except KeyError: raise ValidationError(message='no county match', payload=user['county']) # Ethnicity (optional) if 'ethnicity' in user: ethnicity_options = options_dict(form['EthnicityId']) form['EthnicityId'].value = ethnicity_options.get( user['ethnicity'].upper(), ethnicity_options['OTHER']) # Political Party Preference user["political_party"] = user["political_party"].strip().upper() # they have two inputs with the same name but separated by other elements # so robobrowser's _group_flat_tags creates two entries, which their server won't validate form.fields.pop('PoliticalPreferenceType') # recreate with just one PoliticalPreferenceType = Input( "<input type='radio' name='PoliticalPreferenceType'/>") PoliticalPreferenceType.options = ['1', '2'] form.add_field(PoliticalPreferenceType) if user['political_party'].lower( ) == 'independent' or user['political_party'].lower() == "none": PoliticalPreferenceType.value = '2' PoliticalPreferenceType.checked = 'checked' # also delete the politcal party select form.fields.pop('PoliticalPartyId') else: # mess with the DOM to un-disable Political Party del self.browser.select( 'select[name="PoliticalPartyId"]')[0]['disabled'] PoliticalPreferenceType.value = '1' PoliticalPreferenceType.checked = 'checked' party_options = options_dict(form['PoliticalPartyId']) # do fuzzy match to political party options party_choice = get_party_from_list(user['political_party'], party_options.keys()) if party_choice in party_options.keys(): form['PoliticalPartyId'].value = party_options[party_choice] else: form['PoliticalPartyId'].value = party_options.get('Other') form['OtherPoliticalParty'].value = user['political_party'] self.submit_form_field(form, 'GoToNext')
def complete_form(self, user, form): address_components = get_address_components(user['address'], user['city'], user['state'], user['zip']) form['ctl00$MainContent$txtStNum'].value = address_components[ 'primary_number'] street_name = get_street_name_from_components(address_components) form['ctl00$MainContent$txStNameSuffix'].value = street_name[:25] if user.get('address_unit' ) and not user.get('address_unit').lower() == "none": form['ctl00$MainContent$txtUnitApt'].value = user.get( 'address_unit') if 'street_suffix' in address_components: street_suffix_options = options_dict( form['ctl00$MainContent$ddlStreetSuffix']) try: form[ 'ctl00$MainContent$ddlStreetSuffix'].value = street_suffix_options[ address_components['street_suffix'].upper()] except KeyError: form[ 'ctl00$MainContent$ddlStreetSuffix'].value = street_suffix_options[ 'No suffix'] city_normalized = MA_ARCHAIC_COMMUNITIES.get(user['city'], user['city']) try: form['ctl00$MainContent$ddlCityTown'].value = options_dict( form['ctl00$MainContent$ddlCityTown'])[city_normalized] except KeyError: raise ValidationError( message='unable to find city in MA CityTown list', payload=user['city']) form['ctl00$MainContent$txtZip'].value = user['zip'] user_party = user['political_party'].strip() parties = options_dict(form['ctl00$MainContent$ddlPartyList']) designations = options_dict( form['ctl00$MainContent$ddlPoliticalDesig']) party = get_party_from_list(user_party, parties.keys()) designation = get_party_from_list(user_party, designations.keys()) user_party = user_party.lower() if user_party and user_party != 'independent' and user_party != 'none': if party: form['ctl00$MainContent$PartyEnrolled'].value = 'rdoBtnParty' # crucial - un-disable the party list del self.browser.select( 'select[name="ctl00$MainContent$ddlPartyList"]' )[0]['disabled'] form['ctl00$MainContent$ddlPartyList'].value = parties[party] elif designation: form[ 'ctl00$MainContent$PartyEnrolled'].value = 'rdoBtnPolDesig' # crucial - un-disable the designation list del self.browser.select( 'select[name="ctl00$MainContent$ddlPoliticalDesig"]' )[0]['disabled'] form[ 'ctl00$MainContent$ddlPoliticalDesig'].value = designations[ designation] else: # unable to match designation, unenrolled self.add_error( "We were unable to match that political designation", field='political_party') form['ctl00$MainContent$PartyEnrolled'].value = 'rdoBtnNoParty' else: # No Party (Unenrolled, commonly referred to as ''Independent'') form['ctl00$MainContent$PartyEnrolled'].value = 'rdoBtnNoParty' # phone number, optional if user.get('phone'): phone = user.get('phone').replace('+1', '') form['ctl00$MainContent$txtAreaCode'].value = phone[0:3] form['ctl00$MainContent$txtPhone3'].value = phone[3:6] form['ctl00$MainContent$txtPhone4'].value = phone[6:10] # separate mailing address if user.get('has_separate_mailing_address'): form['ctl00$MainContent$ChkDiffMailAddr'].checked = 'checked' form['ctl00$MainContent$ChkDiffMailAddr'].value = 'on' # remove the disabled attr on the relevant fields del self.browser.select( 'input[name="ctl00$MainContent$txtDiffStNamePO"]' )[0]['disabled'] del self.browser.select( 'input[name="ctl00$MainContent$txtDiffUnitApt"]' )[0]['disabled'] del self.browser.select( 'input[name="ctl00$MainContent$txtDiffCityTownCounty"]' )[0]['disabled'] del self.browser.select( 'input[name="ctl00$MainContent$txtDiffZip"]')[0]['disabled'] del self.browser.select( 'select[name="ctl00$MainContent$ddlDiffStateTerr"]' )[0]['disabled'] # parse mailing address components mailing_address = get_address_from_freeform( user['separate_mailing_address']) mailing_components = mailing_address['components'] # update fields with mailing address data form[ 'ctl00$MainContent$txtDiffStNamePO'].value = get_street_address_from_components( mailing_components) if mailing_components.get('secondary_number'): form[ 'ctl00$MainContent$txtDiffUnitApt'].value = get_address_unit_from_components( mailing_components) form[ 'ctl00$MainContent$txtDiffCityTownCounty'].value = mailing_components[ 'city_name'] form['ctl00$MainContent$txtDiffZip'].value = mailing_components[ 'zipcode'] form[ 'ctl00$MainContent$ddlDiffStateTerr'].value = mailing_components[ 'state_abbreviation'] # former name if user.get('has_previous_name'): prev_first, prev_middle, prev_last = split_name( user.get('previous_name')) del self.browser.select( 'input[name="ctl00$MainContent$txtFirstNameFormer"]' )[0]['disabled'] del self.browser.select( 'input[name="ctl00$MainContent$txtLastNameFormer"]' )[0]['disabled'] form['ctl00$MainContent$txtFirstNameFormer'].value = prev_first form['ctl00$MainContent$txtLastNameFormer'].value = prev_last # address where you were last registered to vote if user.get('has_previous_address'): form['ctl00$MainContent$ChkPrevRegAddr'].checked = 'checked' form['ctl00$MainContent$ChkPrevRegAddr'].value = 'on' # remove the disabled attr on the relevant fields del self.browser.select( 'input[name="ctl00$MainContent$TxtPrevRegStAddr"]' )[0]['disabled'] del self.browser.select( 'input[name="ctl00$MainContent$TxtPrevRegUnitApt"]' )[0]['disabled'] del self.browser.select( 'input[name="ctl00$MainContent$TxtPrevRegCityTownCounty"]' )[0]['disabled'] del self.browser.select( 'input[name="ctl00$MainContent$TxtPrevRegZip"]')[0]['disabled'] del self.browser.select( 'select[name="ctl00$MainContent$ddlPrevRegStateTerr"]' )[0]['disabled'] # update fields with previous address data form['ctl00$MainContent$TxtPrevRegStAddr'].value = user.get( 'previous_address', '') form['ctl00$MainContent$TxtPrevRegUnitApt'].value = user.get( 'previous_address_unit', '') form[ 'ctl00$MainContent$TxtPrevRegCityTownCounty'].value = user.get( 'previous_city', '') form['ctl00$MainContent$TxtPrevRegZip'].value = user.get( 'previous_zip', '') state_options = options_dict( form['ctl00$MainContent$ddlPrevRegStateTerr']) try: prev_state = state_options[state_abbr_to_name( user.get('previous_state'))] form[ 'ctl00$MainContent$ddlPrevRegStateTerr'].value = prev_state except KeyError: pass self.browser.submit_form(form)
def register_to_vote(self, user): frm = self.browser.get_form() user["political_party"] = user["political_party"].strip() if user['political_party'].lower( ) == 'independent' or user['political_party'].lower() == "none": frm['partyPreference'].value = "No Party Preference" else: party_options = options_dict(frm['partyPreference']) # do fuzzy match to political party options party_choice = get_party_from_list(user['political_party'], party_options.keys()) if party_choice in party_options.keys(): frm['partyPreference'].value = party_options[party_choice] else: frm['otherPartyPreference'].value = user['political_party'] frm['email'].value = user['email'] if user.get('has_previous_address'): frm['regOther'].checked = 'checked' prev_address_components = get_address_components( user['previous_address'], user['previous_city'], user['previous_state'], user['previous_zip']) # County or state where previously registered try: if prev_address_components['state_abbreviation'] == "AZ": COUNTY_IDS = { "Apache": "01", "Cochise": "02", "Coconino": "03", "Gila": "04", "Graham": "05", "Greenlee": "06", "Maricopa": "07", "Mohave": "08", "Navajo": "09", "Pima": "10", "Pinal": "11", "Santa Cruz": "12", "Yavapai": "13", "Yuma": "14", "La Paz": "15" } frm['regCounty'].value = COUNTY_IDS[ prev_address_components['county_name']] else: frm['regCounty'].value = user['previous_state'] except KeyError: raise ValidationError( message='unable to match previous state/county', payload=user['previous_zip']) if user.get('has_previous_name'): frm['nameChange'].checked = 'checked' (prev_first, prev_middle, prev_last) = split_name(user.get('previous_name')) frm['formerFirstName'] = prev_first frm['formerMiddleName'] = prev_middle frm['formerLastname'] = prev_last self.browser.submit_form(frm, submit=frm['_eventId_register'], headers=self.get_default_submit_headers())