def do_site_search(q, allow_redirect=False, request=None): if q.strip() == "": return [] results = [] from bill.models import Bill from vote.models import Vote if "pass" in q or "fail" in q or "vote" in q: results.append({ "title": "Tracking Federal Legislation", "href": "/start", "noun": "feeds", "results": [{ "href": f.link, "label": f.title, "obj": f, "feed": f, "secondary": False } for f in ( Bill.EnactedBillsFeed(), Bill.ActiveBillsExceptIntroductionsFeed(), Bill.ComingUpFeed(), Vote.AllVotesFeed(), )] }) from haystack.query import SearchQuerySet from events.models import Feed from person.models import RoleType sqs = SearchQuerySet().using("person")\ .filter( indexed_model_name__in=["Person"], all_role_types__in=(RoleType.representative, RoleType.senator), content=q) if 'XapianEngine' not in settings.HAYSTACK_CONNECTIONS['person']['ENGINE']: # Xapian doesn't provide a 'score' so we can't do this when debugging. sqs = sqs.order_by('-is_currently_serving', '-score') results.append({ "title": "Members of Congress", "href": "/congress/members/all", "qsarg": "name", "noun": "Members of Congress", "results": [{ "href": p.object.get_absolute_url(), "label": p.object.name, "obj": p.object, "feed": p.object.get_feed(), "secondary": p.object.get_current_role() == None } for p in sqs[0:9]] }) import us results.append({ "title": "States", "href": "/congress/members", "noun": "states", "results": sorted([{ "href": "/congress/members/%s" % s, "label": us.statenames[s] } for s in us.statenames if us.statenames[s].lower().startswith(q.lower())], key=lambda p: p["label"]) }) # search committees -- name must contain all of the words in the # search query (e.g. "rules committee" should match "committee on rules") from committee.models import Committee committees_qs = Committee.objects.filter(obsolete=False) for word in q.split(" "): committees_qs = committees_qs.filter(name__icontains=word) results.append({ "title": "Congressional Committees", "href": "/congress/committees", "noun": "committees in Congress", "results": sorted([{ "href": c.get_absolute_url(), "label": c.fullname, "feed": c.get_feed(), "obj": c, "secondary": c.committee != None } for c in committees_qs], key=lambda c: c["label"]) }) from settings import CURRENT_CONGRESS from bill.search import parse_bill_citation bill = parse_bill_citation(q) congress = "__ALL__" if not bill or not allow_redirect: # query Solr w/ the boosted field from haystack.inputs import AutoQuery from haystack.query import SQ q = SearchQuerySet().using("bill").filter(indexed_model_name__in=["Bill"])\ .filter( SQ(text=AutoQuery(q)) | SQ(text_boosted=AutoQuery(q)) ) # restrict to current bills if any (at least 10) bills match q1 = q.filter(congress=CURRENT_CONGRESS) if q1.count() >= 10: q = q1 congress = str(CURRENT_CONGRESS) bills = [\ {"href": b.object.get_absolute_url(), "label": b.object.title, "obj": b.object, "feed": b.object.get_feed() if b.object.is_alive else None, "secondary": b.object.congress != CURRENT_CONGRESS } for b in q[0:9]] else: url = bill.get_absolute_url() if request.GET.get("track"): url += "#track" return HttpResponseRedirect(url) results.append({ "title": "Bills and Resolutions", "href": "/congress/bills/browse", "qsarg": "congress=%s&text" % congress, "noun": "federal bills or resolutions", "results": bills }) # subject terms, but exclude subject terms that look like committee names because # that is confusing to also see with committee results from bill.models import BillTerm, TermType results.append({ "title": "Subject Areas", "href": "/congress/bills", "noun": "subject areas", "results": [{ "href": p.get_absolute_url(), "label": p.name, "obj": p, "feed": p.get_feed(), "secondary": not p.is_top_term() } for p in BillTerm.objects.filter( name__icontains=q, term_type=TermType.new).exclude( name__contains=" Committee on ")[0:9]] }) # in each group, make sure the secondary results are placed last, but otherwise preserve order for grp in results: for i, obj in enumerate(grp["results"]): obj["index"] = i grp["results"].sort( key=lambda o: (o.get("secondary", False), o["index"])) # sort categories first by whether all results are secondary results, then by number of matches (fewest first, if greater than zero) results.sort(key=lambda c: (len([ d for d in c["results"] if d.get("secondary", False) == False ]) == 0, len(c["results"]) == 0, len(c["results"]))) return results
def do_site_search(q, allow_redirect=False): if q.strip() == "": return [] results = [] from bill.models import Bill from vote.models import Vote if "pass" in q or "fail" in q or "vote" in q: results.append({ "title": "Tracking Federal Legislation", "href": "/start", "noun": "feeds", "results": [{ "href": f.link, "label": f.title, "obj": f, "feed": f, "secondary": False } for f in ( Bill.EnactedBillsFeed(), Bill.ActiveBillsExceptIntroductionsFeed(), Bill.ComingUpFeed(), Vote.AllVotesFeed(), )] }) from haystack.query import SearchQuerySet from events.models import Feed results.append({ "title": "Members of Congress, Presidents, and Vice Presidents", "href": "/congress/members/all", "qsarg": "name", "noun": "Members of Congress, Presidents, or Vice Presidents", "results": [{ "href": p.object.get_absolute_url(), "label": p.object.name, "obj": p.object, "feed": p.object.get_feed(), "secondary": p.object.get_current_role() == None } for p in SearchQuerySet().using("person").filter( indexed_model_name__in=["Person"], content=q).order_by( '-is_currently_serving', '-score')[0:9]] }) # Skipping states for now because we might want to go to the district maps or to # the state's main page for state legislative information. #import us #results.append(("States", "/congress/members", "most_recent_role_state", "states", # sorted([{"href": "/congress/members/%s" % s, "label": us.statenames[s] } # for s in us.statenames # if us.statenames[s].lower().startswith(q.lower()) # ], key=lambda p : p["label"]))) from committee.models import Committee results.append({ "title": "Congressional Committees", "href": "/congress/committees", "noun": "committees in Congress", "results": sorted([{ "href": c.get_absolute_url(), "label": c.fullname, "feed": c.get_feed(), "obj": c, "secondary": c.committee != None } for c in Committee.objects.filter(name__icontains=q, obsolete=False) ], key=lambda c: c["label"]) }) from settings import CURRENT_CONGRESS from bill.search import parse_bill_citation bill = parse_bill_citation(q) if not bill or not allow_redirect: from haystack.inputs import AutoQuery bills = [\ {"href": b.object.get_absolute_url(), "label": b.object.title, "obj": b.object, "feed": b.object.get_feed() if b.object.is_alive else None, "secondary": b.object.congress != CURRENT_CONGRESS } for b in SearchQuerySet().using("bill").filter(indexed_model_name__in=["Bill"], content=AutoQuery(q)).order_by('-current_status_date')[0:9]] else: #bills = [{"href": bill.get_absolute_url(), "label": bill.title, "obj": bill, "secondary": bill.congress != CURRENT_CONGRESS }] return HttpResponseRedirect(bill.get_absolute_url()) results.append({ "title": "Bills and Resolutions (Federal)", "href": "/congress/bills/browse", "qsarg": "congress=__ALL__&text", "noun": "federal bills or resolutions", "results": bills }) if "states" in settings.HAYSTACK_CONNECTIONS: results.append({ "title": "State Legislation", "href": "/states/bills/browse", "qsarg": "text", "noun": "state legislation", "results": [{ "href": p.object.get_absolute_url(), "label": p.object.short_display_title, "obj": p.object, "feed": Feed(feedname="states_bill:%d" % p.object.id), "secondary": True } for p in SearchQuerySet().using('states').filter( indexed_model_name__in=["StateBill"], content=q)[0:9]] }) # subject terms, but exclude subject terms that look like committee names because # that is confusing to also see with committee results from bill.models import BillTerm, TermType results.append({ "title": "Subject Areas (Federal Legislation)", "href": "/congress/bills", "noun": "subject areas", "results": [{ "href": p.get_absolute_url(), "label": p.name, "obj": p, "feed": p.get_feed(), "secondary": not p.is_top_term() } for p in BillTerm.objects.filter( name__icontains=q, term_type=TermType.new).exclude( name__contains=" Committee on ")[0:9]] }) # in each group, make sure the secondary results are placed last, but otherwise preserve order for grp in results: for i, obj in enumerate(grp["results"]): obj["index"] = i grp["results"].sort( key=lambda o: (o.get("secondary", False), o["index"])) # sort categories first by whether all results are secondary results, then by number of matches (fewest first, if greater than zero) results.sort(key=lambda c: (len([ d for d in c["results"] if d.get("secondary", False) == False ]) == 0, len(c["results"]) == 0, len(c["results"]))) return results