def _taxon_image(image): if image is None: return json = { 'url': secure_url(image.image.url), 'type': image.image_type_name if hasattr(image, 'image_type_name') else image.image_type.name, 'rank': image.rank, 'title': image.alt, 'thumb_url': secure_url(image.thumb_small()), 'large_thumb_url': secure_url(image.thumb_large()), } return json
def _character_values(request, pile_slug, character_short_name): character = models.Character.objects.get(short_name=character_short_name) for cv in models.CharacterValue.objects.filter(character=character): image_url = '' thumbnail_url = '' if cv.image: image_url = secure_url(cv.image.url) thumbnail_url = secure_url(cv.image.thumbnail.absolute_url) yield { 'value': cv.value, 'friendly_text': cv.friendly_text, 'image_url': image_url, 'thumbnail_url': thumbnail_url }
def _character_values(request, pile_slug, character_short_name): character = models.Character.objects.get( short_name=character_short_name) for cv in models.CharacterValue.objects.filter( character=character): image_url = '' thumbnail_url = '' if cv.image: image_url = secure_url(cv.image.url) thumbnail_url = secure_url(cv.image.thumbnail.absolute_url) yield {'value': cv.value, 'friendly_text': cv.friendly_text, 'image_url': image_url, 'thumbnail_url': thumbnail_url}
def glossary_blob(request): """Return a dictionary of glossary terms and definitions. For now we omit glossary terms for which there are duplicates - like "Absent", which as of the writing of this comment has six definitions: Absent. no, spores are present throughout Absent. no horizontal stem Absent. no constrictions Absent. no branches Absent. no, all leaves on the horizontal stem are about the same size Absent. no stomates Since we cannot guess which of these six meanings is intended in an arbitrary context (like the glossary itself), we had better restrict ourselves for the moment to highlighting terms which *are* unique across our current glossary. """ glossaryterms = list( GlossaryTerm.objects.filter(highlight=True).extra( where=['CHAR_LENGTH(term) > 2'])) definitions = {} for gt in glossaryterms: gt.plural = inflector.plural(gt.term) definitions[gt.term.lower()] = gt.lay_definition definitions[gt.plural.lower()] = gt.lay_definition # Calling gt.image.url is very slow, because this is Django, so we # only do it once; this will work fine as long as we do not start # putting different images in different storages. prefix = None for gt in glossaryterms: gt.image_path = gt.__dict__['image'] if gt.image_path and prefix is None: try: url = gt.image.url prefix = url[:-len(gt.image_path)] prefix = secure_url(prefix) except ValueError: # Image not found in storage. pass images = {} for gt in glossaryterms: if not gt.image_path or prefix is None: continue images[gt.term.lower()] = prefix + gt.image_path images[gt.plural.lower()] = prefix + gt.image_path return jsonify({'definitions': definitions, 'images': images})
def glossary_blob(request): """Return a dictionary of glossary terms and definitions. For now we omit glossary terms for which there are duplicates - like "Absent", which as of the writing of this comment has six definitions: Absent. no, spores are present throughout Absent. no horizontal stem Absent. no constrictions Absent. no branches Absent. no, all leaves on the horizontal stem are about the same size Absent. no stomates Since we cannot guess which of these six meanings is intended in an arbitrary context (like the glossary itself), we had better restrict ourselves for the moment to highlighting terms which *are* unique across our current glossary. """ glossaryterms = list(GlossaryTerm.objects.filter(highlight=True) .extra(where=['CHAR_LENGTH(term) > 2'])) definitions = {} for gt in glossaryterms: gt.plural = inflector.plural(gt.term) definitions[gt.term.lower()] = gt.lay_definition definitions[gt.plural.lower()] = gt.lay_definition # Calling gt.image.url is very slow, because this is Django, so we # only do it once; this will work fine as long as we do not start # putting different images in different storages. prefix = None for gt in glossaryterms: gt.image_path = gt.__dict__['image'] if gt.image_path and prefix is None: try: url = gt.image.url prefix = url[:-len(gt.image_path)] prefix = secure_url(prefix) except ValueError: # Image not found in storage. pass images = {} for gt in glossaryterms: if not gt.image_path or prefix is None: continue images[gt.term.lower()] = prefix + gt.image_path images[gt.plural.lower()] = prefix + gt.image_path return jsonify({'definitions': definitions, 'images': images})
def _jsonify_character(character, pile_slug): return { 'friendly_name': character.friendly_name, 'short_name': character.short_name, 'value_type': character.value_type, 'unit': character.unit, 'character_group': character.character_group.name, 'question': character.question, 'hint': character.hint, 'image_url': (secure_url(character.image.url) if character.image else ''), 'pile_slug': pile_slug, }
def vectors_character(request, name): character = get_object_or_404(Character, short_name=name) mm = character.UNIT_MM.get(character.unit) if mm is None: mm = 1.0 values = character.character_values.all() tcvs = list(TaxonCharacterValue.objects.filter(character_value__in=values)) species = defaultdict(list) for tcv in tcvs: species[tcv.character_value_id].append(tcv.taxon_id) return jsonify([{ 'friendly_text': v.friendly_text, 'taxa': sorted(species[v.id]), 'choice': v.value_str, 'scalar': v.value_flt, 'min': v.value_min and v.value_min * mm, 'max': v.value_max and v.value_max * mm, # 'image_url': secure_url(v.image.url) if v.image else '', } for v in values ])
def dkey_images(request, slug): if slug == 'key-to-the-families': return jsonify({}) # Whether a dkey page displays groups of families, genera, or taxa, # we need to pull exactly one species to stand as the representative # for each taxon, and then grab all of the rank=1 content images for # those species. title = dkey_models.slug_to_title(slug) page = get_object_or_404(dkey_models.Page, title=title) taxa = None rank = None taxa_names = [] for lead in page.leads.all(): if lead.taxa_cache: rank, comma_list = lead.taxa_cache.split(':') taxa_names.extend(comma_list.split(',')) if rank is None: return jsonify({}) group_title = None if page.rank == 'group': group_title = page.title else: for ancestor in page.breadcrumb_cache.all(): if ancestor.rank == 'group': group_title = ancestor.title image_types_allowed = ['plant form'] image_types_allowed.extend(extra_image_types.get(group_title, ())) if rank == u'family': # See https://github.com/newfs/gobotany-app/issues/302 # and https://github.com/newfs/gobotany-app/issues/304 group_number = title.split()[-1] if page.rank == u'group' else u'' cursor = connection.cursor() cursor.execute( """ SELECT f.name, t.id, (SELECT id FROM core_taxon WHERE family_id = f.id LIMIT 1) FROM core_family f LEFT JOIN dkey_illustrativespecies i ON (i.group_number = %s AND f.name = i.family_name) LEFT JOIN core_taxon t ON (i.species_name = t.scientific_name) WHERE f.name IN %s""", ( group_number, tuple(taxa_names), )) rows = cursor.fetchall() family_map = {} for family_name, illustrative_taxon_id, random_taxon_id in rows: taxon_id = illustrative_taxon_id if taxon_id is None: taxon_id = random_taxon_id family_map[taxon_id] = family_name taxon_ids = family_map.keys() elif rank == u'genus': cursor = connection.cursor() cursor.execute( """ SELECT (SELECT id FROM core_taxon WHERE genus_id = g.id LIMIT 1) FROM core_genus g WHERE g.name IN %s""", (tuple(taxa_names), )) taxon_ids = [id for (id, ) in cursor.fetchall()] elif rank == u'species': taxa = Taxon.objects.filter(scientific_name__in=taxa_names) taxon_ids = [taxon.id for taxon in taxa] else: return jsonify({}) if taxa is None: taxa = Taxon.objects.filter(id__in=taxon_ids) ctype = ContentType.objects.get_for_model(Taxon) query = (ContentImage.objects.filter( content_type=ctype, object_id__in=taxon_ids, rank=1).filter( image_type__name__in=image_types_allowed).select_related( 'image_type')) image_map = {(image.object_id, image.image_type.name): image.thumb_small() for image in query} image_types = sorted(set(key[1] for key in image_map)) image_lists = [] for taxon in taxa: if rank == u'family': name = family_map[taxon.id] title = u'{}<br><i>({})</i>'.format(name, taxon.scientific_name) else: if rank == u'genus': name = taxon.genus_name() else: name = taxon.scientific_name title = u'<i>{}</i>'.format(taxon.scientific_name) image_list = [] for image_type in image_types: image = image_map.get((taxon.id, image_type)) if image is not None: image_list.append({ 'image_type': image_type, 'image_url': secure_url(image_map.get((taxon.id, image_type))), }) image_lists.append({ 'name': name, 'scientific_name': taxon.scientific_name, 'title': title, 'image_list': image_list, }) image_lists.sort(key=itemgetter('title')) return jsonify({ 'image_types': image_types, 'image_lists': image_lists, })
def dkey_images(request, slug): if slug == 'key-to-the-families': return jsonify({}) # Whether a dkey page displays groups of families, genera, or taxa, # we need to pull exactly one species to stand as the representative # for each taxon, and then grab all of the rank=1 content images for # those species. title = dkey_models.slug_to_title(slug) page = get_object_or_404(dkey_models.Page, title=title) taxa = None rank = None taxa_names = [] for lead in page.leads.all(): if lead.taxa_cache: rank, comma_list = lead.taxa_cache.split(':') taxa_names.extend(comma_list.split(',')) if rank is None: return jsonify({}) group_title = None if page.rank == 'group': group_title = page.title else: for ancestor in page.breadcrumb_cache.all(): if ancestor.rank == 'group': group_title = ancestor.title image_types_allowed = ['plant form'] image_types_allowed.extend(extra_image_types.get(group_title, ())) if rank == u'family': # See https://github.com/newfs/gobotany-app/issues/302 # and https://github.com/newfs/gobotany-app/issues/304 group_number = title.split()[-1] if page.rank == u'group' else u'' cursor = connection.cursor() cursor.execute(""" SELECT f.name, t.id, (SELECT id FROM core_taxon WHERE family_id = f.id LIMIT 1) FROM core_family f LEFT JOIN dkey_illustrativespecies i ON (i.group_number = %s AND f.name = i.family_name) LEFT JOIN core_taxon t ON (i.species_name = t.scientific_name) WHERE f.name IN %s""", (group_number, tuple(taxa_names),)) rows = cursor.fetchall() family_map = {} for family_name, illustrative_taxon_id, random_taxon_id in rows: taxon_id = illustrative_taxon_id if taxon_id is None: taxon_id = random_taxon_id family_map[taxon_id] = family_name taxon_ids = family_map.keys() elif rank == u'genus': cursor = connection.cursor() cursor.execute(""" SELECT (SELECT id FROM core_taxon WHERE genus_id = g.id LIMIT 1) FROM core_genus g WHERE g.name IN %s""", (tuple(taxa_names),)) taxon_ids = [ id for (id,) in cursor.fetchall() ] elif rank == u'species': taxa = Taxon.objects.filter(scientific_name__in=taxa_names) taxon_ids = [ taxon.id for taxon in taxa ] else: return jsonify({}) if taxa is None: taxa = Taxon.objects.filter(id__in=taxon_ids) ctype = ContentType.objects.get_for_model(Taxon) query = (ContentImage.objects .filter(content_type=ctype, object_id__in=taxon_ids, rank=1) .filter(image_type__name__in=image_types_allowed) .select_related('image_type') ) image_map = { (image.object_id, image.image_type.name): image.thumb_small() for image in query } image_types = sorted(set(key[1] for key in image_map)) image_lists = [] for taxon in taxa: if rank == u'family': name = family_map[taxon.id] title = u'{}<br><i>({})</i>'.format(name, taxon.scientific_name) else: if rank == u'genus': name = taxon.genus_name() else: name = taxon.scientific_name title = u'<i>{}</i>'.format(taxon.scientific_name) image_list = [] for image_type in image_types: image = image_map.get((taxon.id, image_type)) if image is not None: image_list.append({ 'image_type': image_type, 'image_url': secure_url(image_map.get((taxon.id, image_type))), }) image_lists.append({ 'name': name, 'scientific_name': taxon.scientific_name, 'title': title, 'image_list': image_list, }) image_lists.sort(key=itemgetter('title')) return jsonify({ 'image_types': image_types, 'image_lists': image_lists, })