예제 #1
0
def get_transparency_stats(person, role, stats, congress, startdate, enddate):
	global transparency_bills
	if not transparency_bills:
		transparency_bills = []
		for line in open("analysis/transparency-bills.txt"):
			bill = Bill.from_congressproject_id(re.split("\s", line)[0])
			if bill.congress != congress: continue
			transparency_bills.append(bill)

	# which bills are in the right chamber?
	plausible_bills = []
	for bill in transparency_bills:
		if BillType.by_value(bill.bill_type).chamber == RoleType.by_value(role.role_type).congress_chamber:
			plausible_bills.append(bill)

	# did person sponsor any of these within this session?
	sponsored = []
	for bill in transparency_bills:
		if startdate <= bill.introduced_date <= enddate and bill.sponsor == person:
			sponsored.append(bill)

	# did person cosponsor any of these within this session?
	cosponsored = []
	for cosp in Cosponsor.objects.filter(person=person, bill__in=transparency_bills, joined__gte=startdate, joined__lte=enddate):
		cosponsored.append(cosp.bill)

	stats["transparency-bills"] = {
		"value": len(sponsored)*3 + len(cosponsored),
		"sponsored": make_bill_entries(sponsored),
		"cosponsored": make_bill_entries(cosponsored),
		"num_bills": len(plausible_bills),
		"chamber": RoleType.by_value(role.role_type).congress_chamber,
	}
예제 #2
0
 def fixup_item(item):
     item = dict(item)
     if item["my_ratio"] * item["other_ratio"] > .9:
         item["identical"] = True
     item["other"] = Bill.from_congressproject_id(item["other"])
     item["other_ratio"] *= 100
     return item
예제 #3
0
 def fixup_item(item):
     item = dict(item)
     if item["my_ratio"] * item["other_ratio"] > .9:
         item["identical"] = True
     item["other"] = Bill.from_congressproject_id(item["other"])
     item["other_ratio"] *= 100
     return item
예제 #4
0
def dump_reactions(request):
    from django.db.models import Count
    from website.models import Reaction
    from collections import defaultdict, OrderedDict
    from website.models import Bill

    # Get subjects with the most users reacting.
    reactions = Reaction.objects.values_list("subject").annotate(
        count=Count('subject')).order_by('-count')[0:100]

    # Build ouptut.
    def emojis(subject):
        counts = defaultdict(lambda: 0)
        for r in Reaction.objects.filter(subject=subject):
            for e in (r.reaction or {}).get("emojis", []):
                counts[e] += 1
        return OrderedDict(sorted(counts.items(), key=lambda kv: -kv[1]))

    ret = [
        OrderedDict([
            ("subject", r[0]),
            ("title", Bill.from_congressproject_id(r[0][5:]).title),
            ("unique_users", r[1]),
            ("emojis", emojis(r[0])),
        ]) for r in reactions
    ]
    return HttpResponse(json.dumps(ret, indent=2),
                        content_type="application/json")
예제 #5
0
def dump_reactions(request):
    from django.db.models import Count
    from website.models import Reaction
    from collections import defaultdict, OrderedDict
    from website.models import Bill

    # Get subjects with the most users reacting.
    reactions = Reaction.objects.values_list("subject").annotate(count=Count('subject')).order_by('-count')[0:100]

    # Build ouptut.
    def emojis(subject):
        counts = defaultdict(lambda : 0)
        for r in Reaction.objects.filter(subject=subject):
            for e in (r.reaction or {}).get("emojis", []):
                counts[e] += 1
        return OrderedDict(sorted(counts.items(), key = lambda kv : -kv[1]))
    
    ret = [
        OrderedDict([
            ("subject", r[0]),
            ("title", Bill.from_congressproject_id(r[0][5:]).title),
            ("unique_users", r[1]),
            ("emojis", emojis(r[0])),
        ])
        for r in reactions
    ]
    return HttpResponse(json.dumps(ret, indent=2), content_type="application/json")
예제 #6
0
        if b2_versioncode != latest_version_code[b2_id]: continue

        # Does this record represent enough text similarity that it is worth
        # loading into the database? We'll treat this record as indicating
        # similarity if...

        # For exceedingly formulaic bills, we'll only identify identical bills.
        # Bills naming buildings etc. are formulaic and produce text similarity
        # to other bills of the same type, because the part that differs is very
        # small. So we use a very high threshold for comparison. This may not
        # be needed. I added it after seeing the analysis produce false positives,
        # but then I discovered that cmp_text_len was not being compared right in
        # the next block so this may actually not be needed to help.
        b1_ratio = round(float(b1_ratio), 3)
        b2_ratio = round(float(b2_ratio), 3)
        b1 = Bill.from_congressproject_id(b1_id)
        if  b1.title_no_number.startswith("A bill to designate ") \
         or b1.title_no_number.startswith("To designate ") \
         or b1.title_no_number.startswith("To name ") \
         or "Commemorative Coin Act" in b1.title_no_number:
            if b1_ratio * b2_ratio < .85:
                continue

        # For other bills...
        #   a) The bills are nearly identical, i.e. the ratios indicating how
        #      must text of each bill is in the other are both high, and
        #      there is some minimum amount of text in the bills so that we're
        #      sure there is substantative text at all.
        #   b) The bills are substantially similar to each other and the text
        #      in common is large enough to exclude cases where all of the
        #      substance in the bills are in the dis-similar parts.
    if b2_versioncode != latest_version_code[b2_id]: continue

    # Does this record represent enough text similarity that it is worth
    # loading into the database? We'll treat this record as indicating
    # similarity if...

    # For exceedingly formulaic bills, we'll only identify identical bills.
    # Bills naming buildings etc. are formulaic and produce text similarity
    # to other bills of the same type, because the part that differs is very
    # small. So we use a very high threshold for comparison. This may not
    # be needed. I added it after seeing the analysis produce false positives,
    # but then I discovered that cmp_text_len was not being compared right in
    # the next block so this may actually not be needed to help.
    b1_ratio = round(float(b1_ratio),3)
    b2_ratio = round(float(b2_ratio),3)
    b1 = Bill.from_congressproject_id(b1_id)
    if  b1.title_no_number.startswith("A bill to designate ") \
     or b1.title_no_number.startswith("To designate ") \
     or b1.title_no_number.startswith("To name ") \
     or b1.title_no_number.startswith("A bill for the relief of ") \
     or "Commemorative Coin Act" in b1.title_no_number:
      if b1_ratio*b2_ratio < .85:
        continue

    # For other bills...
    if is_text_incorporated(b1_ratio, b2_ratio, cmp_text_len):
      # Index this information with both bills.

      # For b2, we're saying that it (or parts of it) were enacted
      # through these other bills...
      text_incorporation[b2_id][b1_id] = {
예제 #8
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))]
    }
예제 #9
0
    # Skip if this record is for an outdated version of either bill.
    if b1_versioncode != latest_version_code[b1_id]: continue
    if b2_versioncode != latest_version_code[b2_id]: continue

    # Does this record represent enough text similarity that it is worth
    # loading into the database? We'll treat this record as indicating
    # similarity if...

    # For exceedingly formulaic bills, we'll only identify identical bills.
    # Bills naming buildings etc. are formulaic and produce text similarity
    # to other bills of the same type, because the part that differs is very
    # small. So we use a very high threshold for comparison.
    b1_ratio = round(float(b1_ratio),3)
    b2_ratio = round(float(b2_ratio),3)
    b1 = Bill.from_congressproject_id(b1_id)
    if  b1.title_no_number.startswith("A bill to designate ") \
     or b1.title_no_number.startswith("To designate ") \
     or b1.title_no_number.startswith("To name ") \
     or "Commemorative Coin Act" in b1.title_no_number:
      if b1_ratio*b2_ratio < .85:
        continue

    # For other bills...
    #   a) The bills are nearly identical, i.e. the ratios indicating how
    #      must text of each bill is in the other are both high, and
    #      there is some minimum amount of text in the bills so that we're
    #      sure there is substantative text at all.
    #   b) The bills are substantially similar to each other and the text
    #      in common is large enough to exclude cases where all of the
    #      substance in the bills are in the dis-similar parts.
예제 #10
0
def new_stakeholder(request):
    from bill.models import Bill
    related_bill = None
    if request.GET.get('bill'):
        related_bill = Bill.from_congressproject_id(request.GET['bill'])

    class NewStakehoderForm(Form):
        organization_name = CharField()
        organization_website = URLField(initial="http://")
        twitter_account = CharField(initial="@", required=False)
        if related_bill:
            position = ChoiceField(choices=[(None, '(choose)'), (1, "Support"),
                                            (0, "Neutral"), (-1, "Oppose")],
                                   required=False,
                                   label="Your organization's position on " +
                                   related_bill.display_number)
            position_statement_link = URLField(
                required=False,
                label=
                "Link to webpage or PDF containing a position statement about "
                + related_bill.display_number + " (optional)")
            position_statement_content = CharField(
                required=False,
                widget=Textarea,
                label="Paste the text of your position statement about " +
                related_bill.display_number + " (optional)")

    if request.method == "GET":
        form = NewStakehoderForm()
    else:  # POST
        form = NewStakehoderForm(request.POST)
        if form.is_valid():
            # Create a new un-verified Stakeholder object.
            stk = Stakeholder()
            stk.name = form.cleaned_data['organization_name']
            stk.website = form.cleaned_data['organization_website'] or None
            stk.twitter_handle = form.cleaned_data['twitter_account'].lstrip(
                "@") or None
            stk.save()

            # Create a new post.
            if related_bill and (
                    form.cleaned_data['position'] != ''
                    or form.cleaned_data['position_statement_link']
                    or form.cleaned_data['position_statement_content']):
                post = Post()
                post.stakeholder = stk
                if form.cleaned_data[
                        'position_statement_link'] or form.cleaned_data[
                            'position_statement_content']:
                    post.post_type = 1  # summary
                    post.link = (form.cleaned_data['position_statement_link']
                                 or None)
                    post.content = (
                        form.cleaned_data['position_statement_content']
                        or None)
                else:
                    post.post_type = 0  # positions only
                post.save()

                bp = BillPosition()
                bp.post = post
                bp.bill = related_bill
                if form.cleaned_data['position'] != '':
                    bp.position = int(form.cleaned_data['position'])
                bp.save()

            # Make this user an admin.
            stk.admins.add(request.user)

            # Go view it.
            return HttpResponseRedirect(stk.get_absolute_url())

    return render(request, "stakeholder/new.html", {
        "form": form,
        "related_bill": related_bill,
    })
예제 #11
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))
        ]
    }
예제 #12
0
def new_stakeholder_post(request):
    from bill.models import Bill
    related_bill = None
    if request.GET.get('bill'):
        related_bill = Bill.from_congressproject_id(request.GET['bill'])

    data = {}

    user_admin_of_stakeholders = request.user.stakeholder_set.all()

    class NewStakehoderForm(Form):
        if not user_admin_of_stakeholders:
            organization_name = CharField()
            organization_website = URLField(initial="http://")
            twitter_account = CharField(initial="@", required=False)
        else:
            organization = ChoiceField(choices=[
                (s.id, s.name) for s in user_admin_of_stakeholders
            ],
                                       label="Your organization")
        if related_bill:
            position = ChoiceField(choices=[(None, '(choose)'), (1, "Support"),
                                            (0, "Neutral"), (-1, "Oppose")],
                                   required=True,
                                   label="Your organization's position on " +
                                   related_bill.display_number)
            position_statement_link = URLField(
                required=False,
                label=
                "Link to webpage or PDF containing a position statement about "
                + related_bill.display_number)
            position_statement_content = CharField(
                required=True,
                widget=Textarea,
                label="Paste the text of your position statement about " +
                related_bill.display_number)


#If post already exists, update it instead of making a new one. Assumes only one of user's accounts has a statement on a given bill. Should be integrated into code below for clarity. Code added by Ben, a bad coder.

    if user_admin_of_stakeholders:
        for s in user_admin_of_stakeholders:
            for p in Post.objects.filter(stakeholder=s):
                for bp in p.bill_positions.all():
                    if bp.bill == related_bill:
                        data = {
                            'organization': (s.id, s.name),
                            'position': bp.position,
                            'position_statement_link': p.link,
                            'position_statement_content': p.content
                        }
                        if request.method == 'POST':
                            form = NewStakehoderForm(request.POST,
                                                     initial=data)
                            if form.is_valid():
                                if form.cleaned_data['position'] != '':
                                    bp.position = int(
                                        form.cleaned_data['position'])
                                p.link = form.cleaned_data[
                                    'position_statement_link']
                                p.content = form.cleaned_data[
                                    'position_statement_content']
                                bp.save()
                                p.save()
                                return HttpResponseRedirect(
                                    s.get_absolute_url())

    if request.method == "GET":
        form = NewStakehoderForm(initial=data)
    else:  # POST
        form = NewStakehoderForm(request.POST)
        if form.is_valid():
            if not user_admin_of_stakeholders:
                # Create a new un-verified Stakeholder object.
                stk = Stakeholder()
                stk.name = form.cleaned_data['organization_name']
                stk.website = form.cleaned_data['organization_website'] or None
                stk.twitter_handle = form.cleaned_data[
                    'twitter_account'].lstrip("@") or None
                stk.save()

                # Make this user an admin.
                stk.admins.add(request.user)
            else:
                # Get an existing Stakeholder that they are the admin of.
                stk = get_object_or_404(Stakeholder,
                                        id=form.cleaned_data['organization'])
                if request.user not in stk.admins.all():
                    # Invalid. Get out of here.
                    return HttpResponseRedirect(stk.get_absolute_url())

            # Create a new post if this page is for a related bill and a position,
            # link, or statement are provided.
            if related_bill and (
                    form.cleaned_data['position'] != ''
                    or form.cleaned_data['position_statement_link']
                    or form.cleaned_data['position_statement_content']):
                # Create a new Post object.
                post = Post()
                post.stakeholder = stk
                if form.cleaned_data[
                        'position_statement_link'] or form.cleaned_data[
                            'position_statement_content']:
                    post.post_type = 1  # summary
                    post.link = (form.cleaned_data['position_statement_link']
                                 or None)
                    post.content = (
                        form.cleaned_data['position_statement_content']
                        or None)
                else:
                    post.post_type = 0  # positions only
                post.save()

                # Attach a BillPosition to the Post.
                bp = BillPosition()
                bp.post = post
                bp.bill = related_bill
                if form.cleaned_data['position'] != '':
                    bp.position = int(form.cleaned_data['position'])
                bp.save()

            # Go view it.
            return HttpResponseRedirect(stk.get_absolute_url())

    return render(request, "stakeholder/new.html", {
        "form": form,
        "related_bill": related_bill,
    })