def inflate_hierarchy(doc):

    props = doc.get('properties', {})

    placetype = pt.placetype(props['wof:placetype'])
    ancestors = placetype.ancestors(roles=['common', 'common_optional', 'optional'])

    hierarchies = props.get('wof:hierarchy', [])
    hiers = []

    for hier in hierarchies:

        inflated = []

        for a in ancestors:

            rel = "%s_id" % a
            id = hier.get(rel, None)

            if id:
                inflated.append((a, get_by_id(id)))

        inflated.reverse()
        hiers.append(inflated)

    return hiers
def placetype(placetype):

    placetype = sanitize_str(placetype)

    if not pt.is_valid_placetype(placetype):
        flask.abort(404)

    placetype = pt.placetype(placetype)
    placetype_id = placetype.id()

    query = {
        'term': {
            'wof:placetype_id': placetype_id
        }
    }

    query = enfilterify(query)
    
    body = {
        'query': query,
    }

    args = {'per_page': 50}

    page = get_int('page')
    page = get_single(page)

    if page:
        args['page'] = page

    rsp = flask.g.search_idx.search(body, **args)

    pagination = rsp['pagination']
    docs = rsp['rows']

    facets = facetify(query)
    
    pagination_url = build_pagination_url()
    facet_url = pagination_url

    template_args = {
        'es_query': query,
        'placetype': placetype,
        'docs': docs,
        'pagination': pagination,
        'pagination_url': pagination_url,
        'facets': facets,
        'facet_url': facet_url
    }

    return flask.render_template('placetype.html', **template_args)
def enfilterify(query):

    filters = []

    placetype = get_str('placetype')
    iso = get_str('iso')

    tag = get_str('tag')
    category = get_str('category')

    locality = get_int('locality_id')
    region = get_int('region_id')

    if placetype:

        ids = []

        for p in placetype:

            if not pt.is_valid_placetype(p):
                logging.warning("invalid placetype %s" % p)
                flask.abort(404)

            placetype = pt.placetype(p)
            ids.append(placetype.id())

        if len(ids) == 1:

            filters.append({ 'term': {
                'wof:placetype_id' : ids[0]
            }})

        else:

            filters.append({ 'terms': {
                'wof:placetype_id' : ids
            }})


    if iso:

        if len(iso) == 1:

            iso = get_single(iso)
            iso = iso.lower()
            esc_iso = flask.g.search_idx.escape(iso)
            
            filters.append({ 'term': {
                'iso:country' : esc_iso
            }})

        else:

            esc_iso = []

            for i in iso:
                i = i.lower()
                esc_iso.append(flask.g.search_idx.escape(i))

            filters.append({ 'terms': {
                'iso:country' : esc_iso
            }})
                
    if tag:

        if len(tag) == 1:

            tag = get_single(tag)
            esc_tag = flask.g.search_idx.escape(tag)

            filters.append({ 'term': {
                'sg:tags' : esc_tag
            }})
        else:

            esc_tags = map(flask.g.search_idx.escape, tag)

            filters.append({ 'terms': {
                'sg:tags' : esc_tags
            }})

    if category:

        if len(category) == 1:
            category = get_single(category)
            esc_cat = flask.g.search_idx.escape(category)
            
            filters.append({ 'term': {
                'category' : esc_cat
            }})
        else:
            esc_cat = map(flask.g.search_idx.escape, category)

            filters.append({ 'terms': {
                'category' : esc_cat
            }})

    if locality:

        if len(locality) == 1:

            locality = get_single(locality)
            esc_loc = locality

            filters.append({ 'term': {
                'locality_id' : esc_loc
            }})
        else:

            esc_locs = locality

            filters.append({ 'terms': {
                'locality_id' : esc_locs
            }})

    if region:

        if len(region) == 1:

            region = get_single(region)
            esc_loc = region

            filters.append({ 'term': {
                'region_id' : esc_loc
            }})
        else:

            esc_locs = region

            filters.append({ 'terms': {
                'region_id' : esc_locs
            }})

    # oh elasticsearch... Y U MOON LANGUAGE?
    # https://github.com/elastic/elasticsearch/issues/1688#issuecomment-5415536

    if len(filters):

        query = {
            'filtered': {
                'query': query,
                'filter': { 'and': filters }
                }
        }

    return query