def publication(publication):
    if not publication.published and not (current_user.is_authenticated and
                                          current_user.canEdit(publication)):
        raise NotFound()
    return render_vue(publication.serialize(),
                      title=publication.title,
                      menu='publications')
def scan(scan):
    if not scan.published and not (current_user.is_authenticated
                                   and current_user.canEdit(scan)):
        raise NotFound()
    data = hideScanFiles(scan.serialize())

    return render_vue(data, title=scan.scientific_name, menu='library')
def manage_publications(page=1):
    """View a list of publications with publish, edit, delete actions"""

    # Process delete request
    if request.method == 'POST':
        action = request.form.get('action')
        publication_id = request.form.get('id')
        if publication_id:
            publication = Publication.query.get(publication_id)
            ensureEditable(publication)

            if action == 'delete':
                db.session.delete(publication)
                db.session.commit()
            elif action == 'publish':
                publication.published = True
                db.session.commit()
            elif action == 'unpublish':
                publication.published = False
                db.session.commit()
        return redirect(request.full_path)

    per_page = 50
    offset = (page - 1) * per_page

    pub_year = request.args.get('pub_year')
    search = request.args.get('q')

    query = Publication.query

    if search:
        searchQuery = '%{0}%'.format(search)

        query = query.filter(
            db.or_(Publication.title.ilike(searchQuery),
                   Publication.authors.ilike(searchQuery)))
    if (pub_year):
        query = query.filter_by(pub_year=pub_year)
    publications = query.order_by(Publication.pub_year.desc()).paginate(
        page, per_page)
    data = {
        'publications': [
            pub.serialize() for pub in publications.items
            if current_user.canEdit(pub)
        ],
        'page':
        page,
        'total_pages':
        math.ceil(publications.total / per_page),
        'years': [
            y[0] for y in db.session.query(Publication.pub_year).order_by(
                Publication.pub_year.desc()).distinct().all()
        ],
        'q':
        search
    }
    return render_vue(data, title="Manage Publications", menu="publications")
def manage_uploads(page=1):
    """View a list of uploads with publish, edit, delete actions"""

    # Process delete request
    if request.method == 'POST':
        scan_id = request.form.get('delete')
        scan = Scan.query.get(scan_id)
        ensureEditable(scan)
        db.session.delete(scan)
        db.session.commit()
        return redirect(request.full_path)

    # To publish, we have to submit to the ScanUploadForm endpoint,
    # which requires a CSRF token. Construct the form to generate one.
    ScanUploadForm()

    per_page = 50
    offset = (page - 1) * per_page

    startswith = request.args.get('char')
    search = request.args.get('q')

    query = Scan.query

    if search:
        searchQuery = '%{0}%'.format(search)

        query = query.filter(
            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)))

    if (startswith):
        query = query.filter(Scan.scientific_name.startswith(startswith))
    scans = query.paginate(page, per_page)
    data = {
        'scans':
        [s.serialize() for s in scans.items if current_user.canEdit(s)],
        'page': page,
        'total_pages': math.ceil(scans.total / per_page),
        'csrf_token': g.csrf_token,
        'q': search
    }
    return render_vue(data, title="Manage Uploads", menu="library")
def ensureEditable(item):
    """ Throw Forbidden exception if the current user is not allowed to edit the given model """
    if not current_user.canEdit(item):
        raise Forbidden(
            'You cannot edit this item as you are not the original author.')