Ejemplo n.º 1
0
def home_view(request):
    """View for the home page of the Go Botany site."""

    partner = which_partner(request)

    # Get home page images for the partner
    home_page_images = HomePageImage.objects.filter(partner_site=partner)

    # Get or generate today's Plant of the Day, if appropriate.
    plant_of_the_day = PlantOfTheDay.get_by_date.for_day(
        date.today(), partner.short_name)
    plant_of_the_day_taxon = None
    if plant_of_the_day:
        # Get the Taxon record of the Plant of the Day.
        try:
            plant_of_the_day_taxon = Taxon.objects.get(
                scientific_name=plant_of_the_day.scientific_name)
        except ObjectDoesNotExist:
            pass

    plant_of_the_day_image = None
    species_images = botany.species_images(plant_of_the_day_taxon)
    if species_images:
        plant_of_the_day_image = botany.species_images(
            plant_of_the_day_taxon)[0]

    return render_per_partner(
        'home.html', {
            'home_page_images': home_page_images,
            'plant_of_the_day': plant_of_the_day_taxon,
            'plant_of_the_day_image': plant_of_the_day_image,
        }, request)
Ejemplo n.º 2
0
def home_view(request):
    """View for the home page of the Go Botany site."""

    home_page_images = HomePageImage.objects.all()
    # Get or generate today's Plant of the Day.
    partner = which_partner(request)
    plant_of_the_day = PlantOfTheDay.get_by_date.for_day(date.today(), partner.short_name)
    # Get the Taxon record of the Plant of the Day.
    plant_of_the_day_taxon = None
    try:
        plant_of_the_day_taxon = Taxon.objects.get(scientific_name=plant_of_the_day.scientific_name)
    except ObjectDoesNotExist:
        pass

    plant_of_the_day_image = None
    species_images = botany.species_images(plant_of_the_day_taxon)
    if species_images:
        plant_of_the_day_image = botany.species_images(plant_of_the_day_taxon)[0]

    return render_to_response(
        "gobotany/home.html",
        {
            "home_page_images": home_page_images,
            "plant_of_the_day": plant_of_the_day_taxon,
            "plant_of_the_day_image": plant_of_the_day_image,
        },
        context_instance=RequestContext(request),
    )
Ejemplo n.º 3
0
def home_view(request):
    """View for the home page of the Go Botany site."""

    partner = which_partner(request)

    # Get home page images for the partner
    home_page_images = HomePageImage.objects.filter(partner_site=partner)

    # Get or generate today's Plant of the Day, if appropriate.
    plant_of_the_day = PlantOfTheDay.get_by_date.for_day(
        date.today(), partner.short_name)
    plant_of_the_day_taxon = None
    if plant_of_the_day:
        # Get the Taxon record of the Plant of the Day.
        try:
            plant_of_the_day_taxon = Taxon.objects.get(
                scientific_name=plant_of_the_day.scientific_name)
        except ObjectDoesNotExist:
            pass

    plant_of_the_day_image = None
    species_images = botany.species_images(plant_of_the_day_taxon)
    if species_images:
        plant_of_the_day_image = botany.species_images(
            plant_of_the_day_taxon)[0]

    return render_to_response_per_partner('home.html', {
            'home_page_images': home_page_images,
            'plant_of_the_day': plant_of_the_day_taxon,
            'plant_of_the_day_image': plant_of_the_day_image,
            }, request)
Ejemplo n.º 4
0
def vectors_key(request, key):
    if key != 'simple':
        raise Http404()
    partner = which_partner(request)
    ids = sorted( ps.species_id for ps in PartnerSpecies.objects
                  .filter(partner=partner, simple_key=True) )
    return jsonify([{'key': 'simple', 'species': ids}],
                   headers={'Expires': 'Thu, 1 Jan 1970 00:00:00 GMT'})
Ejemplo n.º 5
0
def vectors_key(request, key):
    if key != 'simple':
        raise Http404()
    partner = which_partner(request)
    ids = sorted( ps.species_id for ps in PartnerSpecies.objects
                  .filter(partner=partner, simple_key=True) )
    return jsonify([{'key': 'simple', 'species': ids}],
                   headers={'Expires': 'Thu, 1 Jan 1970 00:00:00 GMT'})
Ejemplo n.º 6
0
def _edit_pile_length_character(request, pile, character, taxa):

    # There is little point in being heroic and trying to create exactly
    # one character value for a pair of

    taxon_ids = {taxon.id for taxon in taxa}
    taxon_values = {}
    minmaxes = {taxon.id: [None, None] for taxon in taxa}

    for tcv in models.TaxonCharacterValue.objects.filter(
            taxon__in=taxa, character_value__character=character
          ).select_related('character_value'):
        v = tcv.character_value
        taxon_values[tcv.taxon_id] = v
        minmaxes[tcv.taxon_id] = [v.value_min, v.value_max]

    # Process a POST.

    if 'new_values' in request.POST:
        new_values = request.POST['new_values']
        return _save(request, new_values, character=character)

    # Grabbing one copy of each family once is noticeably faster than
    # using select_related('family') up in the taxon fetch:

    family_ids = set(t.family_id for t in taxa)
    families = models.Family.objects.filter(id__in=family_ids)

    taxa.sort(key=pluck('family_id'))  # always sort() before groupby()!
    taxa_by_family_id = { family_id: list(group) for family_id, group
                          in groupby(taxa, key=pluck('family_id')) }

    def grid():
        """Iterator across families and their taxa."""
        for family in families:
            yield 'family', family, None
            for taxon in taxa_by_family_id.get(family.id, ()):
                name = taxon.scientific_name
                if taxon.id not in simple_ids:
                    name += ' (fk)'
                yield 'taxon', name, minmaxes[taxon.id]

    partner = which_partner(request)
    simple_ids = set(ps.species_id for ps in models.PartnerSpecies.objects
                     .filter(partner_id=partner.id, simple_key=True))

    valued_ids = {id for id, value in minmaxes.items() if value != ['', ''] }
    coverage_percent_full = len(valued_ids) * 100.0 / len(taxa)
    coverage_percent_simple = (len(simple_ids.intersection(valued_ids))
                     * 100.0 / len(simple_ids.intersection(taxon_ids)))

    return render(request, 'gobotany/edit_pile_length.html', {
        'character': character,
        'coverage_percent_full': coverage_percent_full,
        'coverage_percent_simple': coverage_percent_simple,
        'grid': grid(),
        'pile': pile,
        })
Ejemplo n.º 7
0
def atom_view(request):
    MAX_NUMBER_PLANTS = 15
    partner_short_name = which_partner(request)

    plants_of_the_day = _get_plants_of_the_day(MAX_NUMBER_PLANTS, partner_short_name)

    return render_per_partner(
        "atom.xml", {"plants_of_the_day": plants_of_the_day}, request, content_type="application/atom+xml"
    )
Ejemplo n.º 8
0
def atom_view(request):
    MAX_NUMBER_PLANTS = 15
    partner_short_name = which_partner(request)

    plants_of_the_day = _get_plants_of_the_day(MAX_NUMBER_PLANTS,
                                               partner_short_name)

    return render_to_response_per_partner('atom.xml', {
            'plants_of_the_day': plants_of_the_day
        }, request, content_type='application/atom+xml')
Ejemplo n.º 9
0
def atom_view(request):
    MAX_NUMBER_PLANTS = 15
    partner_short_name = which_partner(request)

    plants_of_the_day = _get_plants_of_the_day(MAX_NUMBER_PLANTS,
                                               partner_short_name)

    return render_per_partner('atom.xml', {
            'plants_of_the_day': plants_of_the_day
        }, request, content_type='application/atom+xml')
Ejemplo n.º 10
0
    def render(self, context):
        scientific_name = self.scientific_name.resolve(context)
        partner = which_partner(context['request'])

        partner_site = PartnerSite.objects.get(short_name=partner.short_name)
        partner_has_species = partner_site.has_species(scientific_name)

        try:
            href = ''
            if partner_has_species:
                href = 'href="/species/%s/"' % \
                       scientific_name.lower().replace(' ', '/')
            html = '<a %s><i>%s</i></a>' % (href, scientific_name)
            return html
        except template.VariableDoesNotExist:
            return ''
Ejemplo n.º 11
0
    def render(self, context):
        scientific_name = self.scientific_name.resolve(context)
        partner = which_partner(context['request'])

        partner_site = PartnerSite.objects.get(short_name=partner)
        partner_has_species = partner_site.has_species(scientific_name)

        try:
            href = ''
            if partner_has_species:
                href = 'href="/species/%s/"' % \
                       scientific_name.lower().replace(' ', '/')
            html = '<a %s><i>%s</i></a>' % (href, scientific_name)
            return html
        except template.VariableDoesNotExist:
            return ''
Ejemplo n.º 12
0
def home_view(request):
    """View for the home page of the Go Botany site."""

    try:
        intro = FlatPage.objects.get(url='/home/').content
    except ObjectDoesNotExist:
        intro = None

    # Get or generate today's Plant of the Day, if appropriate.
    partner = which_partner(request)
    plant_of_the_day = PlantOfTheDay.get_by_date.for_day(
        date.today(), partner.short_name)
    plant_of_the_day_taxon = None
    if plant_of_the_day:
        # Get the Taxon record of the Plant of the Day.
        try:
            plant_of_the_day_taxon = GoOrchidTaxon.objects.get(
                scientific_name=plant_of_the_day.scientific_name)
        except ObjectDoesNotExist:
            pass

    plant_of_the_day_image = None

    if hasattr(plant_of_the_day_taxon, 'taxon_ptr'):
        species_images = botany.species_images(
            plant_of_the_day_taxon.taxon_ptr,
            image_types='flowers,inflorescences')
    if len(species_images) == 0:
        species_images = botany.species_images(
            plant_of_the_day_taxon,
            image_types='flowers,inflorescences')

    if species_images:
        plant_of_the_day_image = species_images[0]

    return render_to_response('gobotany/home.html', {
        'intro': intro,
        'plant_of_the_day': plant_of_the_day_taxon,
        'plant_of_the_day_image': plant_of_the_day_image,
        }, context_instance=RequestContext(request))
Ejemplo n.º 13
0
def home_view(request):
    """View for the home page of the Go Botany site."""

    try:
        intro = FlatPage.objects.get(url='/home/').content
    except ObjectDoesNotExist:
        intro = None

    # Get or generate today's Plant of the Day, if appropriate.
    partner = which_partner(request)
    plant_of_the_day = PlantOfTheDay.get_by_date.for_day(
        date.today(), partner.short_name)
    plant_of_the_day_taxon = None
    if plant_of_the_day:
        # Get the Taxon record of the Plant of the Day.
        try:
            plant_of_the_day_taxon = GoOrchidTaxon.objects.get(
                scientific_name=plant_of_the_day.scientific_name)
        except ObjectDoesNotExist:
            pass

    plant_of_the_day_image = None

    if hasattr(plant_of_the_day_taxon, 'taxon_ptr'):
        species_images = botany.species_images(
            plant_of_the_day_taxon.taxon_ptr,
            image_types='flowers,inflorescences')
    if len(species_images) == 0:
        species_images = botany.species_images(
            plant_of_the_day_taxon, image_types='flowers,inflorescences')

    if species_images:
        plant_of_the_day_image = species_images[0]

    return render_to_response('gobotany/home.html', {
        'intro': intro,
        'plant_of_the_day': plant_of_the_day_taxon,
        'plant_of_the_day_image': plant_of_the_day_image,
    },
                              context_instance=RequestContext(request))
Ejemplo n.º 14
0
def species_view(request, genus_slug, epithet):

    COMPACT_MULTIVALUE_CHARACTERS = [
        'Habitat', 'New England state', 'Specific Habitat'
    ]

    genus_name = genus_slug.capitalize()
    scientific_name = '%s %s' % (genus_name, epithet)
    taxon = get_object_or_404(GoOrchidTaxon, scientific_name=scientific_name)

    scientific_name_short = '%s. %s' % (scientific_name[0], epithet)

    pile_slug = request.GET.get('pile')
    if pile_slug:
        pile = get_object_or_404(Pile, slug=pile_slug)
    else:
        # Randomly grab the first pile from the species
        pile = taxon.piles.order_by('id')[0]
    pilegroup = pile.pilegroup

    partner = which_partner(request)
    partner_species = None
    if partner:
        rows = PartnerSpecies.objects.filter(species=taxon,
                                             partner=partner).all()
        if rows:
            partner_species = rows[0]

    species_in_simple_key = (partner_species and partner_species.simple_key)
    key = request.GET.get('key')
    if not key:
        if species_in_simple_key:
            key = 'simple'
        else:
            key = 'full'

    if hasattr(taxon, 'taxon_ptr'):
        species_images = botany.species_images(taxon.taxon_ptr)
    if len(species_images) == 0:
        species_images = botany.species_images(taxon)

    images = _images_with_copyright_holders(species_images)

    # Get the set of preview characteristics.

    plant_preview_characters = {
        ppc.character_id: ppc.order
        for ppc in PlantPreviewCharacter.objects.filter(pile=pile,
                                                        partner_site=partner)
    }

    # Select ALL character values for this taxon.

    character_values = list(
        taxon.character_values.select_related('character',
                                              'character__character_group'))

    # Throw away values for characters that are not part of this pile.

    pile_ids = (None, pile.id)  # characters like 'habitat' have pile_id None
    character_values = [
        v for v in character_values if v.character.pile_id in pile_ids
    ]

    # Create a tree of character groups, characters, and values.

    get_group_name = lambda v: v.character.character_group.name
    get_character_name = lambda v: v.character.friendly_name

    character_values.sort(key=get_character_name)
    character_values.sort(key=get_group_name)

    all_characteristics = []
    for group_name, seq1 in groupby(character_values, get_group_name):
        characters = []

        for character_name, seq2 in groupby(seq1, get_character_name):
            seq2 = list(seq2)
            character = seq2[0].character  # arbitrary; all look the same
            characters.append({
                'group':
                character.character_group.name,
                'name':
                character.friendly_name,
                'values':
                sorted((_format_character_value(v) for v in seq2),
                       cmp=_compare_character_values),
                'in_preview':
                character.id in plant_preview_characters,
                'preview_order':
                plant_preview_characters.get(character.id, -1),
            })

        all_characteristics.append({
            'name': group_name,
            'characters': characters
        })

    # Pick out the few preview characters for separate display.

    preview_characters = sorted(
        (character for group in all_characteristics
         for character in group['characters'] if character['in_preview']),
        key=itemgetter('preview_order'))

    native_to_north_america = _native_to_north_america_status(taxon)

    return render_to_response(
        'gobotany/species.html',
        {
            'pilegroup':
            pilegroup,
            'pile':
            pile,
            'scientific_name':
            scientific_name,
            'scientific_name_short':
            scientific_name_short,
            'taxon':
            taxon,
            'key':
            key,
            'species_in_simple_key':
            species_in_simple_key,
            'common_names':
            taxon.common_names.all(),  # view uses this 3 times
            'images':
            images,
            'partner_heading':
            partner_species.species_page_heading if partner_species else None,
            'partner_blurb':
            partner_species.species_page_blurb if partner_species else None,
            'ready_for_display':
            taxon.ready_for_display,
            'compact_multivalue_characters':
            COMPACT_MULTIVALUE_CHARACTERS,
            'brief_characteristics':
            preview_characters,
            'all_characteristics':
            all_characteristics,
            'epithet':
            epithet,
            'native_to_north_america':
            native_to_north_america
        },
        context_instance=RequestContext(request))
Ejemplo n.º 15
0
def _edit_pile_string_character(request, pile, character, taxa):

    values = list(character.character_values.all())
    values.sort(key=character_value_key)

    tcvlist = list(models.TaxonCharacterValue.objects
                   .filter(taxon__in=taxa, character_value__in=values))
    value_map = {(tcv.taxon_id, tcv.character_value_id): tcv
                 for tcv in tcvlist}

    # We now have enough information, and can either handle a POST
    # update of specific data or a GET that displays the whole pile.

    if 'new_values' in request.POST:
        new_values = request.POST['new_values']
        return _save(request, new_values, character=character)

    # Grabbing one copy of each family once is noticeably faster than
    # using select_related('family') up in the taxon fetch:

    family_ids = set(t.family_id for t in taxa)
    families = models.Family.objects.filter(id__in=family_ids)

    taxa.sort(key=pluck('family_id'))  # always sort() before groupby()!
    taxa_by_family_id = { family_id: list(group) for family_id, group
                          in groupby(taxa, key=pluck('family_id')) }

    partner = which_partner(request)
    simple_ids = set(ps.species_id for ps in models.PartnerSpecies.objects
                     .filter(partner_id=partner.id, simple_key=True))

    # This view takes far too long to render with slow Django templates,
    # so we simply deliver JSON data for the front-end to render there.

    def grid():
        for family in sorted(families, key=pluck('name')):
            yield [family.name]
            family_taxa = taxa_by_family_id[family.id]
            for taxon in family_taxa:
                vector = ''.join(
                    '1' if (taxon.id, value.id) in value_map else '0'
                    for value in values
                    )
                name = taxon.scientific_name
                if taxon.id not in simple_ids:
                    name += ' (fk)'
                yield [name, vector]

    taxa_with_values = set(tcv.taxon_id for tcv in tcvlist)
    taxa_ids = set(taxon.id for taxon in taxa)

    coverage_percent_full = len(taxa_with_values) * 100.0 / len(taxa)
    coverage_percent_simple = (len(simple_ids.intersection(taxa_with_values))
                     * 100.0 / len(simple_ids.intersection(taxa_ids)))

    return render(request, 'gobotany/edit_pile_character.html', {
        'there_are_any_friendly_texts': any(v.friendly_text for v in values),
        'character': character,
        'coverage_percent_full': coverage_percent_full,
        'coverage_percent_simple': coverage_percent_simple,
        'grid': json.dumps(list(grid())),
        'pile': pile,
        'values': values,
        'values_json': json.dumps([value.value_str for value in values]),
        })
Ejemplo n.º 16
0
def species_view(request, genus_slug, epithet):

    COMPACT_MULTIVALUE_CHARACTERS = [
        'Habitat', 'New England state', 'Specific Habitat'
    ]

    genus_name = genus_slug.capitalize()
    scientific_name = '%s %s' % (genus_name, epithet)
    taxon = get_object_or_404(Taxon, scientific_name=scientific_name)

    scientific_name_short = '%s. %s' % (scientific_name[0], epithet)

    pile_slug = request.GET.get('pile')
    if pile_slug:
        pile = get_object_or_404(Pile, slug=pile_slug)
    else:
        # Randomly grab the first pile from the species
        pile = taxon.piles.order_by('id')[0]
    pilegroup = pile.pilegroup

    partner = which_partner(request)
    partner_species = None
    if partner:
        rows = PartnerSpecies.objects.filter(species=taxon,
                                             partner=partner).all()
        if rows:
            partner_species = rows[0]

    dkey_pages = dkey_models.Page.objects.filter(title=scientific_name)
    dkey_page = dkey_pages[0] if dkey_pages else None

    dkey_hybrids = (dkey_models.Hybrid.objects.filter(
        Q(scientific_name1=scientific_name)
        | Q(scientific_name2=scientific_name)).order_by('number1', 'number2'))

    species_in_simple_key = (partner_species and partner_species.simple_key)
    key = request.GET.get('key')
    if not key:
        if species_in_simple_key:
            key = 'simple'
        else:
            key = 'full'

    species_images = botany.species_images(taxon)
    images = _images_with_copyright_holders(species_images)

    # Get the set of preview characteristics.

    plant_preview_characters = {
        ppc.character_id: ppc.order
        for ppc in PlantPreviewCharacter.objects.filter(pile=pile,
                                                        partner_site=partner)
    }
    # If no preview characteristics are defined for a partner, use the
    # ones defined for Go Botany.
    if len(plant_preview_characters) == 0:
        gobotany = PartnerSite.objects.get(short_name='gobotany')
        plant_preview_characters = {
            ppc.character_id: ppc.order
            for ppc in PlantPreviewCharacter.objects.filter(
                pile=pile, partner_site=gobotany)
        }

    # Select ALL character values for this taxon.

    character_values = list(
        taxon.character_values.select_related('character',
                                              'character__character_group'))

    # Throw away values for characters that are not part of this pile.

    pile_ids = (None, pile.id)  # characters like 'habitat' have pile_id None

    # TODO: eventually remove this temporary code after the Remaining
    # Non-Monocots pile character value data is split and assigned.
    if pile.name.find('Remaining Non-Monocots') > -1:
        try:
            # Include the big pile which has the character value data.
            big_pile = Pile.objects.get(name='Remaining Non-Monocots')
            pile_ids = pile_ids + (big_pile.id, )
        except models.Pile.DoesNotExist:
            pass
    # (end of temporary code)

    character_values = [
        v for v in character_values if v.character.pile_id in pile_ids
    ]

    # Create a tree of character groups, characters, and values.

    get_group_name = lambda v: v.character.character_group.name
    get_character_name = lambda v: v.character.friendly_name

    character_values.sort(key=get_character_name)
    character_values.sort(key=get_group_name)

    all_characteristics = []
    for group_name, seq1 in groupby(character_values, get_group_name):
        characters = []

        for character_name, seq2 in groupby(seq1, get_character_name):
            seq2 = list(seq2)
            character = seq2[0].character  # arbitrary; all look the same
            characters.append({
                'group':
                character.character_group.name,
                'name':
                character.friendly_name,
                'values':
                sorted(_format_character_value(v) for v in seq2),
                'in_preview':
                character.id in plant_preview_characters,
                'preview_order':
                plant_preview_characters.get(character.id, -1),
            })

        all_characteristics.append({
            'name': group_name,
            'characters': characters
        })

    # Pick out the few preview characters for separate display.

    preview_characters = sorted(
        (character for group in all_characteristics
         for character in group['characters'] if character['in_preview']),
        key=itemgetter('preview_order'))

    native_to_north_america = _native_to_north_america_status(taxon)

    statuses = taxon.conservation_statuses.values_list(
        'variety_subspecies_hybrid', 'region', 's_rank', 'endangerment_code')
    statuses_state_names = [{
        'variety_subspecies_hybrid': variety_subspecies_hybrid,
        'state': settings.STATE_NAMES[region.lower()],
        's_rank': s_rank,
        'endangerment_code': endangerment_code
    } for (variety_subspecies_hybrid, region, s_rank,
           endangerment_code) in statuses]
    conservation_statuses = sorted(
        statuses_state_names,
        key=lambda k: (k['variety_subspecies_hybrid'], k['state']))

    return render_per_partner(
        'species.html',
        {
            'pilegroup':
            pilegroup,
            'pile':
            pile,
            'scientific_name':
            scientific_name,
            'scientific_name_short':
            scientific_name_short,
            'taxon':
            taxon,
            'key':
            key,
            'species_in_simple_key':
            species_in_simple_key,
            'common_names':
            taxon.common_names.all(),  # view uses this 3 times
            'dkey_hybrids':
            dkey_hybrids,
            'dkey_page':
            dkey_page,
            'images':
            images,
            'partner_heading':
            partner_species.species_page_heading if partner_species else None,
            'partner_blurb':
            partner_species.species_page_blurb if partner_species else None,
            'compact_multivalue_characters':
            COMPACT_MULTIVALUE_CHARACTERS,
            'brief_characteristics':
            preview_characters,
            'all_characteristics':
            all_characteristics,
            'epithet':
            epithet,
            'native_to_north_america':
            native_to_north_america,
            'conservation_statuses':
            conservation_statuses,
            'prior_signup_detected':
            prior_signup_detected(request),
        },
        request)
Ejemplo n.º 17
0
def species_view(request, genus_slug, epithet):

    COMPACT_MULTIVALUE_CHARACTERS = ['Habitat', 'New England state',
                                     'Specific Habitat']

    genus_name = genus_slug.capitalize()
    scientific_name = '%s %s' % (genus_name, epithet)
    taxon = get_object_or_404(GoOrchidTaxon, scientific_name=scientific_name)

    scientific_name_short = '%s. %s' % (scientific_name[0], epithet)

    pile_slug = request.GET.get('pile')
    if pile_slug:
        pile = get_object_or_404(Pile, slug=pile_slug)
    else:
        # Randomly grab the first pile from the species
        pile = taxon.piles.order_by('id')[0]
    pilegroup = pile.pilegroup

    partner = which_partner(request)
    partner_species = None
    if partner:
        rows = PartnerSpecies.objects.filter(
            species=taxon, partner=partner).all()
        if rows:
            partner_species = rows[0]

    species_in_simple_key = (partner_species and partner_species.simple_key)
    key = request.GET.get('key')
    if not key:
        if species_in_simple_key:
            key = 'simple'
        else:
            key = 'full'

    if hasattr(taxon, 'taxon_ptr'):
        species_images = botany.species_images(taxon.taxon_ptr)
    if len(species_images) == 0:
        species_images = botany.species_images(taxon)

    images = _images_with_copyright_holders(species_images)

    # Get the set of preview characteristics.

    plant_preview_characters = {
        ppc.character_id: ppc.order for ppc in
        PlantPreviewCharacter.objects.filter(pile=pile, partner_site=partner)
    }

    # Select ALL character values for this taxon.

    character_values = list(taxon.character_values.select_related(
        'character', 'character__character_group'))

    # Throw away values for characters that are not part of this pile.

    pile_ids = (None, pile.id)  # characters like 'habitat' have pile_id None
    character_values = [v for v in character_values
                        if v.character.pile_id in pile_ids]

    # Create a tree of character groups, characters, and values.

    get_group_name = lambda v: v.character.character_group.name
    get_character_name = lambda v: v.character.friendly_name

    character_values.sort(key=get_character_name)
    character_values.sort(key=get_group_name)

    all_characteristics = []
    for group_name, seq1 in groupby(character_values, get_group_name):
        characters = []

        for character_name, seq2 in groupby(seq1, get_character_name):
            seq2 = list(seq2)
            character = seq2[0].character  # arbitrary; all look the same
            characters.append({
                'group': character.character_group.name,
                'name': character.friendly_name,
                'values': sorted((_format_character_value(v) for v in seq2),
                                 cmp=_compare_character_values),
                'in_preview': character.id in plant_preview_characters,
                'preview_order': plant_preview_characters.get(character.id, -1),
            })

        all_characteristics.append({
            'name': group_name,
            'characters': characters
        })

    # Pick out the few preview characters for separate display.

    preview_characters = sorted((
        character
        for group in all_characteristics
        for character in group['characters']
        if character['in_preview']
    ), key=itemgetter('preview_order'))

    native_to_north_america = _native_to_north_america_status(taxon)

    return render_to_response('gobotany/species.html', {
        'pilegroup': pilegroup,
        'pile': pile,
        'scientific_name': scientific_name,
        'scientific_name_short': scientific_name_short,
        'taxon': taxon,
        'key': key,
        'species_in_simple_key': species_in_simple_key,
        'common_names': taxon.common_names.all(),  # view uses this 3 times
        'images': images,
        'partner_heading': partner_species.species_page_heading
            if partner_species else None,
        'partner_blurb': partner_species.species_page_blurb
            if partner_species else None,
        'ready_for_display': taxon.ready_for_display,
        'compact_multivalue_characters': COMPACT_MULTIVALUE_CHARACTERS,
        'brief_characteristics': preview_characters,
        'all_characteristics': all_characteristics,
        'epithet': epithet,
        'native_to_north_america': native_to_north_america
    }, context_instance=RequestContext(request))
Ejemplo n.º 18
0
def _edit_pile_length_character(request, pile, character, taxa):

    # There is little point in being heroic and trying to create exactly
    # one character value for a pair of

    taxon_ids = {taxon.id for taxon in taxa}
    taxon_values = {}
    minmaxes = {taxon.id: [None, None] for taxon in taxa}

    for tcv in models.TaxonCharacterValue.objects.filter(
            taxon__in=taxa,
            character_value__character=character).select_related(
                'character_value'):
        v = tcv.character_value
        taxon_values[tcv.taxon_id] = v
        minmaxes[tcv.taxon_id] = [v.value_min, v.value_max]

    # Process a POST.

    if 'new_values' in request.POST:
        new_values = request.POST['new_values']
        return _save(request, new_values, character=character)

    # Grabbing one copy of each family once is noticeably faster than
    # using select_related('family') up in the taxon fetch:

    family_ids = set(t.family_id for t in taxa)
    families = models.Family.objects.filter(id__in=family_ids)

    taxa.sort(key=pluck('family_id'))  # always sort() before groupby()!
    taxa_by_family_id = {
        family_id: list(group)
        for family_id, group in groupby(taxa, key=pluck('family_id'))
    }

    def grid():
        """Iterator across families and their taxa."""
        for family in families:
            yield 'family', family, None
            for taxon in taxa_by_family_id.get(family.id, ()):
                name = taxon.scientific_name
                if taxon.id not in simple_ids:
                    name += ' (fk)'
                yield 'taxon', name, minmaxes[taxon.id]

    partner = which_partner(request)
    simple_ids = set(ps.species_id
                     for ps in models.PartnerSpecies.objects.filter(
                         partner_id=partner.id, simple_key=True))

    valued_ids = {
        id
        for id, value in list(minmaxes.items()) if value != ['', '']
    }
    coverage_percent_full = len(valued_ids) * 100.0 / len(taxa)
    coverage_percent_simple = (len(simple_ids.intersection(valued_ids)) *
                               100.0 / len(simple_ids.intersection(taxon_ids)))

    return render(
        request, 'gobotany/edit_pile_length.html', {
            'character': character,
            'coverage_percent_full': coverage_percent_full,
            'coverage_percent_simple': coverage_percent_simple,
            'grid': grid(),
            'pile': pile,
        })
Ejemplo n.º 19
0
def _edit_pile_string_character(request, pile, character, taxa):

    values = list(character.character_values.all())
    values.sort(key=character_value_key)

    tcvlist = list(
        models.TaxonCharacterValue.objects.filter(taxon__in=taxa,
                                                  character_value__in=values))
    value_map = {(tcv.taxon_id, tcv.character_value_id): tcv
                 for tcv in tcvlist}

    # We now have enough information, and can either handle a POST
    # update of specific data or a GET that displays the whole pile.

    if 'new_values' in request.POST:
        new_values = request.POST['new_values']
        return _save(request, new_values, character=character)

    # Grabbing one copy of each family once is noticeably faster than
    # using select_related('family') up in the taxon fetch:

    family_ids = set(t.family_id for t in taxa)
    families = models.Family.objects.filter(id__in=family_ids)

    taxa.sort(key=pluck('family_id'))  # always sort() before groupby()!
    taxa_by_family_id = {
        family_id: list(group)
        for family_id, group in groupby(taxa, key=pluck('family_id'))
    }

    partner = which_partner(request)
    simple_ids = set(ps.species_id
                     for ps in models.PartnerSpecies.objects.filter(
                         partner_id=partner.id, simple_key=True))

    # This view takes far too long to render with slow Django templates,
    # so we simply deliver JSON data for the front-end to render there.

    def grid():
        for family in sorted(families, key=pluck('name')):
            yield [family.name]
            family_taxa = taxa_by_family_id[family.id]
            for taxon in family_taxa:
                vector = ''.join('1' if (taxon.id,
                                         value.id) in value_map else '0'
                                 for value in values)
                name = taxon.scientific_name
                if taxon.id not in simple_ids:
                    name += ' (fk)'
                yield [name, vector]

    taxa_with_values = set(tcv.taxon_id for tcv in tcvlist)
    taxa_ids = set(taxon.id for taxon in taxa)

    coverage_percent_full = len(taxa_with_values) * 100.0 / len(taxa)
    coverage_percent_simple = (len(simple_ids.intersection(taxa_with_values)) *
                               100.0 / len(simple_ids.intersection(taxa_ids)))

    return render(
        request, 'gobotany/edit_pile_character.html', {
            'there_are_any_friendly_texts': any(v.friendly_text
                                                for v in values),
            'character': character,
            'coverage_percent_full': coverage_percent_full,
            'coverage_percent_simple': coverage_percent_simple,
            'grid': json.dumps(list(grid())),
            'pile': pile,
            'values': values,
            'values_json': json.dumps([value.value_str for value in values]),
        })
Ejemplo n.º 20
0
def per_partner_template(request, template_path):
    partner = which_partner(request)
    if partner and partner.short_name != 'gobotany':
        return '{0}/{1}'.format(partner.short_name, template_path)
    else:
        return template_path
Ejemplo n.º 21
0
def species_list_view(request):
    partner = which_partner(request)

    plants_list = list(PartnerSpecies.objects.values(
            'species__id', 'species__scientific_name',
            'species__family__name', 'species__north_american_native',
            'species__north_american_introduced',
            'species__wetland_indicator_code',
        ).filter(partner=partner).order_by('species__scientific_name'))

    # Strip off the species__ prefix from the list's dictionary keys.
    for plant in plants_list:
        for key in plant:
            if '__' in key:
                new_key = key.replace('species__', '')
                plant[new_key] = plant.pop(key)

    # We build these three related lists manually instead of tempting
    # _get_plants() to return N * M copies of each plant.

    for plantdict in plants_list:
        plantdict['common_names'] = []
        plantdict['pile_titles'] = []
        plantdict['pilegroup_titles'] = []
        plantdict['states'] = set()

        scientific_name = plantdict['scientific_name']
        plantdict['genus'], plantdict['epithet'] = scientific_name.split()[:2]
        plantdict['lowgenus'] = plantdict['genus'].lower()

    plantmap = {
        plantdict['id']: plantdict for plantdict in plants_list
    }

    q = CommonName.objects.values_list('common_name', 'taxon_id')
    for common_name, taxon_id in q:
        if taxon_id in plantmap:
            plantmap[taxon_id]['common_names'].append(common_name)

    # Populate states from Distribution data.
    taxon_ids = plantmap.keys()
    t = Taxon.objects.filter(id__in=taxon_ids).values_list(
        'id', 'scientific_name')
    sci_names = list(set([name for id, name in t]))
    states = [state.upper() for state in settings.STATE_NAMES.keys()]
    d = Distribution.objects.filter(present=True).filter(
        county__exact='').filter(state__in=states).filter(
        species_name__in=sci_names).values_list('species_name', 'state')
    ids_by_name = {name: id for id, name in t}
    for scientific_name, state in d:
        taxon_id = ids_by_name[scientific_name]
        plantmap[taxon_id]['states'].add(state)

    q = Pile.species.through.objects.values_list(
        'taxon_id', 'pile__friendly_title', 'pile__pilegroup__friendly_title',
        )
    for taxon_id, pile_title, pilegroup_title in q:
        if taxon_id in plantmap:
            # Skip adding the "big Remaining Non-Monocots" pile's title,
            # since that pile has been split from the user's standpoint.
            # (Once the pile is fully split in the database, this check
            # can be removed.) 
            if pile_title != 'All other herbaceous, flowering dicots':
                plantmap[taxon_id]['pile_titles'].append(pile_title)
                plantmap[taxon_id]['pilegroup_titles'].append(pilegroup_title)

    for plantdict in plants_list:
        plantdict['states'] = ' '.join(sorted(plantdict['states'])).upper()

    return render_to_response_per_partner('species_list.html', {
        'plants': plants_list,
        }, request)
Ejemplo n.º 22
0
def species_list_view(request):
    partner = which_partner(request)

    plants_list = list(
        PartnerSpecies.objects.values(
            'species__id',
            'species__scientific_name',
            'species__family__name',
            'species__north_american_native',
            'species__north_american_introduced',
            'species__wetland_indicator_code',
        ).filter(partner=partner).order_by('species__scientific_name'))

    # Strip off the species__ prefix from the list's dictionary keys.
    for plant in plants_list:
        for key in plant:
            if '__' in key:
                new_key = key.replace('species__', '')
                plant[new_key] = plant.pop(key)

    # We build these three related lists manually instead of tempting
    # _get_plants() to return N * M copies of each plant.

    for plantdict in plants_list:
        plantdict['common_names'] = []
        plantdict['pile_titles'] = []
        plantdict['pilegroup_titles'] = []
        plantdict['states'] = set()

        scientific_name = plantdict['scientific_name']
        plantdict['genus'], plantdict['epithet'] = scientific_name.split()[:2]
        plantdict['lowgenus'] = plantdict['genus'].lower()

    plantmap = {plantdict['id']: plantdict for plantdict in plants_list}

    q = CommonName.objects.values_list('common_name', 'taxon_id')
    for common_name, taxon_id in q:
        if taxon_id in plantmap:
            plantmap[taxon_id]['common_names'].append(common_name)

    # Populate states from Distribution data.
    taxon_ids = list(plantmap.keys())
    t = Taxon.objects.filter(id__in=taxon_ids).values_list(
        'id', 'scientific_name')
    sci_names = list(set([name for id, name in t]))
    states = [state.upper() for state in list(settings.STATE_NAMES.keys())]
    d = Distribution.objects.filter(present=True).filter(
        county__exact='').filter(state__in=states).filter(
            species_name__in=sci_names).values_list('species_name', 'state')
    ids_by_name = {name: id for id, name in t}
    for scientific_name, state in d:
        taxon_id = ids_by_name[scientific_name]
        plantmap[taxon_id]['states'].add(state)

    q = Pile.species.through.objects.values_list(
        'taxon_id',
        'pile__friendly_title',
        'pile__pilegroup__friendly_title',
    )
    for taxon_id, pile_title, pilegroup_title in q:
        if taxon_id in plantmap:
            # Skip adding the "big Remaining Non-Monocots" pile's title,
            # since that pile has been split from the user's standpoint.
            # (Once the pile is fully split in the database, this check
            # can be removed.)
            if pile_title != 'All other herbaceous, flowering dicots':
                plantmap[taxon_id]['pile_titles'].append(pile_title)
                plantmap[taxon_id]['pilegroup_titles'].append(pilegroup_title)

    for plantdict in plants_list:
        plantdict['states'] = ' '.join(sorted(plantdict['states'])).upper()

    return render_per_partner('species_list.html', {
        'plants': plants_list,
    }, request)
Ejemplo n.º 23
0
def species_view(request, genus_slug, epithet):

    COMPACT_MULTIVALUE_CHARACTERS = ['Habitat', 'New England state',
                                     'Specific Habitat']

    genus_name = genus_slug.capitalize()
    scientific_name = '%s %s' % (genus_name, epithet)
    taxon = get_object_or_404(Taxon, scientific_name=scientific_name)

    scientific_name_short = '%s. %s' % (scientific_name[0], epithet)

    pile_slug = request.GET.get('pile')
    if pile_slug:
        pile = get_object_or_404(Pile, slug=pile_slug)
    else:
        # Randomly grab the first pile from the species
        pile = taxon.piles.order_by('id')[0]
    pilegroup = pile.pilegroup

    partner = which_partner(request)
    partner_species = None
    if partner:
        rows = PartnerSpecies.objects.filter(
            species=taxon, partner=partner).all()
        if rows:
            partner_species = rows[0]

    dkey_pages = dkey_models.Page.objects.filter(title=scientific_name)
    dkey_page = dkey_pages[0] if dkey_pages else None

    dkey_hybrids = (dkey_models.Hybrid.objects
                    .filter(Q(scientific_name1=scientific_name) |
                            Q(scientific_name2=scientific_name))
                    .order_by('number1', 'number2'))

    species_in_simple_key = (partner_species and partner_species.simple_key)
    key = request.GET.get('key')
    if not key:
        if species_in_simple_key:
            key = 'simple'
        else:
            key = 'full'

    species_images = botany.species_images(taxon)
    images = _images_with_copyright_holders(species_images)

    # Get the set of preview characteristics.

    plant_preview_characters = {
        ppc.character_id: ppc.order for ppc in
        PlantPreviewCharacter.objects.filter(pile=pile, partner_site=partner)
        }

    # Select ALL character values for this taxon.

    character_values = list(taxon.character_values.select_related(
            'character', 'character__character_group'))

    # Throw away values for characters that are not part of this pile.

    pile_ids = (None, pile.id)  # characters like 'habitat' have pile_id None

    # TODO: eventually remove this temporary code after the Remaining
    # Non-Monocots pile character value data is split and assigned.
    if pile.name.find('Remaining Non-Monocots') > -1:
        try:
            # Include the big pile which has the character value data.
            big_pile = Pile.objects.get(name='Remaining Non-Monocots')
            pile_ids = pile_ids + (big_pile.id,)
        except models.Pile.DoesNotExist:
            pass
    # (end of temporary code)

    character_values = [ v for v in character_values
                         if v.character.pile_id in pile_ids ]

    # Create a tree of character groups, characters, and values.

    get_group_name = lambda v: v.character.character_group.name
    get_character_name = lambda v: v.character.friendly_name

    character_values.sort(key=get_character_name)
    character_values.sort(key=get_group_name)

    all_characteristics = []
    for group_name, seq1 in groupby(character_values, get_group_name):
        characters = []

        for character_name, seq2 in groupby(seq1, get_character_name):
            seq2 = list(seq2)
            character = seq2[0].character  # arbitrary; all look the same
            characters.append({
                'group': character.character_group.name,
                'name': character.friendly_name,
                'values': sorted(_format_character_value(v) for v in seq2),
                'in_preview': character.id in plant_preview_characters,
                'preview_order': plant_preview_characters.get(character.id, -1),
                })

        all_characteristics.append({
            'name': group_name,
            'characters': characters
            })

    # Pick out the few preview characters for separate display.

    preview_characters = sorted((
        character
        for group in all_characteristics
        for character in group['characters']
        if character['in_preview']
        ), key=itemgetter('preview_order'))

    native_to_north_america = _native_to_north_america_status(taxon)

    return render_to_response('gobotany/species.html', {
           'pilegroup': pilegroup,
           'pile': pile,
           'scientific_name': scientific_name,
           'scientific_name_short': scientific_name_short,
           'taxon': taxon,
           'key': key,
           'species_in_simple_key': species_in_simple_key,
           'common_names': taxon.common_names.all(),  # view uses this 3 times
           'conservation_status_rows': (
                'endangered', 'threatened', 'special concern', 'historic',
                'rare', 'extirpated', 'invasive', 'prohibited',
                ),
           'dkey_hybrids': dkey_hybrids,
           'dkey_page': dkey_page,
           'images': images,
           'partner_heading': partner_species.species_page_heading
               if partner_species else None,
           'partner_blurb': partner_species.species_page_blurb
               if partner_species else None,
           'compact_multivalue_characters': COMPACT_MULTIVALUE_CHARACTERS,
           'brief_characteristics': preview_characters,
           'all_characteristics': all_characteristics,
           'epithet': epithet,
           'native_to_north_america': native_to_north_america
           }, context_instance=RequestContext(request))
Ejemplo n.º 24
0
def per_partner_template(request, template_path):
    partner = which_partner(request)
    return "{0}/{1}".format(partner.short_name, template_path)