Example #1
0
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
Example #2
0
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
Example #3
0
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
        }
Example #4
0
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}
Example #5
0
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})
Example #6
0
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})
Example #7
0
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,
    }
Example #8
0
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,
        }
Example #9
0
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 ])
Example #10
0
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 ])
Example #11
0
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,
    })
Example #12
0
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,
            })