def get_best_voter_rec(dao, contact): from models.voter import Voter candidates = Voter.voters_by_name_and_address(dao, contact.address, contact.name) if not candidates: return None streets = set( [candidate.address.street_name for candidate in candidates]) best_street = MatchLib.get_best_match(contact.address.street_name, streets, 85) if not best_street: return None candidates = [ candidate for candidate in candidates if candidate.address.street_name == best_street ] best_name = MatchLib.get_best_match( str(contact), [str(candidate.name) for candidate in candidates], 85) if not best_name: return None return [ candidate for candidate in candidates if str(candidate.name) == best_name ][0]
def batch_lookup(submissions): from models.street_index import StreetIndex from dao.dao import Dao dao = Dao(stateful=True) for submission in submissions: # print(str(submission.name)) street = '%s %s' % (submission.address.street_name, submission.address.street_type) if submission.address.metaphone: voters = Voter.__get_by_location(dao, submission) if voters: streets = set( [voter.address.street_name for voter in voters]) matches = MatchLib.get_best_partials(street, streets, 85) voters = [ voter for voter in voters if voter.address.street_name in matches ] voters_by_name = { str(voter.name): voter for voter in voters } names = [str(voter.name) for voter in voters] matches = MatchLib.get_best_partials( str(submission.name), names, 65) if matches: submission.matches = [ voters_by_name[match] for match in matches ] top_score = 0 for match in submission.matches: Voter.__set_match_score(submission, match) if match.score > top_score: top_score = match.score if top_score < 65: voters = [] else: continue voters = Voter.__get_by_name(dao, submission) if voters: if submission.address.street_name: streets = set( [voter.address.street_name for voter in voters]) matches = MatchLib.get_best_partials(street, streets, 85) submission.matches = [ voter for voter in voters if voter.address.street_name in matches ] else: submission.matches = voters if not submission.matches: if StreetIndex.is_valid_address(submission.address): submission.matches = Voter.__get_household(dao, submission) for match in submission.matches: Voter.__set_match_score(submission, match) dao.close()
def choose_email(candidates, target, threshold): from utils.match import MatchLib target = target.split('@') emails = [c.split('@') for c in candidates] best_domain = MatchLib.get_best_match(target[1], set([email[1] for email in emails]))[0] usernames = [email[0] for email in emails if email[1] in [target[1], best_domain]] matches = MatchLib.get_best_matches(target[0], usernames, threshold) return [match[0] + '@' + best_domain for match in matches] if matches else []
def choose_email(self, candidates): target = self.info.email.split('@') emails = [c.split('@') for c in candidates] best_domain = MatchLib.get_best_match( target[1], set([email[1] for email in emails]))[0] usernames = [ email[0] for email in emails if email[1] in [target[1], best_domain] ] matches = MatchLib.get_best_matches(target[0], usernames, 80) return [match[0] + '@' + best_domain for match in matches] if matches else []
def choose_email(candidates, target, threshold): from utils.match import MatchLib target = target.split('@') emails = [c.split('@') for c in candidates] best_domain = MatchLib.get_best_match( target[1], set([email[1] for email in emails]))[0] usernames = [ email[0] for email in emails if email[1] in [target[1], best_domain] ] matches = MatchLib.get_best_matches(target[0], usernames, threshold) return [match[0] + '@' + best_domain for match in matches] if matches else []
def __get_by_name(dao, submission): candidates = Voter.__get_candidates_name_only(dao, submission) candidates_by_name = { str(candidate.name): candidate for candidate in candidates } names = [str(candidate.name) for candidate in candidates] matches = MatchLib.get_best_partials(str(submission.name), names, 75) return [candidates_by_name[match] for match in matches]
def __voters_by_name(dao, pn): candidates = Voter.__get_candidates_by_name(dao, pn) candidates_by_name = { str(candidate.name): candidate for candidate in candidates } names = [str(candidate.name) for candidate in candidates] matches = MatchLib.get_best_partials(str(pn), names, 75) return [candidates_by_name[match] for match in matches]
def do_it(): sql = 'SELECT * FROM contacts' contacts = cursor.execute(sql).fetchall() for contact in contacts: if contact[9] == '': continue # username = contact[9].split('@')[0] metaphone = MatchLib.get_single(contact[9]) sql = "UPDATE contacts SET email_metaphone='%s' WHERE id=%d" % (metaphone, contact[0]) cursor.execute(sql) db.commit()
def get_best_turf(dao, contact): turfs = Address.get_turf(dao, contact.address) if not turfs: return None if len(set([turf['precinct_id'] for turf in turfs])) == 1: return turfs[0] d = {(t['pre_direction'] + ' ' + t['street_name'] + ' ' + t['street_type'] + ' ' + t['suf_direction']).strip(): t for t in turfs} match = MatchLib.get_best_match(str(contact.address), d.keys(), 85) return d[match] if match else None
def is_valid_address(addr): from utils.match import MatchLib rex = StreetIndex.get_by_address(addr) if not rex: return False streets = [ rec['street_name'] + ' ' + expanded_street_type(rec['street_type']) for rec in rex ] best_match = MatchLib.get_best_partial(addr.street, streets, 90) return True if best_match else False
def __get_candidates_name_only(dao, submission): pn = submission.name addr = submission.address sql = ("SELECT * " "FROM voters " "WHERE last_name_meta=? " "AND last_name LIKE ? " "AND first_name_meta=? " "AND first_name LIKE ?") vals = [ MatchLib.get_single(pn.last), pn.last[0] + '%', MatchLib.get_single(pn.first), pn.first[0] + '%' ] if addr.zipcode: sql += " AND zipcode LIKE ?" vals.append(addr.zipcode[0:4] + '%') elif addr.city: sql += " AND city=?" vals.append(addr.city) rex = dao.execute(sql, vals) return [Voter(rec) for rec in rex] if rex else []
def street_lookup(): from models.address import str_parse from utils.match import MatchLib params = json.loads(request.form['params']) addr = str_parse(params['address']) addr['county_code'] = '81' # TODO: get from cfg addr['meta'] = Address.get_street_meta(addr['street_name']) if params['city']: addr['city'] = params['city'] if params['zipcode']: addr['zipcode'] = params['zipcode'] dao = Dao() try: candidates = turf_dao.street_fuzzy_lookup(dao, addr) matches = MatchLib.get_best_matches( addr['street_name'], [c['street_name'] for c in candidates], 80) matches = [match[0] for match in matches] candidates = [ candidate for candidate in candidates if candidate['street_name'] in matches ] candidates = [{ 'address': { 'house_num_low': candidate['house_num_low'], 'house_num_high': candidate['house_num_high'], 'odd_even': candidate['odd_even'], 'pre_direction': candidate['pre_direction'], 'street_name': candidate['street_name'], 'street_type': candidate['street_type'], 'suf_direction': candidate['suf_direction'], 'unit_low': candidate['ext_low'], 'unit_high': candidate['ext_high'], 'city': candidate['city'], 'zipcode': candidate['zipcode'] }, 'voter_info': { 'precinct_id': candidate['precinct_id'] } } for candidate in candidates] return jsonify(candidates=candidates) except Exception as ex: return jsonify(error=str(ex))
def fuzzy_lookup(params): from models.person_name import PersonName from models.address import Address pn = PersonName(params) if 'address' in params and params['address'] != '': addr = Address(params) matches = Voter.by_fuzzy_name_and_address(pn, addr) if matches: return matches candidates = Voter.by_fuzzy_name(pn) candidates_by_name = { str(candidate): candidate for candidate in candidates } names = [str(candidate) for candidate in candidates] matches = MatchLib.get_best_partials(str(pn), names, 75) return [candidates_by_name[match] for match in matches]
def get_street_meta(street_name, street_type=None): from utils.match import MatchLib street = street_name.upper().strip() if street in ordinal_streets: street = ordinal_streets[street] n = '' for c in list(street): if c.isnumeric(): n += Address.__digit_mappings[c] else: n += c if n: street = n if street_type: st = street_type if st in street_abbrs: st = street_abbrs[st] street += ' ' + st return MatchLib.get_single(street)
def nickname(self, value): self.__nickname = value self.__nickname_meta = MatchLib.get_single(value)
def first(self, value): self.__first = self.__clean(value) self.__first_meta = MatchLib.get_single(self.__first)
def __init__(self, d=None): if d: self.last_name = d['last_name'].upper() self.name_metaphone = MatchLib.get_single(self.last_name) self.first_name = d['first_name'].upper()