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)
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), )
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)
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'})
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'})
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, })
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" )
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')
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')
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 ''
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 ''
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))
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))
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))
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]), })
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)
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))
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, })
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]), })
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
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)
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)
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))
def per_partner_template(request, template_path): partner = which_partner(request) return "{0}/{1}".format(partner.short_name, template_path)