def search(request):
    params = request.GET
    q = params.get('q', '')
    page = params.get('page', 1)
    fmt = params.get('format', 'html')
    raw = params.get('raw', False)
    online = params.get('online', False)
    page_size = params.get('page_size', 20)

    try:
        page = int(page)
        page_size = int(page_size)
    except __HOLE__:
        raise Http404

    # summon can't return results for pages > 50 with page size of 20
    max_pages = 50
    if page > max_pages:
        raise Http404

    api = summon.Summon(settings.SUMMON_ID, settings.SUMMON_SECRET_KEY)
    kwargs = {
        "hl": False,
        "pn": page,
        "ps": page_size,
        "fq": ['SourceType:("Library Catalog")'],
        "ff": [
            'ContentType,or',
            'Author,or',
            'Language,or',
            'Genre,or',
            'Institution,or',
            'Discipline,or',
            'SubjectTerms,or',
            'TemporalSubjectTerms,or',
            'GeographicLocations,or',
        ],
        "ho": "t",
        "light": "t",
        "raw": raw,
    }

    q, kwargs = _filter_by_pubdate(q, kwargs)

    # add to the query if they want online resources only
    if online:
        if q:
            q += " AND"
        q += " lccallnum:('gw electronic' OR 'shared+electronic'" + \
            " OR 'e-resources' OR 'e-govpub' OR 'streaming')"

    # add selected facets to the query
    for facet in params.getlist('facet'):
        if ':' not in facet:
            continue
        facet_field, facet_value = facet.split(':', 1)

        if 'fvf' not in kwargs:
            kwargs['fvf'] = []

        # TODO: maybe summoner should do these escapes somehow?
        def escape(m):
            return '\\' + m.group(1)
        facet_value = re.sub('([,:\()${}])', escape, facet_value)

        kwargs['fvf'].append('%s,%s,false' % (facet_field, facet_value))

        # add Library facet field if user is faceting by Institution
        if facet_field == 'Institution' and 'Library,or' not in kwargs['ff']:
            kwargs['ff'].append('Library,or')

    if fmt == "html":
        kwargs['for_template'] = True

    # catch and retry up to MAX_ATTEMPTS times if we get errors
    # from the Summon API?
    retries = 0
    while True:
        try:
            search_results = api.search(q, **kwargs)
            break
        except requests.HTTPError as error:
            retries += 1
            if retries <= settings.SER_SOL_API_MAX_ATTEMPTS:
                time.sleep(1)
                continue
            else:
                logger.exception('unable to search Summon (3 tries): %s' %
                                 error)
                return error500(request)

    if not raw:
        search_results = _remove_facets(search_results)
        search_results = _reorder_facets(search_results)
        search_results = _remove_active_facets(request, search_results)
        search_results = _format_facets(request, search_results)

    # json-ld
    if fmt == "json":
        return HttpResponse(
            json.dumps(search_results, indent=2),
            content_type='application/json'
        )

    # raw summon results
    elif raw:
        if settings.DEBUG:
            return HttpResponse(
                json.dumps(search_results, indent=2),
                content_type='application/json'
            )
        else:
            # don't serve as a Summon proxy in production!
            return HttpResponse('Unauthorized', status=401)

    # default to a regular html web page
    else:
        # TODO: pull out page link generation so it can be tested
        # how many pagination links to display
        page_links = 5

        # the first page number in the pagination links
        page_range_start = ((page - 1) / page_links) * page_links + 1

        # the last page number + 1 in the pagination links
        # this is used in a range() below so it is offset by 1
        page_range_end = page_range_start + page_links

        # don't display page links that we can't get
        actual_pages = search_results['totalResults'] / page_size + 1
        if actual_pages <= page_range_end:
            page_range_end = actual_pages + 1

        # build page links as a list of tuples (page number, url)
        page_range = []
        page_query = request.GET.copy()
        for n in range(page_range_start, page_range_end):
            page_query['page'] = n
            page_range.append((n, page_query.urlencode()))

        # create links for going to the next set of page results
        next_page_range = prev_page_range = None
        if page_range_end - 1 < actual_pages \
                and page_range_end - 1 < max_pages:
            page_query['page'] = page_range_end
            next_page_range = page_query.urlencode()
        if page_range_start > page_links:
            page_query['page'] = page_range_start - 1
            prev_page_range = page_query.urlencode()

        return render(request, 'search.html', {
            "q": params.get('q'),
            "original_facets": params.getlist('facet'),
            "active_facets": _get_active_facets(request),
            "page": page,
            "page_range": page_range,
            "next_page_range": next_page_range,
            "prev_page_range": prev_page_range,
            "search_results": search_results,
            "debug": settings.DEBUG,
            "online": online,
            "json_url": request.get_full_path() + "&format=json",
            "raw_url": request.get_full_path() + "&raw=true",
            "max_subjects": settings.MAX_SUBJECTS,
        })
dataset/ETHPy150Open gwu-libraries/launchpad/lp/ui/views.py/search