Пример #1
0
def plant_name_suggestions_view(request):
    """Return some suggestions for plant name input."""
    MAX_RESULTS = 10
    query = request.GET.get('q', '').lower()
    query = clean_input_string(query)

    suggestions = []
    if query != '':
        regex = query_regex(query)

        # Make a variation for checking at the start of the string.
        regex_at_start = '^%s' % regex

        # First look for suggestions that match at the start of the
        # query string.
        suggestions = list(PlantNameSuggestion.objects.filter(
            name__iregex=regex_at_start).exclude(name=query).
            order_by('name').values_list('name', flat=True)[:MAX_RESULTS])

        # If fewer than the maximum number of suggestions were found,
        # try finding some additional ones that match anywhere in the
        # query string.
        remaining_slots = MAX_RESULTS - len(suggestions)
        if remaining_slots > 0:
            more_suggestions = list(PlantNameSuggestion.objects.filter(
                name__iregex=regex).exclude(name__iregex=regex_at_start).
                order_by('name').values_list('name', flat=True)[:MAX_RESULTS])
            more_suggestions = list(more_suggestions)[:remaining_slots]
            suggestions.extend(more_suggestions)

    return HttpResponse(json.dumps(suggestions),
        content_type='application/json; charset=utf-8')
Пример #2
0
def plant_name_suggestions_view(request):
    """Return some suggestions for plant name input."""
    MAX_RESULTS = 10
    query = request.GET.get('q', '').lower()
    query = clean_input_string(query)

    suggestions = []
    if query != '':
        regex = query_regex(query)

        # Make a variation for checking at the start of the string.
        regex_at_start = '^%s' % regex

        # First look for suggestions that match at the start of the
        # query string.
        suggestions = list(
            PlantNameSuggestion.objects.filter(
                name__iregex=regex_at_start).exclude(
                    name=query).order_by('name').values_list(
                        'name', flat=True)[:MAX_RESULTS])

        # If fewer than the maximum number of suggestions were found,
        # try finding some additional ones that match anywhere in the
        # query string.
        remaining_slots = MAX_RESULTS - len(suggestions)
        if remaining_slots > 0:
            more_suggestions = list(
                PlantNameSuggestion.objects.filter(name__iregex=regex).exclude(
                    name__iregex=regex_at_start).order_by('name').values_list(
                        'name', flat=True)[:MAX_RESULTS])
            more_suggestions = list(more_suggestions)[:remaining_slots]
            suggestions.extend(more_suggestions)

    return HttpResponse(json.dumps(suggestions),
                        content_type='application/json; charset=utf-8')
Пример #3
0
def search_suggestions_view(request):
    """Return some search suggestions for search."""
    MAX_RESULTS = 10
    query = request.GET.get('q', '').lower()
    query = clean_input_string(query)

    suggestions = []
    if query != '':
        regex = query_regex(query)

        # Make a variation for checking at the start of the string.
        regex_at_start = '^%s' % regex

        # First look for suggestions that match at the start of the
        # query string.

        # This query is case-sensitive for better speed than using a
        # case-insensitive query. The database field is also case-
        # sensitive, so it is important that all SearchSuggestion
        # records be lowercased before import to ensure that they
        # can be reached.
        suggestions = list(
            SearchSuggestion.objects.filter(
                term__iregex=regex_at_start).exclude(
                    term=query).order_by('term').values_list('term', flat=True)
            [:MAX_RESULTS * 2])  # Fetch extra to handle case-sensitive dups
        # Remove any duplicates due to case-sensitivity and pare down to
        # the desired number of results.
        suggestions = list(
            sorted(set([suggestion.lower()
                        for suggestion in suggestions])))[:MAX_RESULTS]

        # If fewer than the maximum number of suggestions were found,
        # try finding some additional ones that match anywhere in the
        # query string.
        remaining_slots = MAX_RESULTS - len(suggestions)
        if remaining_slots > 0:
            more_suggestions = list(
                SearchSuggestion.objects.filter(term__iregex=regex).exclude(
                    term__iregex=regex_at_start).order_by('term').values_list(
                        'term', flat=True)[:MAX_RESULTS * 2])
            more_suggestions = list(
                sorted(
                    set([
                        suggestion.lower() for suggestion in more_suggestions
                    ])))[:remaining_slots]
            suggestions.extend(more_suggestions)

    return HttpResponse(json.dumps(suggestions),
                        content_type='application/json; charset=utf-8')
Пример #4
0
def search_suggestions_view(request):
    """Return some search suggestions for search."""
    MAX_RESULTS = 10
    query = request.GET.get("q", "").lower()
    query = clean_input_string(query)

    suggestions = []
    if query != "":
        regex = query_regex(query)

        # Make a variation for checking at the start of the string.
        regex_at_start = "^%s" % regex

        # First look for suggestions that match at the start of the
        # query string.

        # This query is case-sensitive for better speed than using a
        # case-insensitive query. The database field is also case-
        # sensitive, so it is important that all SearchSuggestion
        # records be lowercased before import to ensure that they
        # can be reached.
        suggestions = list(
            SearchSuggestion.objects.filter(term__iregex=regex_at_start)
            .exclude(term=query)
            .order_by("term")
            .values_list("term", flat=True)[: MAX_RESULTS * 2]
        )  # Fetch extra to handle case-sensitive dups
        # Remove any duplicates due to case-sensitivity and pare down to
        # the desired number of results.
        suggestions = list(sorted(set([suggestion.lower() for suggestion in suggestions])))[:MAX_RESULTS]

        # If fewer than the maximum number of suggestions were found,
        # try finding some additional ones that match anywhere in the
        # query string.
        remaining_slots = MAX_RESULTS - len(suggestions)
        if remaining_slots > 0:
            more_suggestions = list(
                SearchSuggestion.objects.filter(term__iregex=regex)
                .exclude(term__iregex=regex_at_start)
                .order_by("term")
                .values_list("term", flat=True)[: MAX_RESULTS * 2]
            )
            more_suggestions = list(sorted(set([suggestion.lower() for suggestion in more_suggestions])))[
                :remaining_slots
            ]
            suggestions.extend(more_suggestions)

    return HttpResponse(json.dumps(suggestions), content_type="application/json; charset=utf-8")
Пример #5
0
def restrictions(plant_name, location=None):
    """Return a list of taxa matching a given plant name, along with any
    information on restrictions for sightings of rare plants, etc.
    """
    plant_regex = query_regex(plant_name, anchor_at_start=True,
        anchor_at_end=True)
    covered_state = get_covered_state(location)
    restrictions = []

    # Restrictions apply for all names for a plant: scientific name,
    # synonyms, and common names.
    scientific_name_taxa = Taxon.objects.filter(
        scientific_name__iregex=plant_regex)
    common_name_taxa = Taxon.objects.filter(
        common_names__common_name__iregex=plant_regex)
    synonym_taxa = Taxon.objects.filter(
        synonyms__scientific_name__iregex=plant_regex)
    taxa = list(
        set(chain(scientific_name_taxa, common_name_taxa, synonym_taxa)))

    for taxon in taxa:
        common_names = [n.common_name for n in taxon.common_names.all()]
        synonyms = [s.scientific_name for s in taxon.synonyms.all()]

        allow_public_posting = {}
        for status in taxon.conservation_statuses.all():
            state_name = settings.STATE_NAMES[status.region.lower()]
            # If a status entry has already set a state's "allow public
            # posting" value to False, prevent another from overwriting it.
            if (state_name not in allow_public_posting.keys() or
                    allow_public_posting[state_name] != False):
                allow_public_posting[state_name] = status.allow_public_posting
        # Fill in any states that do not have conservation status
        # records.
        for key in settings.STATE_NAMES.keys():
            state_name = settings.STATE_NAMES[key]
            if state_name not in allow_public_posting.keys():
                allow_public_posting[state_name] = True

        sightings_restricted = False
        sightings_flagged = False

        # Terms used here:
        # 'restrict': allow only private sighting visibility
        # 'flag': set a flag on the sighting to alert for admin. review

        # If the location is in a state covered by the site, restrict
        # (and flag) only if the plant is rare in that state.
        if covered_state is not None and covered_state:
            if not allow_public_posting[covered_state]:
                sightings_restricted = True
                sightings_flagged = True
        else:
            # If the location is anywhere else (or is unknown), flag
            # if the plant is rare in any New England state.
            # This is a conservative measure for various edge cases
            # such as plants that may be rare outside New England,
            # incorrect location detection, etc.
            for state in allow_public_posting.keys():
                if not allow_public_posting[state]:
                    sightings_flagged = True
                    break

        restrictions.append({
            'scientific_name': taxon.scientific_name,
            'common_names': common_names,
            'synonyms': synonyms,
            'covered_state': covered_state,
            'allow_public_posting': allow_public_posting,
            'sightings_restricted': sightings_restricted,
            'sightings_flagged': sightings_flagged,
        })

    return restrictions
Пример #6
0
def restrictions(plant_name, location=None):
    """Return a list of taxa matching a given plant name, along with any
    information on restrictions for sightings of rare plants, etc.
    """
    plant_regex = query_regex(plant_name,
                              anchor_at_start=True,
                              anchor_at_end=True)
    covered_state = get_covered_state(location)
    restrictions = []

    # Restrictions apply for all names for a plant: scientific name,
    # synonyms, and common names.
    scientific_name_taxa = Taxon.objects.filter(
        scientific_name__iregex=plant_regex)
    common_name_taxa = Taxon.objects.filter(
        common_names__common_name__iregex=plant_regex)
    synonym_taxa = Taxon.objects.filter(
        synonyms__scientific_name__iregex=plant_regex)
    taxa = list(
        set(chain(scientific_name_taxa, common_name_taxa, synonym_taxa)))

    for taxon in taxa:
        common_names = [n.common_name for n in taxon.common_names.all()]
        synonyms = [s.scientific_name for s in taxon.synonyms.all()]

        allow_public_posting = {}
        for status in taxon.conservation_statuses.all():
            state_name = settings.STATE_NAMES[status.region.lower()]
            # If a status entry has already set a state's "allow public
            # posting" value to False, prevent another from overwriting it.
            if (state_name not in allow_public_posting.keys()
                    or allow_public_posting[state_name] != False):
                allow_public_posting[state_name] = status.allow_public_posting
        # Fill in any states that do not have conservation status
        # records.
        for key in settings.STATE_NAMES.keys():
            state_name = settings.STATE_NAMES[key]
            if state_name not in allow_public_posting.keys():
                allow_public_posting[state_name] = True

        sightings_restricted = False
        sightings_flagged = False

        # Terms used here:
        # 'restrict': allow only private sighting visibility
        # 'flag': set a flag on the sighting to alert for admin. review

        # If the location is in a state covered by the site, restrict
        # (and flag) only if the plant is rare in that state.
        if covered_state is not None and covered_state:
            if not allow_public_posting[covered_state]:
                sightings_restricted = True
                sightings_flagged = True
        else:
            # If the location is anywhere else (or is unknown), flag
            # if the plant is rare in any New England state.
            # This is a conservative measure for various edge cases
            # such as plants that may be rare outside New England,
            # incorrect location detection, etc.
            for state in allow_public_posting.keys():
                if not allow_public_posting[state]:
                    sightings_flagged = True
                    break

        restrictions.append({
            'scientific_name': taxon.scientific_name,
            'common_names': common_names,
            'synonyms': synonyms,
            'covered_state': covered_state,
            'allow_public_posting': allow_public_posting,
            'sightings_restricted': sightings_restricted,
            'sightings_flagged': sightings_flagged,
        })

    return restrictions