Beispiel #1
0
    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
Beispiel #2
0
    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
Beispiel #3
0
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,
        },
    )
Beispiel #4
0
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"