def get_bills(self, request, state): jid = abbr_to_jid(state) bills = Bill.objects.all().select_related( "legislative_session", "legislative_session__jurisdiction", "billstatus") bills = bills.filter(legislative_session__jurisdiction_id=jid) # query parameter filtering query = request.GET.get("query", "") chamber = request.GET.get("chamber") session = request.GET.get("session") sponsor = request.GET.get("sponsor") classification = request.GET.get("classification") q_subjects = request.GET.getlist("subjects") status = request.GET.getlist("status") form = { "query": query, "chamber": chamber, "session": session, "sponsor": sponsor, "classification": classification, "subjects": q_subjects, "status": status, } if query: if re.match(r"\w{1,3}\s*\d{1,5}", query): bills = bills.filter(identifier=fix_bill_id(query)) else: bills = bills.filter(searchable__search_vector=SearchQuery( query, search_type="web", config="english")) if chamber: bills = bills.filter(from_organization__classification=chamber) if session: bills = bills.filter(legislative_session__identifier=session) if sponsor: bills = bills.filter(sponsorships__person_id=sponsor) if classification: bills = bills.filter(classification__contains=[classification]) if q_subjects: bills = bills.filter(subject__overlap=q_subjects) if "passed-lower-chamber" in status: bills = bills.filter( actions__classification__contains=["passage"], actions__organization__classification="lower", ) elif "passed-upper-chamber" in status: bills = bills.filter( actions__classification__contains=["passage"], actions__organization__classification="upper", ) elif "signed" in status: bills = bills.filter( actions__classification__contains=["executive-signature"]) bills = bills.order_by("-billstatus__latest_action_date") return bills, form
def resolve_bill( self, info, id=None, jurisdiction=None, session=None, identifier=None, openstatesUrl=None, ): bill = None if jurisdiction and session and identifier: query = dict(legislative_session__identifier=session, identifier=identifier) query.update(jurisdiction_query(jurisdiction)) bill = Bill.objects.get(**query) if id: bill = Bill.objects.get(id=id) if openstatesUrl: # remove domain, start and end slashes path = urlparse(openstatesUrl).path.strip("/") # parse openstatesUrl into state abbr, session, and bill_id m = re.match( r"(?P<abbr>\w+)/bills/(?P<session>.+)/(?P<bill_id>.+)", path) if m: jid = abbr_to_jid(m["abbr"]) identifier = fix_bill_id(m["bill_id"]) session = m["session"] # query Bill with components # (this bit taken from def bill in views/bills.py) bill = Bill.objects.select_related( "legislative_session", "legislative_session__jurisdiction", "from_organization", ).get( legislative_session__jurisdiction_id=jid, legislative_session__identifier=session, identifier=identifier, ) else: raise ValueError( "Unable to parse openstatesUrl. openstatesUrl may be malformed." ) if not bill: raise ValueError( "must either pass 'id', 'openstatesUrl', or 'jurisdiction', " "'session', and 'identifier' together") return bill
def bill(request, state, session, bill_id): # canonicalize without space if " " in bill_id: return redirect("bill", state, session, bill_id.replace(" ", ""), permanent=True) jid = abbr_to_jid(state) identifier = fix_bill_id(bill_id) try: bill = Bill.objects.select_related( "legislative_session", "legislative_session__jurisdiction", "from_organization", ).get( legislative_session__jurisdiction_id=jid, legislative_session__identifier=session, identifier=identifier, ) except Bill.DoesNotExist: # try to find the asset in S3 request.path = request.path.replace(bill_id, identifier) return fallback(request) # sponsorships, attach people manually sponsorships = list(bill.sponsorships.all()) sponsor_people = { p.id: p for p in Person.objects.filter( id__in=[s.person_id for s in sponsorships if s.person_id]).prefetch_related( "memberships", "memberships__organization", "memberships__post") } for s in sponsorships: s.person = sponsor_people.get(s.person_id) related_entities = Prefetch( "related_entities", BillActionRelatedEntity.objects.all().select_related( "person", "organization"), ) actions = list(bill.actions.all().select_related( "organization").prefetch_related(related_entities).order_by("-date")) votes = list(bill.votes.all().select_related( "organization")) # .prefetch_related('counts') # stage calculation # get other chamber name chambers = { c.classification: c.name for c in get_chambers_from_abbr(state) } second_chamber = None if len(chambers ) > 1 and bill.from_organization.classification != "legislature": second_chamber = { "upper": chambers["lower"], "lower": chambers["upper"] }[bill.from_organization.classification] stages = compute_bill_stages(actions, bill.from_organization.name, second_chamber) versions = list(bill.versions.order_by("-date").prefetch_related("links")) documents = list( bill.documents.order_by("-date").prefetch_related("links")) try: sorted_links = sorted(versions[0].links.all(), key=_document_sort_key) read_link = sorted_links[0].url except IndexError: read_link = None return render( request, "public/views/bill.html", { "state": state, "state_nav": "bills", "unicameral": state in ("dc", "ne"), "bill": bill, "sponsorships": sponsorships, "actions": actions, "stages": stages, "votes": votes, "versions": versions, "documents": documents, "read_link": read_link, }, )
def test_fix_bill_id(): assert fix_bill_id("HB1") == "HB 1" assert fix_bill_id("HB 0001") == "HB 1" assert fix_bill_id("SJRA") == "SJR A"