def write_row(bill, sponsor, sponsor_type, sponsor_date):
  w.writerow([
    bill.congress,
    bill.display_number_no_congress_number,
    bill.title_no_number.encode("utf8"),
    bill.sponsor_role.party,
    "https://www.govtrack.us" + bill.get_absolute_url(),
    sponsor_type,
    sponsor.id,
    get_person_name(sponsor, firstname_position='before', show_district=True, show_party=True, firstname_style="nickname").encode("utf8"),
    get_person_name(sponsor, firstname_position='after', show_district=True, show_party=True, show_title=False, firstname_style="nickname").encode("utf8"),
    sponsor.role.party,
    sponsor_date.isoformat(),
  ])
Exemplo n.º 2
0
def bill_widget(request, congress, type_slug, number):
    bill = load_bill_from_url(congress, type_slug, number)

    from person.name import get_person_name
    if bill.sponsor: bill.sponsor.role = bill.sponsor_role  # for rending name
    sponsor_name = None if not bill.sponsor else \
        get_person_name(bill.sponsor, firstname_position='before', show_suffix=True)

    def get_text_info():
        from billtext import load_bill_text
        try:
            return load_bill_text(bill, None, mods_only=True)
        except IOError:
            return None

    return {
        "SITE_ROOT_URL":
        settings.SITE_ROOT_URL,
        "bill":
        bill,
        "congressdates":
        get_congress_dates(bill.congress),
        "subtitle":
        get_secondary_bill_title(bill, bill.titles),
        "sponsor_name":
        sponsor_name,
        "current":
        bill.congress == CURRENT_CONGRESS,
        "dead":
        bill.congress != CURRENT_CONGRESS
        and bill.current_status not in BillStatus.final_status_obvious,
        "text":
        get_text_info,
    }
Exemplo n.º 3
0
def bill_widget(request, congress, type_slug, number):
    bill = load_bill_from_url(congress, type_slug, number)

    from person.name import get_person_name
    if bill.sponsor: bill.sponsor.role = bill.sponsor_role # for rending name
    sponsor_name = None if not bill.sponsor else \
        get_person_name(bill.sponsor, firstname_position='before', show_suffix=True)

    def get_text_info():
        from billtext import load_bill_text
        try:
            return load_bill_text(bill, None, mods_only=True)
        except IOError:
            return None

    return {
        "SITE_ROOT_URL": settings.SITE_ROOT_URL,
        "bill": bill,
        "congressdates": get_congress_dates(bill.congress),
        "subtitle": get_secondary_bill_title(bill, bill.titles),
        "sponsor_name": sponsor_name,
        "current": bill.congress == CURRENT_CONGRESS,
        "dead": bill.congress != CURRENT_CONGRESS and bill.current_status not in BillStatus.final_status_obvious,
        "text": get_text_info,
    }
Exemplo n.º 4
0
def write_row(bill, sponsor, sponsor_type, sponsor_date):
    w.writerow([
        bill.congress,
        bill.display_number_no_congress_number,
        bill.title_no_number.encode("utf8"),
        bill.sponsor_role.party,
        "https://www.govtrack.us" + bill.get_absolute_url(),
        sponsor_type,
        sponsor.id,
        get_person_name(sponsor,
                        firstname_position='before',
                        show_district=True,
                        show_party=True,
                        firstname_style="nickname").encode("utf8"),
        get_person_name(sponsor,
                        firstname_position='after',
                        show_district=True,
                        show_party=True,
                        show_title=False,
                        firstname_style="nickname").encode("utf8"),
        sponsor.role.party,
        sponsor_date.isoformat(),
    ])
Exemplo n.º 5
0
def bill_details(request, congress, type_slug, number):
    if type_slug.isdigit():
        bill_type = type_slug
    else:
        try:
            bill_type = BillType.by_slug(type_slug)
        except BillType.NotFound:
            raise Http404("Invalid bill type: " + type_slug)
    
    bill = get_object_or_404(Bill, congress=congress, bill_type=bill_type, number=number)
    
    from person.name import get_person_name
    sponsor_name = None if not bill.sponsor else \
        get_person_name(bill.sponsor, role_date=bill.introduced_date, firstname_position='before', show_suffix=True)
    
    def get_reintroductions():
        reintro_prev = None
        reintro_next = None
        for reintro in bill.find_reintroductions():
            if reintro.congress < bill.congress: reintro_prev = reintro
            if reintro.congress > bill.congress and not reintro_next: reintro_next = reintro
        return reintro_prev, reintro_next
        
    def get_text_info():
        from billtext import load_bill_text
        try:
            return load_bill_text(bill, None, mods_only=True)
        except IOError:
            return None

    return {
        'bill': bill,
        "congressdates": get_congress_dates(bill.congress),
        "subtitle": get_secondary_bill_title(bill, bill.titles),
        "sponsor_name": sponsor_name,
        "reintros": get_reintroductions, # defer so we can use template caching
        "current": bill.congress == CURRENT_CONGRESS,
        "dead": bill.congress != CURRENT_CONGRESS and bill.current_status not in BillStatus.final_status_obvious,
        "feed": Feed.BillFeed(bill),
        "text": get_text_info,
    }
Exemplo n.º 6
0
	def handle(self, *args, **options):
		# get all calls
		calls = list(CallLog.objects.all()
			.filter(position__position__issue__bills__id__gt=0)	# only calls on bills, since we had a few non-bill calls at the beginning
			.exclude(user__email__endswith="@govtrack.us").exclude(user__email__endswith="@occams.info") # no testing calls by me
			.order_by('created')
			)

		# filter - take only calls with recordings
		calls = filter(lambda call : call.log.get("finished", {}).get("RecordingUrl"), calls)

		## shuffle so new anonymous ID assignments are random
		#shuffle(calls)

		# write out
		w = csv.writer(sys.stdout)

		w.writerow([
			"call_id",
			"call_date",
			"call_duration",
			# "recording_url", # !!! not-anonymized

			"caller_id",
			"caller_account_created",

			"caller_district",
			"caller_areacode",
			"caller_areacode_city",
			"caller_areacode_state",

			"topic_id",
			"topic_name",
			"topic_link",
			"position_id",
			"position_name",

			"office_id",
			"office_type",
			"office_name",
		])

		def anonymize_user(user):
			global max_research_anon_key
			profile = user.userprofile()
			if profile.research_anon_key is None:
				# assign next available ID
				max_research_anon_key += 1
				profile.research_anon_key = max_research_anon_key
				profile.save()
			return profile.research_anon_key

		for call in calls:
			if len(call.position.district) == 2: continue # data error in our very early data (one record?)

			# for making the right name for the called office
			call.target.person.role = call.target

			# write row
			w.writerow([
				# call
				call.id,
				call.created.isoformat(),
				int(call.log["finished"]["RecordingDuration"][0]),
				# !!! this is not anonymous - call.log["finished"]["RecordingUrl"][0],

				# user
				anonymize_user(call.user),
				call.user.date_joined.isoformat(),

				# caller
				call.position.district,
				call.log["start"]["Called"][0][2:5],
				call.log["start"]["CalledCity"][0],
				call.log["start"]["CalledState"][0],

				# topic of call
				call.position.position.issue.first().id,
				call.position.position.issue.first().title.encode("utf8"),
				";".join(["https://www.govtrack.us"+b.bill.get_absolute_url() for b in call.position.position.issue.first().bills.all()]),
				call.position.position.id,
				call.position.position.text.encode("utf8"),

				# target of call
				call.target.person.id,
				call.target.get_title(),
				get_person_name(call.target.person).encode("utf8"),
			])
Exemplo n.º 7
0
def lookup_reps(request):
    from django.contrib.humanize.templatetags.humanize import ordinal
    from person.name import get_person_name

    # Get the state and district from the query string.
    try:
        state = request.GET['state']
        district = int(request.GET['district'])
        if state not in stateapportionment: raise Exception()
    except:
        return {}

    # Get the bill (optional) from the query string
    from bill.models import Bill
    try:
        bill = Bill.from_congressproject_id(request.GET["bill"])
    except:
        bill = None

    # Helper to get relevant committee assignments.
    from committee.models import CommitteeMember, CommitteeMemberRole
    from committee.util import sort_members

    def mention_committees_once(committeeassignments):
        # The committee assignments have been sorted first by role (i.e.
        # committees that the person is the chair of come first) and then
        # by committee name (which also puts subcommittees after committees).
        # In order to be less verbose, only mention each full committee
        # once --- take the first in each mention.
        seen = set()
        for c in committeeassignments:
            if (c.committee in seen) or (c.committee.committee in seen):
                continue
            yield c
            if c.committee.committee is not None:
                seen.add(c.committee.committee)  # add main committee
            else:
                seen.add(c.committee)  # add this committee

    bounds = get_district_bounds(state, district)
    return {
        "state": {
            "name": statenames[state],
            "isTerritory": stateapportionment[state] == "T",
        },
        "district": {
            "ordinal": ordinal(district) if district > 0 else "At Large",
            "bounds": {
                "center": {
                    "latitude": bounds[0],
                    "longitude": bounds[1]
                },
                "zoom": bounds[2]
            }
        },
        "members": [{
            "id":
            p.id,
            "name":
            get_person_name(p,
                            role_recent=True,
                            firstname_position="before",
                            show_title=True,
                            show_party=False,
                            show_district=False),
            "name_formal":
            p.current_role.get_title() + " " + p.lastname,
            "url":
            p.get_absolute_url(),
            "type":
            p.current_role.get_role_type_display(),
            "description":
            p.current_role.get_description(),
            "party":
            p.current_role.party,
            "photo_url":
            p.get_photo_url_50() if p.has_photo() else None,
            "contact_url": (p.current_role.extra or {}).get("contact_form")
            or p.current_role.website,
            "phone":
            p.current_role.phone,
            "website":
            p.current_role.website,
            "pronouns": {
                "him_her": p.him_her,
                "his_her": p.his_her,
                "he_she": p.he_she,
            },
            "bill-status": {
                "cosponsor":
                p in bill.cosponsors.all(),
                "committee-assignments": [{
                    "committee":
                    c.committee.fullname,
                    "role":
                    c.get_role_display() if c.role in (
                        CommitteeMemberRole.chair,
                        CommitteeMemberRole.ranking_member,
                        CommitteeMemberRole.vice_chair) else None,
                } for c in mention_committees_once(
                    sort_members(
                        CommitteeMember.objects.filter(
                            person=p, committee__in=bill.committees.all())))]
            } if bill else None,
        } for p in list(
            Person.objects.filter(roles__current=True,
                                  roles__state=state,
                                  roles__role_type=RoleType.senator).order_by(
                                      'roles__senator_rank')) +
                    list(
                        Person.objects.filter(
                            roles__current=True,
                            roles__state=state,
                            roles__district=district,
                            roles__role_type=RoleType.representative))]
    }
Exemplo n.º 8
0
def get_vote_matrix(votes, filter_people=None, tqdm=lambda _: _):
    # Convert votes array to Vote instances with extra fields attached as instance fields.
    # votes is an array of tuples of the form
    # (Vote instance | Vote id, Vote slug, { extra dict info })
    # or an array of just the first part of the tuple.

    def fetch_vote(item):
        if isinstance(item, tuple):
            id, extra = item
        else:
            id = item
            extra = {}

        # Fetch vote.
        if isinstance(id, int):
            vote = Vote.objects.get(id=id)
        elif isinstance(id, Vote):
            vote = id
        else:
            import re
            m = re.match(r"^(\d+)-(\w+)/([hs])(\d+)$", id)
            if not m:
                raise Http404(id)
            congress, session, chamber, number = m.groups()
            try:
                vote = load_vote(congress, session, chamber, number)
            except Http404:
                raise ValueError("Vote ID is not valid: " + id)

        # Add additional user-supplied fields.
        for k, v in extra.items():
            setattr(vote, k, v)

        # Return
        return vote

    votes = [fetch_vote(item) for item in votes]

    # Compute totals by party, which yields a matrix like the matrix for voters
    # where the rows are parties and in each row the 'votes' key provides columns
    # for the votes.

    if not filter_people:
        party_totals = {}
        for i, vote in enumerate(votes):
            totals = vote.totals()
            for party, party_total in zip(totals['parties'],
                                          totals['party_counts']):
                pt = party_totals.setdefault(
                    party,
                    {
                        "party": party,
                        "total_votes": 0,
                        "votes": [None] * len(
                            votes
                        ),  # if this party didn't occur in prev votes, make sure we have an empty record
                    })
                pt["total_votes"] += party_total["total"]
                pt["votes"][i] = party_total
        party_totals = sorted(party_totals.values(),
                              key=lambda value: -value['total_votes'])
        party_sort_order = [
            party_total["party"] for party_total in party_totals
        ]

    # Is more than one chamber involved here?
    more_than_one_chamber = (len(set(v.chamber for v in votes)) > 1)

    # Compute the rows of the matrix.

    voters = {}
    for i, vote in enumerate(tqdm(votes)):
        for voter in vote.get_voters(filter_people=filter_people):
            if filter_people and voter.person not in filter_people: continue
            v = voters.setdefault(
                voter.person_id, {
                    "person": voter.person,
                    "total_plus": 0,
                    "total_votes": 0,
                    "votes": [None for _ in votes],
                })

            v["votes"][i] = voter
            if voter.option.key == "+":
                v["total_plus"] += 1
            if voter.option.key not in ("0", "P"):
                v["total_votes"] += 1

            # Add name info at the moment of the vote.
            from person.name import get_person_name
            voter.person.role = voter.person_role
            voter.person.role.party = voter.party  # party at this moment
            v["votes"][i].person_name = get_person_name(
                voter.person,
                firstname_position='after',
                show_district=True,
                show_title=False,
                show_type=more_than_one_chamber,
                show_party=False)

    # Choose one name & party & state-district (for sort).
    for voter in voters.values():
        names = set(v.person_name for v in voter["votes"] if v is not None)
        if len(names) == 1:
            voter["person_name"] = list(names)[0]
        else:
            voter["person_name"] = get_person_name(
                voter["person"],
                firstname_position='after',
                show_district=False,
                show_title=False,
                show_type=more_than_one_chamber,
                show_party=False)

        parties = set(v.party for v in voter["votes"] if v is not None)
        if len(parties) == 1:
            voter["party"] = list(parties)[0]
            voter["party_order"] = party_sort_order.index(voter["party"])

        roles = set(
            (v.person_role.state, str(v.person_role.role_type),
             str(v.person_role.senator_rank),
             ("%02d" %
              v.person_role.district if v.person_role.district else ""))
            for v in voter["votes"] if v is not None)
        if len(roles) == 1:
            voter["state_district"] = "-".join(list(roles)[0])

    # Default sort order.
    voters = sorted(voters.values(), key=lambda value: value['person_name'])

    return votes, party_totals if not filter_people else None, voters
def person_name(p, when):
	p.role = p.get_role_at_date(when) # set for get_person_name
	return get_person_name(p).encode("utf8")
Exemplo n.º 10
0
def person_name(p, when):
    p.role = p.get_role_at_date(when)  # set for get_person_name
    return get_person_name(p).encode("utf8")
Exemplo n.º 11
0
def bill_details(request, congress, type_slug, number):
    bill = load_bill_from_url(congress, type_slug, number)

    from person.name import get_person_name
    sponsor_name = None if not bill.sponsor else \
        get_person_name(bill.sponsor, role_date=bill.introduced_date, firstname_position='before', show_suffix=True)

    def get_reintroductions():
        reintro_prev = None
        reintro_next = None
        for reintro in bill.find_reintroductions():
            if reintro.congress < bill.congress: reintro_prev = reintro
            if reintro.congress > bill.congress and not reintro_next: reintro_next = reintro
        return reintro_prev, reintro_next

    def get_text_info():
        from models import USCSection
        from billtext import load_bill_text
        from search import parse_slip_law_number
        import re
        try:
            metadata = load_bill_text(bill, None, mods_only=True)

            # do interesting stuff with citations
            if "citations" in metadata and not settings.DEBUG:
                slip_laws = []
                statutes = []
                usc = { }
                other = []
                usc_other = USCSection(name="Other Citations", ordering=99999)
                for cite in metadata["citations"]:
                    if cite["type"] == "slip_law":
                        slip_laws.append(cite)
                        cite["bill"] = parse_slip_law_number(cite["text"])
                    elif cite["type"] == "statutes_at_large":
                        statutes.append(cite)
                    elif cite["type"] in ("usc-section", "usc-chapter"):
                        # Build a tree of title-chapter-...-section nodes so we can
                        # display the citations in context.
                        try:
                            sec_obj = USCSection.objects.get(citation=cite["key"])
                        except: # USCSection.DoesNotExist and MultipleObjectsReturned both possible
                            # create a fake entry for the sake of output
                            # the 'id' field is set to make these objects properly hashable
                            sec_obj = USCSection(id=cite["text"], name=cite["text"], parent_section=usc_other)

                        if "range_to_section" in cite:
                            sec_obj.range_to_section = cite["range_to_section"]

                        # recursively go up to the title
                        path = [sec_obj]
                        so = sec_obj
                        while so.parent_section:
                            so = so.parent_section
                            path.append(so)

                        # build a link to LII
                        if cite["type"] == "usc-section":
                            cite_link = "http://www.law.cornell.edu/uscode/text/" + cite["title"]
                            if cite["section"]:
                                cite_link += "/" + cite["section"]
                            if cite["paragraph"]: cite_link += "#" + "_".join(re.findall(r"\(([^)]+)\)", cite["paragraph"]))
                        elif cite["type"] == "usc-chapter":
                            cite_link = "http://www.law.cornell.edu/uscode/text/" + cite["title"] + "/" + "/".join(
                                (so.level_type + "-" + so.number) for so in reversed(path[:-1])
                                )
                        sec_obj.link = cite_link

                        # now pop off from the path to put the node at the right point in a tree
                        container = usc
                        while path:
                            p = path.pop(-1)
                            if p not in container: container[p] = { }
                            container = container[p]

                    else:
                        other.append(cite)

                slip_laws.sort(key = lambda x : (x["congress"], x["number"]))

                # restructure data format
                def ucfirst(s): return s[0].upper() + s[1:]
                def rebuild_usc_sec(seclist, indent=0):
                    ret = []
                    seclist = sorted(seclist.items(), key=lambda x : x[0].ordering)
                    for sec, subparts in seclist:
                        ret.append({
                            "text": (ucfirst(sec.level_type + ((" " + sec.number) if sec.number else "") + (": " if sec.name else "")) if sec.level_type else "") + (sec.name_recased if sec.name else ""),
                            "link": getattr(sec, "link", None),
                            "range_to_section": getattr(sec, "range_to_section", None),
                            "indent": indent,
                        })
                        ret.extend(rebuild_usc_sec(subparts, indent=indent+1))
                    return ret
                usc = rebuild_usc_sec(usc)

                metadata["citations"] = {
                    "slip_laws": slip_laws, "statutes": statutes, "usc": usc, "other": other,
                    "count": len(slip_laws)+len(statutes)+len(usc)+len(other) }
            return metadata
        except IOError:
            return None

    return {
        'bill': bill,
        "congressdates": get_congress_dates(bill.congress),
        "subtitle": get_secondary_bill_title(bill, bill.titles),
        "sponsor_name": sponsor_name,
        "reintros": get_reintroductions, # defer so we can use template caching
        "current": bill.congress == CURRENT_CONGRESS,
        "dead": bill.congress != CURRENT_CONGRESS and bill.current_status not in BillStatus.final_status_obvious,
        "feed": Feed.BillFeed(bill),
        "text": get_text_info,

        "care2_category_id": {
            5816: '793', # Agriculture and Food=>Health
            5840: '789', # Animals=>Animal Welfare
            5996: '794', # Civil Rights=>Human Rights
            5991: '791', # Education=>Education
            6021: '792', # Energy=>Environment & Wildlife
            6038: '792', # Environmental Protection=>Environment & Wildlife
            6053: '793', # Families=>Health
            6130: '793', # Health=>Health
            6206: '794', # Immigration=>Human Rights
            6279: '792', # Public Lands/Natural Resources=>Environment & Wildlife
            6321: '791', # Social Sciences=>Education
            6328: '793', # Social Welfare => Health
        }.get(bill.get_top_term_id(), '795') # fall back to Politics category
    }
Exemplo n.º 12
0
def person_name(id, when):
    p = Person.objects.get(id=id)
    p.role = p.get_role_at_date(when)  # set for get_person_name
    return get_person_name(p)
Exemplo n.º 13
0
def lookup_reps(request):
    from django.contrib.humanize.templatetags.humanize import ordinal
    from person.name import get_person_name

    # Get the state and district from the query string.
    try:
        state = request.GET['state']
        district = int(request.GET['district'])
        if state not in stateapportionment: raise Exception()
    except:
        return {
        }

    # Get the bill (optional) from the query string
    from bill.models import Bill
    try:
        bill = Bill.from_congressproject_id(request.GET["bill"])
    except:
        bill = None

    # Helper to get relevant committee assignments.
    from committee.models import CommitteeMember, CommitteeMemberRole
    from committee.util import sort_members
    def mention_committees_once(committeeassignments):
        # The committee assignments have been sorted first by role (i.e.
        # committees that the person is the chair of come first) and then
        # by committee name (which also puts subcommittees after committees).
        # In order to be less verbose, only mention each full committee
        # once --- take the first in each mention.
        seen = set()
        for c in committeeassignments:
            if (c.committee in seen) or (c.committee.committee in seen):
                continue
            yield c
            if c.committee.committee is not None:
                seen.add(c.committee.committee) # add main committee
            else:
                seen.add(c.committee) # add this committee

    bounds = get_district_bounds(state, district)
    return {
        "state": {
            "name": statenames[state],
            "isTerritory": stateapportionment[state] == "T",
        },
        "district": {
            "ordinal": ordinal(district) if district > 0 else "At Large",
            "bounds": {
                "center": { "latitude": bounds[0], "longitude": bounds[1] },
                "zoom": bounds[2]
            }
        },
        "members": [
            {
                "id": p.id,
                "name": get_person_name(p, role_recent=True, firstname_position="before", show_title=True, show_party=False, show_district=False),
                "name_formal": p.current_role.get_title() + " " + p.lastname,
                "url": p.get_absolute_url(),
                "type": p.current_role.get_role_type_display(),
                "description": p.current_role.get_description(),
                "party": p.current_role.party,
                "photo_url": p.get_photo_url_50() if p.has_photo() else None,
                "contact_url": (p.current_role.extra or {}).get("contact_form") or p.current_role.website,
                "phone": p.current_role.phone,
                "website": p.current_role.website,
                "pronouns": {
                    "him_her": p.him_her,
                    "his_her": p.his_her,
                    "he_she": p.he_she,
                },
                "bill-status": {
                    "cosponsor": p in bill.cosponsors.all(),
                    "committee-assignments": [
                        {
                            "committee": c.committee.fullname,
                            "role": c.get_role_display() if c.role in (CommitteeMemberRole.chair, CommitteeMemberRole.ranking_member, CommitteeMemberRole.vice_chair) else None,
                        }
                        for c in
                            mention_committees_once(
                             sort_members(
                                CommitteeMember.objects.filter(person=p, committee__in=bill.committees.all())))
                    ]
                } if bill else None,
            }
            for p in
            list(Person.objects.filter(roles__current=True, roles__state=state, roles__role_type=RoleType.senator)
              .order_by('roles__senator_rank'))
            +
            list(Person.objects.filter(roles__current=True, roles__state=state, roles__district=district, roles__role_type=RoleType.representative))
        ]
    }
Exemplo n.º 14
0
def vote_comparison_table(request, table_id, table_slug):
    # Validate URL.
    if int(table_id) != 1:
        raise Http404()
    if table_slug != "trump-nominations":
        return HttpResponseRedirect(
            "/congress/votes/compare/1/trump-nominations")

    # Get votes to show.
    votes = [
        ("115-2017/s29", {
            "title": "James Mattis to be Secretary of Defense"
        }),
        ("115-2017/s30", {
            "title": "John F. Kelly to be Secretary of Homeland Security"
        }),
        ("115-2017/s32", {
            "title":
            "Mike Pompeo to be Director of the Central Intelligence Agency"
        }),
        ("115-2017/s33", {
            "title":
            "Nikki R. Haley to be the Ambassador to the United Nations"
        }),
    ]
    voters = None

    # Fetch votes.
    def fetch_vote(id, extra):
        # Fetch vote.
        if isinstance(id, int):
            vote = Vote.objects.get(id=id)
        else:
            import re
            m = re.match(r"^(\d+)-(\w+)/([hs])(\d+)$", id)
            if not m:
                raise Http404(id)
            congress, session, chamber, number = m.groups()
            try:
                vote = load_vote(congress, session, chamber, number)
            except Http404:
                raise ValueError("Vote ID is not valid: " + id)

        # Add additional user-supplied fields.
        for k, v in extra.items():
            setattr(vote, k, v)

        # Return
        return vote

    votes = [fetch_vote(id, extra) for id, extra in votes]

    # Compute totals by party.
    party_totals = {}
    for vote in votes:
        totals = vote.totals()
        for party, party_total in zip(totals['parties'],
                                      totals['party_counts']):
            pt = party_totals.setdefault(party, {
                "party": party,
                "total_votes": 0,
                "votes": [],
            })
            pt["total_votes"] += party_total["total"]
            pt["votes"].append(party_total)
    party_totals = sorted(party_totals.values(),
                          key=lambda value: -value['total_votes'])
    party_sort_order = [party_total["party"] for party_total in party_totals]

    # Is more than one chamber in involved here?
    more_than_one_chamber = (len(set(v.chamber for v in votes)) > 1)

    # Pull voters.
    voters = {}
    for i, vote in enumerate(votes):
        for voter in vote.get_voters():
            v = voters.setdefault(
                voter.person_id, {
                    "person": voter.person,
                    "total_plus": 0,
                    "total_votes": 0,
                    "votes": [None for _ in votes],
                })

            v["votes"][i] = voter
            if voter.option.key == "+":
                v["total_plus"] += 1
            if voter.option.key not in ("0", "P"):
                v["total_votes"] += 1

            # Add name info at the moment of the vote.
            from person.name import get_person_name
            voter.person.role = voter.person_role
            voter.person.role.party = voter.party  # party at this moment
            v["votes"][i].person_name = get_person_name(
                voter.person,
                firstname_position='after',
                show_district=True,
                show_title=False,
                show_type=more_than_one_chamber,
                show_party=False)

    # Choose one name & party & state-district (for sort).
    for voter in voters.values():
        names = set(v.person_name for v in voter["votes"] if v is not None)
        if len(names) == 1:
            voter["person_name"] = list(names)[0]
        else:
            voter["person_name"] = get_person_name(
                voter["person"],
                firstname_position='after',
                show_district=False,
                show_title=False,
                show_type=more_than_one_chamber,
                show_party=False)

        parties = set(v.party for v in voter["votes"] if v is not None)
        if len(parties) == 1:
            voter["party"] = list(parties)[0]
            voter["party_order"] = party_sort_order.index(voter["party"])

        roles = set(
            (v.person_role.state, str(v.person_role.role_type),
             str(v.person_role.senator_rank),
             ("%02d" %
              v.person_role.district if v.person_role.district else ""))
            for v in voter["votes"] if v is not None)
        if len(roles) == 1:
            voter["state_district"] = "-".join(list(roles)[0])

    # Default sort order.
    voters = sorted(voters.values(), key=lambda value: value['person_name'])

    return {
        "title": "Key Trump Nominations",
        "description": "Senate votes on key Trump nominations.",
        "votes": votes,
        "party_totals": party_totals,
        "voters": voters,
        "col_width_pct": int(round(100 / (len(votes) + 1))),
    }
Exemplo n.º 15
0
def bill_details(request, congress, type_slug, number):
    if type_slug.isdigit():
        bill_type = type_slug
    else:
        try:
            bill_type = BillType.by_slug(type_slug)
        except BillType.NotFound:
            raise Http404("Invalid bill type: " + type_slug)
    
    bill = get_object_or_404(Bill, congress=congress, bill_type=bill_type, number=number)
    
    from person.name import get_person_name
    sponsor_name = None if not bill.sponsor else \
        get_person_name(bill.sponsor, role_date=bill.introduced_date, firstname_position='before', show_suffix=True)
    
    def get_reintroductions():
        reintro_prev = None
        reintro_next = None
        for reintro in bill.find_reintroductions():
            if reintro.congress < bill.congress: reintro_prev = reintro
            if reintro.congress > bill.congress and not reintro_next: reintro_next = reintro
        return reintro_prev, reintro_next
        
    def get_text_info():
        from models import USCSection
        from billtext import load_bill_text
        from search import parse_slip_law_number
        import re
        try:
            metadata = load_bill_text(bill, None, mods_only=True)
            
            # do interesting stuff with citations
            if "citations" in metadata:
                slip_laws = []
                statutes = []
                usc = { }
                other = []
                usc_other = USCSection(name="Other Citations", ordering=99999)
                for cite in metadata["citations"]:
                    if cite["type"] == "slip_law":
                        slip_laws.append(cite)
                        cite["bill"] = parse_slip_law_number(cite["text"])
                    elif cite["type"] == "statutes_at_large":
                        statutes.append(cite)
                    elif cite["type"] == "usc":
                        # build a normalized citation and a link to LII
                        cite_norm = "usc/" + cite["title"]
                        cite_link = "http://www.law.cornell.edu/uscode/text/" + cite["title"]
                        if cite["section"]:
                            cite_link += "/" + cite["section"]
                            cite_norm += "/" + cite["section"]
                        if cite["paragraph"]: cite_link += "#" + "_".join(re.findall(r"\(([^)]+)\)", cite["paragraph"]))
                        
                        # Build a tree of title-chapter-...-section nodes so we can
                        # display the citations in context.
                        try:
                            sec_obj = USCSection.objects.get(citation=cite_norm)
                        except: # USCSection.DoesNotExist and MultipleObjectsReturned both possible
                            # the 'id' field is set to make these objects properly hashable
                            sec_obj = USCSection(id=cite["text"], name=cite["text"], parent_section=usc_other)
                        
                        sec_obj.link = cite_link
                        
                        if "range_to_section" in cite:
                            sec_obj.range_to_section = cite["range_to_section"]
                        
                        # recursively go up to the title
                        path = [sec_obj]
                        while sec_obj.parent_section:
                            sec_obj = sec_obj.parent_section
                            path.append(sec_obj)
                            
                        # now pop off from the path to put the node at the right point in a tree
                        container = usc
                        while path:
                            p = path.pop(-1)
                            if p not in container: container[p] = { }
                            container = container[p]
                        
                    else:
                        other.append(cite)
                        
                slip_laws.sort(key = lambda x : (x["congress"], x["number"]))
                
                # restructure data format
                def ucfirst(s): return s[0].upper() + s[1:]
                def rebuild_usc_sec(seclist, indent=0):
                    ret = []
                    seclist = sorted(seclist.items(), key=lambda x : x[0].ordering)
                    for sec, subparts in seclist:
                        ret.append({
                            "text": (ucfirst(sec.level_type + ((" " + sec.number) if sec.number else "") + (": " if sec.name else "")) if sec.level_type else "") + (sec.name if sec.name else ""),
                            "link": getattr(sec, "link", None),
                            "range_to_section": getattr(sec, "range_to_section", None),
                            "indent": indent,
                        })
                        ret.extend(rebuild_usc_sec(subparts, indent=indent+1))
                    return ret
                usc = rebuild_usc_sec(usc)
                
                metadata["citations"] = {
                    "slip_laws": slip_laws, "statutes": statutes, "usc": usc, "other": other,
                    "count": len(slip_laws)+len(statutes)+len(usc)+len(other) }
            return metadata
        except IOError:
            return None

    return {
        'bill': bill,
        "congressdates": get_congress_dates(bill.congress),
        "subtitle": get_secondary_bill_title(bill, bill.titles),
        "sponsor_name": sponsor_name,
        "reintros": get_reintroductions, # defer so we can use template caching
        "current": bill.congress == CURRENT_CONGRESS,
        "dead": bill.congress != CURRENT_CONGRESS and bill.current_status not in BillStatus.final_status_obvious,
        "feed": Feed.BillFeed(bill),
        "text": get_text_info,
    }
Exemplo n.º 16
0
def get_vote_matrix(votes, filter_people=None, tqdm=lambda _ : _):
	# Convert votes array to Vote instances with extra fields attached as instance fields.
	# votes is an array of tuples of the form
	# (Vote instance | Vote id, Vote slug, { extra dict info })
	# or an array of just the first part of the tuple.

	def fetch_vote(item):
		if isinstance(item, tuple):
			id, extra = item
		else:
			id = item
			extra = { }

		# Fetch vote.
		if isinstance(id, int):
			vote = Vote.objects.get(id=id)
		elif isinstance(id, Vote):
			vote = id
		else:
			import re
			m = re.match(r"^(\d+)-(\w+)/([hs])(\d+)$", id)
			if not m:
				raise Http404(id)
			congress, session, chamber, number = m.groups()
			try:
				vote = load_vote(congress, session, chamber, number)
			except Http404:
				raise ValueError("Vote ID is not valid: " + id)

		# Add additional user-supplied fields.
		for k, v in extra.items():
			setattr(vote, k, v)

		# Return
		return vote

	votes = [fetch_vote(item) for item in votes]

	# Compute totals by party, which yields a matrix like the matrix for voters
	# where the rows are parties and in each row the 'votes' key provides columns
	# for the votes.

	if not filter_people:
		party_totals = { }
		for i, vote in enumerate(votes):
			totals = vote.totals()
			for party, party_total in zip(totals['parties'], totals['party_counts']):
				pt = party_totals.setdefault(party, {
					"party": party,
					"total_votes": 0,
					"votes": [None] * len(votes), # if this party didn't occur in prev votes, make sure we have an empty record
				})
				pt["total_votes"] += party_total["total"]
				pt["votes"][i] = party_total
		party_totals = sorted(party_totals.values(), key = lambda value : -value['total_votes'])
		party_sort_order = [party_total["party"] for party_total in party_totals]

	# Is more than one chamber involved here?
	more_than_one_chamber = (len(set(v.chamber for v in votes)) > 1)

	# Compute the rows of the matrix.

	voters = { }
	for i, vote in enumerate(tqdm(votes)):
		for voter in vote.get_voters(filter_people=filter_people):
			if filter_people and voter.person not in filter_people: continue
			v = voters.setdefault(voter.person_id, {
				"person": voter.person,
				"total_plus": 0,
				"total_votes": 0,
				"votes": [None for _ in votes],
			})

			v["votes"][i] = voter
			if voter.option.key == "+":
				v["total_plus"] += 1
			if voter.option.key not in ("0", "P"):
				v["total_votes"] += 1

			# Add name info at the moment of the vote.
			from person.name import get_person_name
			voter.person.role = voter.person_role
			voter.person.role.party = voter.party # party at this moment
			v["votes"][i].person_name = get_person_name(voter.person, firstname_position='after', show_district=True, show_title=False, show_type=more_than_one_chamber, show_party=False)

	# Choose one name & party & state-district (for sort).
	for voter in voters.values():
		names = set(v.person_name for v in voter["votes"] if v is not None)
		if len(names) == 1:
			voter["person_name"] = list(names)[0]
		else:
			voter["person_name"] = get_person_name(voter["person"], firstname_position='after', show_district=False, show_title=False, show_type=more_than_one_chamber, show_party=False)

		parties = set(v.party for v in voter["votes"] if v is not None)
		if len(parties) == 1:
			voter["party"] = list(parties)[0]
			voter["party_order"] = party_sort_order.index(voter["party"])

		roles = set((v.person_role.state, str(v.person_role.role_type), str(v.person_role.senator_rank), ("%02d" % v.person_role.district if v.person_role.district else "")) for v in voter["votes"] if v is not None)
		if len(roles) == 1:
			voter["state_district"] = "-".join(list(roles)[0])

	# Default sort order.
	voters = sorted(voters.values(), key = lambda value : value['person_name'])

	return votes, party_totals if not filter_people else None, voters
Exemplo n.º 17
0
 def person_name(self):
     # don't need title because it's implicit from the bill type
     from person.name import get_person_name
     return get_person_name(self.person, role_date=self.joined, firstname_position="after", show_title=False)
def person_name(id, when):
		p = Person.objects.get(id=id)
		p.role = p.get_role_at_date(when) # set for get_person_name
		return get_person_name(p)