def library(page=1): per_page = 100 sort = request.args.get("sort") ontogenic_age = request.args.getlist("ontogenic_age") geologic_age = request.args.getlist("geologic_age") elements = request.args.getlist("elements") taxonomy = request.args.getlist("taxonomy") mine = 'mine' in request.args.keys() search = request.args.get('q') scanConditions = [Scan.published] if search: searchQuery = '%{0}%'.format(search) textSearch = db.or_(Scan.scientific_name.ilike(searchQuery), Scan.alt_name.ilike(searchQuery), Scan.specimen_id.ilike(searchQuery), Scan.specimen_location.ilike(searchQuery), Scan.description.ilike(searchQuery)) scanConditions.append(textSearch) for searchTags in [ontogenic_age, geologic_age, elements]: if len(searchTags) > 0: scanConditions.append( Scan.tags.any( Tag.taxonomy.startswith(searchTags[0]) if len(searchTags) == 1 else db.or_( * [Tag.taxonomy.startswith(term) for term in searchTags]))) if len(taxonomy) > 0: scanConditions.append(Scan.taxonomy.any(Taxonomy.id.in_(taxonomy))) if mine and current_user.is_authenticated: scanConditions.append(Scan.author_id == current_user.id) scanConditions = db.and_(*scanConditions) # This is annoying... if we're sorting by name it's just sort, # but if we're sorting by tag we need to group it all. # Put it under the `groups` key so the view knows it needs to render differently if (sort in ('geologic_age', 'ontogenic_age')): results = [(tag, tag.scans.filter(scanConditions).all()) for tag in Tag.query.filter_by(category=sort).all()] data = { 'groups': [{ 'group': tag.name, 'items': [s.serialize(full=False) for s in scans] } for (tag, scans) in results if len(scans) > 0] } else: query = Scan.scientific_name results = Scan.query.filter(scanConditions).order_by(query).paginate( page, per_page) data = { 'scans': [s.serialize(full=False) for s in results.items], 'page': page, 'total_pages': math.ceil(results.total / per_page) } data['tags'] = Tag.tree() data['tags']['taxonomy'] = Taxonomy.tree() data['q'] = search data[ 'showMine'] = current_user.is_authenticated and current_user.isContributor( ) out = render_vue(data, title="Scans", menu='library') return out