def test_canonicalize_committee(client):
    o = Organization.objects.get(name="Wizards")
    url = pretty_url(o).replace("wizards", "xyz")
    assert "xyz" in url
    resp = client.get(url)
    assert resp.status_code == 301
    assert resp.url == pretty_url(o)
Beispiel #2
0
def test_canonicalize_person(client):
    p = Person.objects.get(name="Amanda Adams")
    url = pretty_url(p).replace("amanda", "xyz")
    assert "xyz" in url
    resp = client.get(url)
    assert resp.status_code == 301
    assert resp.url == pretty_url(p)
Beispiel #3
0
def legislator_fallback(request, legislator_id):
    try:
        p = Person.objects.get(
            identifiers__scheme="legacy_openstates",
            identifiers__identifier=legislator_id,
        )
        return redirect(pretty_url(p), permanent=True)
    except Person.DoesNotExist:
        return fallback(request)
def test_committee_detail(client, django_assert_num_queries):
    o = Organization.objects.get(name="Wizards")
    with django_assert_num_queries(9):
        resp = client.get(pretty_url(o))
    assert resp.status_code == 200
    assert resp.context["state"] == "ak"
    assert resp.context["state_nav"] == "committees"
    org = resp.context["committee"]
    assert org.name == "Wizards"
    assert len(resp.context["memberships"]) == 5
Beispiel #5
0
def test_person_view_retired(client, django_assert_num_queries):
    p = Person.objects.get(name="Rhonda Retired")
    # fewer views, we don't do the bill queries
    with django_assert_num_queries(9):
        resp = client.get(pretty_url(p))
    assert resp.status_code == 200
    assert resp.context["state"] == "ak"
    assert resp.context["state_nav"] == "legislators"
    person = resp.context["person"]
    assert person.name == "Rhonda Retired"
    assert resp.context["retired"] is True
 def site_url(self):
     if self.subscription_type == "query":
         queryobj = {
             "query": self.query,
             "subjects": self.subjects or [],
             "status": self.status or [],
         }
         if self.classification:
             queryobj["classification"] = self.classification
         if self.session:
             queryobj["session"] = self.session
         if self.chamber:
             queryobj["chamber"] = self.chamber
         if self.sponsor_id:
             queryobj["sponsor_id"] = self.sponsor_id
         querystr = urllib.parse.urlencode(queryobj, doseq=True)
         if self.state:
             return f"/{self.state}/bills/?{querystr}"
         else:
             return f"/search/?{querystr}"
     elif self.subscription_type == "bill":
         return pretty_url(self.bill)
     elif self.subscription_type == "sponsor":
         return pretty_url(self.sponsor)
def _people_from_lat_lon(lat, lon):
    PERSON_GEO_QUERY = """{
      people(latitude: %s, longitude: %s, first: 15) {
        edges {
          node {
            id
            image
            name
            currentMemberships(classification: ["upper", "lower", "legislature", "party"]) {
              post {
                label
                division { id }
              }
              organization {
                classification
                name
                jurisdictionId
              }
            }
          }
        }
      }
    }"""
    resp = schema.execute(PERSON_GEO_QUERY % (lat, lon))

    nodes = [node["node"] for node in resp.data["people"]["edges"]]
    people = []
    for node in nodes:
        person = {
            "name": node["name"],
            "id": node["id"],
            "image": node["image"],
            "pretty_url": pretty_url(node),
        }
        for m in node["currentMemberships"]:
            if m["organization"]["classification"] == "party":
                person["party"] = m["organization"]["name"]
            else:
                person["chamber"] = m["organization"]["classification"]
                person["district"] = m["post"]["label"]
                person["division_id"] = m["post"]["division"]["id"]
                person["jurisdiction_id"] = m["organization"]["jurisdictionId"]
                person["level"] = (
                    "federal" if m["organization"]["jurisdictionId"]
                    == "ocd-jurisdiction/country:us/government" else "state")
        people.append(person)

    return people
Beispiel #8
0
def csv_view(request, slug):
    bundle = Bundle.objects.get(slug=slug)

    response = HttpResponse(content_type="text/csv")
    response["Content-Disposition"] = f'attachment; filename="{slug}.csv"'

    writer = csv.DictWriter(
        response,
        fieldnames=[
            "state",
            "session",
            "identifier",
            "title",
            "introduced",
            "latest_action_description",
            "latest_action_date",
            "openstates_url",
        ],
    )
    writer.writeheader()

    for bill in (bundle.bills.all().select_related(
            "legislative_session__jurisdiction", ).order_by(
                F("first_action_date").desc(nulls_last=True))):
        writer.writerow({
            "state":
            bill.legislative_session.jurisdiction.name,
            "session":
            bill.legislative_session.identifier,
            "identifier":
            bill.identifier,
            "title":
            bill.title,
            "introduced":
            bill.first_action_date,
            "latest_action_date":
            bill.latest_action_date,
            "latest_action_description":
            bill.latest_action_description,
            "openstates_url":
            "https://openstates.org/" + pretty_url(bill),
        })
    return response
def test_person_view(client, django_assert_num_queries):
    p = Person.objects.get(name="Amanda Adams")
    with django_assert_num_queries(9):
        resp = client.get(pretty_url(p))
    assert resp.status_code == 200
    assert resp.context["state"] == "ak"
    assert resp.context["state_nav"] == "legislators"
    person = resp.context["person"]
    assert person.name == "Amanda Adams"
    assert person.current_role == {
        "chamber": "lower",
        "district": 1,
        "division_id": "ocd-division/country:us/state:ak/sldl:1",
        "state": "ak",
        "role": "Representative",
        "party": "Republican",
    }
    assert len(person.sponsored_bills) == 2
    assert len(person.vote_events) == 1
    assert resp.context["retired"] is False
Beispiel #10
0
    def get(self, request, state):
        bills, form = self.get_bills(request, state)
        host = request.get_host()
        link = "https://{}{}?{}".format(
            host,
            reverse("bills", kwargs={"state": state}),
            request.META["QUERY_STRING"],
        )
        feed_url = "https://%s%s?%s" % (
            host,
            reverse("bills_feed", kwargs={"state": state}),
            request.META["QUERY_STRING"],
        )
        description = f"{state.upper()} Bills"
        if form["session"]:
            description += f" ({form['session']})"
        # TODO: improve RSS description
        feed = Rss201rev2Feed(
            title=description,
            link=link,
            feed_url=feed_url,
            ttl=360,
            description=description,
        )
        for item in bills[:100]:
            link = "https://{}{}".format(host, pretty_url(item))
            try:
                description = f"""{item.title}<br />
                          Latest Action: {item.billstatus.latest_action_description}
                          <i>{item.billstatus.latest_action_date}</i>"""
            except Bill.billstatus.RelatedObjectDoesNotExist:
                description = item.title

            feed.add_item(
                title=item.identifier,
                link=link,
                unique_id=link,
                description=description,
            )
        return HttpResponse(feed.writeString("utf-8"),
                            content_type="application/xml")
Beispiel #11
0
def committee(request, state, committee_id):
    ocd_org_id = decode_uuid(committee_id, "organization")
    org = get_object_or_404(Organization.objects.all(), pk=ocd_org_id)

    # canonicalize the URL
    canonical_url = pretty_url(org)
    if request.path != canonical_url:
        return redirect(canonical_url, permanent=True)

    # because there are memberships without person records, we need to do this
    # piecemeal, we'll grab the people and memberships separately and combine them
    memberships = sorted(
        org.memberships.filter(end_date="").select_related("post"),
        key=_role_sort_key)

    members = {
        p.id: p
        for p in Person.objects.filter(memberships__in=memberships).
        annotate(committee_role=F("memberships__role")).prefetch_related(
            "memberships", "memberships__organization", "memberships__post")
    }

    for membership in memberships:
        if membership.person_id:
            membership.member = members[membership.person_id]

    return render(
        request,
        "public/views/committee.html",
        {
            "state": state,
            "state_nav": "committees",
            "committee": org,
            "memberships": memberships,
        },
    )
Beispiel #12
0
def person(request, person_id):
    SPONSORED_BILLS_TO_SHOW = 4
    RECENT_VOTES_TO_SHOW = 3

    try:
        ocd_person_id = decode_uuid(person_id)
    except ValueError:
        ocd_person_id = (
            person_id  # will be invalid and raise 404, but useful in logging later
        )
    person = get_object_or_404(
        Person.objects.prefetch_related("memberships__organization"), pk=ocd_person_id,
    )

    # to display district in front of district name, or not?
    district_maybe = ""

    # canonicalize the URL
    canonical_url = pretty_url(person)
    if request.path != canonical_url:
        return redirect(canonical_url, permanent=True)

    state = person.current_role["state"]
    if not state:
        #  this breaks if they held office in two states, but we don't really worry about that
        for m in person.memberships.all():
            if m.organization.classification in ("upper", "lower", "legislature"):
                state = jid_to_abbr(m.organization.jurisdiction_id)
        retired = True
    else:
        retired = False
        # does it start with a number?
        if str(person.current_role["district"])[0] in "0123456789":
            district_maybe = "District"
    person.all_contact_details = person.contact_details.order_by("note")

    person.sponsored_bills = list(
        Bill.objects.all()
        .select_related("legislative_session", "legislative_session__jurisdiction",)
        .filter(sponsorships__person=person)
        .order_by("-created_at", "id")[:SPONSORED_BILLS_TO_SHOW]
    )

    person.committee_memberships = person.memberships.filter(
        organization__classification="committee"
    ).all()

    votes = person.votes.all().select_related("vote_event", "vote_event__bill")[
        :RECENT_VOTES_TO_SHOW
    ]
    person.vote_events = []
    for vote in votes:
        vote_event = vote.vote_event
        vote_event.legislator_vote = vote
        person.vote_events.append(vote_event)

    return render(
        request,
        "public/views/legislator.html",
        {
            "state": state,
            "person": person,
            "state_nav": "legislators",
            "retired": retired,
            "district_maybe": district_maybe,
        },
    )
Beispiel #13
0
def canonical_url(obj):
    return pretty_url(obj)
Beispiel #14
0
def test_person_view_invalid_uuid(client, django_assert_num_queries):
    p = Person.objects.get(name="Rhonda Retired")
    resp = client.get(pretty_url(p)[:-1] +
                      "abcdefghij/")  # this won't be a valid pretty UUID
    assert resp.status_code == 404
Beispiel #15
0
 def pretty_url(self):
     return pretty_url(self)