Ejemplo n.º 1
0
def text_to_html(value,
                 *,
                 capitalize_first=False,
                 format_links=False,
                 preserve_line_breaks=False,
                 open_links_in_new_tab=False,
                 **kwargs):
    """Convert a string to a HTML string, optionally modifying it first.

    :param bool capitalize_first: If True, the first letter of any text will be capitalized
    :param bool format_links: If True any HTTP URLs in any text will be turned into HTML <a> elements
    :param bool preserve_line_breaks: If True HTTP newline sequences (\\r\\n) will be turned into HTML <br> elements
    :param bool open_links_in_new_tab: If True formatted HTTP URL <a> elements will open in a new tab
    """
    if capitalize_first is True:
        value = filters.capitalize_first(value)

    if format_links is True:
        value = filters.format_links(value, open_links_in_new_tab)

    if preserve_line_breaks is True:
        # replace_newlines_with_breaks escapes its input anyway
        # so wrapping with Markup here is fine.
        value = Markup(filters.replace_newlines_with_breaks(value))

    return escape(value)
Ejemplo n.º 2
0
 def test_capitalize_first_for_non_strings(self):
     assert capitalize_first(5) == 5
     assert capitalize_first(None) is None
     assert capitalize_first(True) is True
     assert capitalize_first(False) is False
     assert capitalize_first(['list', 'of', 'strings']) == ['List', 'Of', 'Strings']
     assert capitalize_first([{'list': 'of'}, 'things']) == [{'list': 'of'}, 'Things']
     assert capitalize_first({'this': 'thing'}) == {'this': 'thing'}
     assert capitalize_first('https://www.example.com') == 'https://www.example.com'
Ejemplo n.º 3
0
 def test_capitalize_first_for_short_strings(self):
     assert capitalize_first('') == ''
     assert capitalize_first('a') == 'A'
     assert capitalize_first('B') == 'B'
     assert capitalize_first('+') == '+'
Ejemplo n.º 4
0
 def test_capitalise_first_for_strings(self):
     assert capitalize_first('lowercase') == 'Lowercase'
     assert capitalize_first('UPPERCASE') == 'UPPERCASE'
     assert capitalize_first('_lower') == '_lower'
     assert capitalize_first('cAMELcASE??') == 'CAMELcASE??'
Ejemplo n.º 5
0
def list_opportunities(framework_family):
    frameworks = data_api_client.find_frameworks()['frameworks']
    frameworks = [v for v in frameworks if v['framework'] == framework_family]
    framework = get_latest_live_framework_or_404(frameworks, framework_family)

    abort_if_not_further_competition_framework(framework)

    lots_by_slug = get_lots_by_slug(framework)
    current_lot_slug = get_valid_lot_from_args_or_none(request.args,
                                                       lots_by_slug)
    content_manifest = content_loader.get_manifest(framework['slug'],
                                                   'briefs_search_filters')

    filters = filters_for_lot(current_lot_slug,
                              content_manifest,
                              all_lots=framework['lots'])

    clean_request_query_params = clean_request_args(request.args,
                                                    filters.values(),
                                                    lots_by_slug)

    try:
        if int(request.args.get('page', 1)) <= 0:
            abort(404)
    except ValueError:
        abort(404)

    index = 'briefs-digital-outcomes-and-specialists'
    doc_type = 'briefs'
    updated_request_args = None

    # This will exclude anything with a 'withdrawn' status
    if 'statusOpenClosed' not in clean_request_query_params.keys():
        updated_request_args = MultiDict([('statusOpenClosed', 'open'),
                                          ('statusOpenClosed', 'closed')])
        updated_request_args.update(clean_request_query_params)

    search_api_response = search_api_client.search(
        index=index,
        doc_type=doc_type,
        **build_search_query(
            updated_request_args
            if updated_request_args else clean_request_query_params,
            filters.values(), content_manifest, lots_by_slug))

    # Convert the values of certain attributes to their label counterparts
    content = content_loader.get_manifest(framework['slug'],
                                          'briefs_search_filters')
    for brief in search_api_response['documents']:
        if brief.get('specialistRole'):
            brief['specialistRole'] = content.summary(brief).get_question(
                'specialistRole').value
        brief['location'] = content.summary(brief).get_question(
            'location').value

    search_results_obj = SearchResults(
        search_api_response,
        lots_by_slug,
        highlight_fields=frozenset(('summary', )),
    )

    # Get the results per page from the Search API meta data (or fall back to Buyer FE config setting)
    results_per_page = search_api_response['meta'].get(
        'results_per_page', current_app.config["DM_SEARCH_PAGE_SIZE"])

    # Get prev/next link info and number of pages
    pagination_config = pagination(search_results_obj.total, results_per_page,
                                   get_page_from_request(request))

    search_summary = SearchSummary(search_api_response['meta']['total'],
                                   clean_request_query_params.copy(),
                                   filters.values(), lots_by_slug)

    category_filter_group = filters.pop(
        'categories') if 'categories' in filters else None
    lots = [lot for lot in framework['lots'] if lot['allowsBrief']]

    view_name = 'list_opportunities'
    selected_category_tree_filters = build_lots_and_categories_link_tree(
        framework, lots, category_filter_group, request, updated_request_args
        if updated_request_args else clean_request_query_params,
        content_manifest, doc_type, index,
        Href(
            url_for('.{}'.format(view_name),
                    framework_family=framework['framework'])),
        search_api_client)

    filter_form_hidden_fields_by_name = {
        f["name"]: f
        for f in selected_category_tree_filters[1:]
    }
    current_lot = lots_by_slug.get(current_lot_slug)

    set_filter_states(filters.values(), request)

    for filter_groups in filters.values():
        for filter_instance in filter_groups['filters']:
            if 'label' in filter_instance:
                filter_instance['label'] = capitalize_first(
                    filter_instance['label'])
                filter_instance['text'] = capitalize_first(
                    filter_instance['label'])
            filter_instance['attributes'] = {
                'aria-controls': 'search-summary-accessible-hint-wrapper'
            }

    clear_filters_url = get_request_url_without_any_filters(
        request, filters, view_name, framework_family=framework_family)
    search_query = query_args_for_pagination(clean_request_query_params)

    template_args = dict(
        briefs=search_results_obj.search_results,
        category_tree_root=selected_category_tree_filters[0],
        clear_filters_url=clear_filters_url,
        current_lot=current_lot,
        doc_type=doc_type,
        filters=filters.values(),
        filter_form_hidden_fields=filter_form_hidden_fields_by_name.values(),
        form_action=url_for('.list_opportunities',
                            framework_family=framework_family),
        framework=framework,
        framework_family=framework['framework'],
        framework_family_name='Digital Outcomes and Specialists',
        lot_names=tuple(lot['name'] for lot in lots_by_slug.values()
                        if lot['allowsBrief']),
        outcomes={
            'awarded': 'awarded',
            'cancelled': 'cancelled',
            'closed': 'awaiting outcome',
            'unsuccessful': 'no suitable suppliers'
        },
        pagination=pagination_config,
        search_keywords=get_keywords_from_request(request),
        search_query=search_query,
        summary=search_summary.markup(),
        total=search_results_obj.total,
        view_name=view_name,
    )

    if request.args.get('live-results'):
        from flask import jsonify

        live_results_dict = {
            "results": {
                "selector":
                "#js-dm-live-search-results",
                "html":
                render_template("search/_results_wrapper.html",
                                **template_args)
            },
            "categories": {
                "selector":
                "#js-dm-live-search-categories",
                "html":
                render_template("search/_categories_wrapper.html",
                                **template_args)
            },
            "summary": {
                "selector": "#js-dm-live-search-summary",
                "html": render_template("search/_summary.html",
                                        **template_args)
            },
            "summary-accessible-hint": {
                "selector":
                "#js-dm-live-search-summary-accessible-hint",
                "html":
                render_template("search/_summary_accessible_hint.html",
                                **template_args)
            },
            "filter-title": {
                "selector":
                "#js-dm-live-filter-title",
                "html":
                render_template("search/_filter_title.html", **template_args)
            },
        }

        return jsonify(live_results_dict)

    return render_template('search/briefs.html', **template_args)