def import_bill(data, standalone_votes, categorizer):
abbr = data[settings.LEVEL_FIELD]<EOL>data['<STR_LIT>'] = fix_bill_id(data['<STR_LIT>'])<EOL>if '<STR_LIT>' in data:<EOL><INDENT>data['<STR_LIT>'] = [fix_bill_id(bid) for bid in<EOL>data['<STR_LIT>']]<EOL><DEDENT>subjects = data.pop('<STR_LIT>', None)<EOL>if subjects:<EOL><INDENT>data['<STR_LIT>'] = subjects<EOL><DEDENT>if categorizer:<EOL><INDENT>categorizer.categorize_bill(data)<EOL><DEDENT>for companion in data['<STR_LIT>']:<EOL><INDENT>companion['<STR_LIT>'] = fix_bill_id(companion['<STR_LIT>'])<EOL>spec = companion.copy()<EOL>spec[settings.LEVEL_FIELD] = abbr<EOL>if not spec['<STR_LIT>']:<EOL><INDENT>spec.pop('<STR_LIT>')<EOL><DEDENT>companion_obj = db.bills.find_one(spec)<EOL>if companion_obj:<EOL><INDENT>companion['<STR_LIT>'] = companion_obj['<STR_LIT>']<EOL><DEDENT>else:<EOL><INDENT>logger.warning('<STR_LIT>'<EOL>.format(**companion))<EOL><DEDENT><DEDENT>bill = db.bills.find_one({settings.LEVEL_FIELD: abbr,<EOL>'<STR_LIT>': data['<STR_LIT>'],<EOL>'<STR_LIT>': data['<STR_LIT>'],<EOL>'<STR_LIT>': data['<STR_LIT>']})<EOL>doc_matcher = DocumentMatcher(abbr)<EOL>if bill:<EOL><INDENT>doc_matcher.learn_ids(bill['<STR_LIT>'] + bill['<STR_LIT>'])<EOL><DEDENT>doc_matcher.set_ids(data['<STR_LIT>'] + data['<STR_LIT>'])<EOL>match_sponsor_ids(abbr, data)<EOL>bill_votes = data.pop('<STR_LIT>', [])<EOL>if metadata(abbr).get('<STR_LIT>'):<EOL><INDENT>numeric_bill_id = data['<STR_LIT>'].split()[<NUM_LIT:1>]<EOL>bill_votes += standalone_votes.pop((data['<STR_LIT>'], data['<STR_LIT>'],<EOL>numeric_bill_id), [])<EOL><DEDENT>else:<EOL><INDENT>bill_votes += standalone_votes.pop((data['<STR_LIT>'], data['<STR_LIT>'],<EOL>data['<STR_LIT>']), [])<EOL><DEDENT>if bill:<EOL><INDENT>prepare_votes(abbr, data['<STR_LIT>'], bill['<STR_LIT>'], bill_votes)<EOL><DEDENT>else:<EOL><INDENT>prepare_votes(abbr, data['<STR_LIT>'], None, bill_votes)<EOL><DEDENT>dates = {'<STR_LIT>': None, '<STR_LIT>': None, '<STR_LIT>': None,<EOL>'<STR_LIT>': None, '<STR_LIT>': None}<EOL>vote_flags = {<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>"<EOL>}<EOL>already_linked = set()<EOL>remove_vote = set()<EOL>for action in data['<STR_LIT>']:<EOL><INDENT>adate = action['<STR_LIT:date>']<EOL>def _match_committee(name):<EOL><INDENT>return get_committee_id(abbr, action['<STR_LIT>'], name)<EOL><DEDENT>def _match_legislator(name):<EOL><INDENT>return get_legislator_id(abbr,<EOL>data['<STR_LIT>'],<EOL>action['<STR_LIT>'],<EOL>name)<EOL><DEDENT>resolvers = {<EOL>"<STR_LIT>": _match_committee,<EOL>"<STR_LIT>": _match_legislator<EOL>}<EOL>if "<STR_LIT>" in action:<EOL><INDENT>for entity in action['<STR_LIT>']:<EOL><INDENT>try:<EOL><INDENT>resolver = resolvers[entity['<STR_LIT:type>']]<EOL><DEDENT>except KeyError as e:<EOL><INDENT>logger.error("<STR_LIT>" % e)<EOL>continue<EOL><DEDENT>id = resolver(entity['<STR_LIT:name>'])<EOL>entity['<STR_LIT:id>'] = id<EOL><DEDENT><DEDENT>if not dates['<STR_LIT>'] or adate < dates['<STR_LIT>']:<EOL><INDENT>dates['<STR_LIT>'] = adate<EOL><DEDENT>if not dates['<STR_LIT>'] or adate > dates['<STR_LIT>']:<EOL><INDENT>dates['<STR_LIT>'] = adate<EOL><DEDENT>if (not dates['<STR_LIT>'] and action['<STR_LIT>'] == '<STR_LIT>'<EOL>and '<STR_LIT>' in action['<STR_LIT:type>']):<EOL><INDENT>dates['<STR_LIT>'] = adate<EOL><DEDENT>elif (not dates['<STR_LIT>'] and action['<STR_LIT>'] == '<STR_LIT>'<EOL>and '<STR_LIT>' in action['<STR_LIT:type>']):<EOL><INDENT>dates['<STR_LIT>'] = adate<EOL><DEDENT>elif (not dates['<STR_LIT>'] and '<STR_LIT>' in action['<STR_LIT:type>']):<EOL><INDENT>dates['<STR_LIT>'] = adate<EOL><DEDENT>action_attached = False<EOL>if set(action['<STR_LIT:type>']).intersection(vote_flags) and action['<STR_LIT:date>']:<EOL><INDENT>for vote in bill_votes:<EOL><INDENT>if not vote['<STR_LIT:date>']:<EOL><INDENT>continue<EOL><DEDENT>delta = abs(vote['<STR_LIT:date>'] - action['<STR_LIT:date>'])<EOL>if (delta < datetime.timedelta(hours=<NUM_LIT:20>) and<EOL>vote['<STR_LIT>'] == action['<STR_LIT>']):<EOL><INDENT>if action_attached:<EOL><INDENT>action.pop('<STR_LIT>', None)<EOL><DEDENT>else:<EOL><INDENT>related_vote = vote['<STR_LIT>']<EOL>if related_vote in already_linked:<EOL><INDENT>remove_vote.add(related_vote)<EOL><DEDENT>already_linked.add(related_vote)<EOL>action['<STR_LIT>'] = [related_vote]<EOL>action_attached = True<EOL><DEDENT><DEDENT><DEDENT><DEDENT><DEDENT>for action in data['<STR_LIT>']:<EOL><INDENT>for vote in remove_vote:<EOL><INDENT>if vote in action.get('<STR_LIT>', []):<EOL><INDENT>action['<STR_LIT>'].remove(vote)<EOL><DEDENT><DEDENT><DEDENT>data['<STR_LIT>'] = dates<EOL>data['<STR_LIT>'] = term_for_session(abbr, data['<STR_LIT>'])<EOL>alt_titles = set(data.get('<STR_LIT>', []))<EOL>for version in data['<STR_LIT>']:<EOL><INDENT>if '<STR_LIT:title>' in version:<EOL><INDENT>alt_titles.add(version['<STR_LIT:title>'])<EOL><DEDENT>if '<STR_LIT>' in version:<EOL><INDENT>alt_titles.add(version['<STR_LIT>'])<EOL><DEDENT><DEDENT>try:<EOL><INDENT>alt_titles.remove(data['<STR_LIT:title>'])<EOL><DEDENT>except KeyError:<EOL><INDENT>pass<EOL><DEDENT>data['<STR_LIT>'] = list(alt_titles)<EOL>data = apply_filters(filters, data)<EOL>if not bill:<EOL><INDENT>insert_with_id(data)<EOL>git_add_bill(data)<EOL>save_votes(data, bill_votes)<EOL>return "<STR_LIT>"<EOL><DEDENT>else:<EOL><INDENT>update(bill, data, db.bills)<EOL>git_add_bill(bill)<EOL>save_votes(bill, bill_votes)<EOL>return "<STR_LIT>"<EOL><DEDENT>
insert or update a bill

data - raw bill JSON
standalone_votes - votes scraped separately
categorizer - SubjectCategorizer (None - no categorization)