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)
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)
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
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
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
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")
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, }, )
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, }, )
def canonical_url(obj): return pretty_url(obj)
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
def pretty_url(self): return pretty_url(self)