def grant(cid): "Display grant field definitions for delete, and add field." call = get_call(cid) if not call: return utils.error("No such call.", flask.url_for("home")) if not allow_edit(call): return utils.error("You are not allowed to edit the call.") if utils.http_GET(): repeat_fields = [ f for f in call.get("grant", []) if f["type"] == constants.REPEAT ] return flask.render_template( "call/grant.html", call=call, repeat_fields=repeat_fields, reviews_count=utils.get_count("reviews", "call", call["identifier"]), ) elif utils.http_POST(): try: with CallSaver(call) as saver: saver.add_grant_field(flask.request.form) except ValueError as error: utils.flash_error(error) return flask.redirect(flask.url_for(".grant", cid=call["identifier"]))
def create(pid, username): "Create a new review for the proposal for the given reviewer." proposal = anubis.proposal.get_proposal(pid) if proposal is None: return utils.error("No such proposal.", flask.url_for("home")) call = anubis.call.get_call(proposal["call"]) try: if not allow_create(proposal): raise ValueError("You may not create a review for the proposal.") user = anubis.user.get_user(username=username) if user is None: raise ValueError("No such user.") if user["username"] not in call["reviewers"]: raise ValueError("User is not a reviewer in the call.") review = get_reviewer_review(proposal, user) if review is not None: utils.flash_message("The review already exists.") return flask.redirect(flask.url_for(".display", iuid=review["_id"])) if proposal["user"] == user["username"]: raise ValueError( "Reviewer not allowed to review their own proposal.") with ReviewSaver(proposal=proposal, user=user) as saver: pass except ValueError as error: utils.flash_error(error) return flask.redirect( flask.url_for("reviews.call_reviewer", cid=proposal["call"], username=username))
def edit(username): "Edit the user. Or delete the user." user = get_user(username=username) if user is None: return utils.error("No such user.", flask.url_for("home")) if not allow_edit(user): return utils.error("Access to user edit not allowed.") if utils.http_GET(): return flask.render_template("user/edit.html", user=user, allow_change_role=allow_change_role(user)) elif utils.http_POST(): try: with UserSaver(user) as saver: if flask.g.am_admin: email = flask.request.form.get("email") saver.set_email(email, require=bool(email)) if allow_change_role(user): saver.set_role(flask.request.form.get("role")) saver.set_call_creator( utils.to_bool(flask.request.form.get("call_creator"))) saver.set_givenname(flask.request.form.get("givenname")) saver.set_familyname(flask.request.form.get("familyname")) saver.set_gender(flask.request.form.get("gender")) saver.set_birthdate(flask.request.form.get("birthdate")) saver.set_degree(flask.request.form.get("degree")) saver.set_affiliation( flask.request.form.get("affiliation") or flask.request.form.get("affiliation_other")) saver.set_postaladdress( flask.request.form.get("postaladdress")) saver.set_phone(flask.request.form.get("phone")) except ValueError as error: utils.flash_error(error) return flask.redirect( flask.url_for(".display", username=user["username"])) elif utils.http_DELETE(): if not allow_delete(user): return utils.error( "Cannot delete the user account; admin or not empty.", flask.url_for(".display", username=username), ) flask.g.db.delete(user) utils.flash_message(f"Deleted user {username}.") if flask.g.am_admin: return flask.redirect(flask.url_for(".all")) else: return flask.redirect(flask.url_for("home"))
def unsubmit(pid): "Unsubmit the proposal." proposal = get_proposal(pid) if proposal is None: return utils.error("No such proposal.", flask.url_for("home")) if utils.http_POST(): try: with ProposalSaver(proposal) as saver: saver.set_unsubmitted() # Tests whether allowed or not. except ValueError as error: utils.flash_error(error) else: utils.flash_warning("Proposal was unsubmitted.") return flask.redirect(flask.url_for(".display", pid=pid))
def unfinalize(iuid): "Unfinalize the review for the proposal." try: review = get_review(iuid) except KeyError: return utils.error("No such review.", flask.url_for("home")) if not allow_unfinalize(review): return utils.error("You are not allowed to unfinalize this review.") if utils.http_POST(): try: with ReviewSaver(doc=review) as saver: saver["finalized"] = None except ValueError as error: utils.flash_error(error) return flask.redirect(flask.url_for(".display", iuid=review["_id"]))
def unfinalize(iuid): "Unfinalize the decision." try: decision = get_decision(iuid) except KeyError: return utils.error("No such decision.", flask.url_for("home")) if not allow_unfinalize(decision): return utils.error("You are not allowed to unfinalize this decision.") if utils.http_POST(): try: with DecisionSaver(doc=decision) as saver: saver["finalized"] = None except ValueError as error: utils.flash_error(error) return flask.redirect(flask.url_for(".display", iuid=decision["_id"]))
def unlock(gid): "Unlock the grant dossier to allow edits by the user." grant = get_grant(gid) if grant is None: return utils.error("No such grant.") if not allow_lock(grant): return utils.error("You are not allowed to unlock this grant dossier.") if utils.http_POST(): try: with GrantSaver(doc=grant) as saver: saver["locked"] = False except ValueError as error: utils.flash_error(error) return flask.redirect( flask.url_for(".display", gid=grant["identifier"]))
def edit(cid): "Edit the call, or delete it." call = get_call(cid) if not call: return utils.error("No such call.", flask.url_for("home")) if not allow_edit(call): return utils.error("You are not allowed to edit the call.") if utils.http_GET(): return flask.render_template( "call/edit.html", call=call, allow_identifier_edit=allow_identifier_edit(call), ) elif utils.http_POST(): try: with CallSaver(call) as saver: saver.set_identifier(flask.request.form.get("identifier")) saver.set_title(flask.request.form.get("title")) saver["description"] = flask.request.form.get("description") saver["home_description"] = ( flask.request.form.get("home_description").strip() or None ) saver["opens"] = utils.normalize_datetime( flask.request.form.get("opens") ) saver["closes"] = utils.normalize_datetime( flask.request.form.get("closes") ) saver["reviews_due"] = utils.normalize_datetime( flask.request.form.get("reviews_due") ) saver.edit_access(flask.request.form) call = saver.doc except ValueError as error: utils.flash_error(error) return flask.redirect(flask.url_for(".display", cid=call["identifier"])) elif utils.http_DELETE(): if not allow_delete(call): return utils.error("You are not allowed to delete the call.") utils.delete(call) utils.flash_message(f"Deleted call {call['identifier']}:{call['title']}.") return flask.redirect( flask.url_for("calls.owner", username=flask.g.current_user["username"]) )
def archive(iuid): "Archive the review for the proposal. Requires 'delete' privilege." try: review = get_review(iuid) except KeyError: return utils.error("No such review.", flask.url_for("home")) # In a sense similar to deleting, so requires same priviliege. if not allow_delete(review): return utils.error("You are not allowed to archive this review.") if utils.http_POST(): try: with ReviewSaver(doc=review) as saver: saver.set_archived() except ValueError as error: utils.flash_error(error) return flask.redirect(flask.url_for(".display", iuid=review["_id"]))
def decision(cid): "Display decision field definitions for delete, and add field." call = get_call(cid) if not call: return utils.error("No such call.", flask.url_for("home")) if not allow_edit(call): return utils.error("You are not allowed to edit the call.") if utils.http_GET(): return flask.render_template("call/decision.html", call=call) elif utils.http_POST(): try: with CallSaver(call) as saver: saver.add_decision_field(flask.request.form) except ValueError as error: utils.flash_error(error) return flask.redirect(flask.url_for(".decision", cid=call["identifier"]))
def documents(cid): "Display documents for delete, or add document (attachment file)." call = get_call(cid) if not call: return utils.error("No such call.", flask.url_for("home")) if not allow_edit(call): return utils.error("You are not allowed to edit the call.") if utils.http_GET(): return flask.render_template("call/documents.html", call=call) elif utils.http_POST(): infile = flask.request.files.get("document") if infile: description = flask.request.form.get("document_description") with CallSaver(call) as saver: saver.add_document(infile, description) else: utils.flash_error("No document selected.") return flask.redirect(flask.url_for(".display", cid=call["identifier"]))
def access(gid): "Edit the access privileges for the grant record." grant = get_grant(gid) if grant is None: return utils.error("No such grant.") if not allow_change_access(grant): return utils.error("You are not allowed to change access" " for this grant dossier.") call = anubis.call.get_call(grant["call"]) if utils.http_GET(): users = {} for user in grant.get("access_view", []): users[user] = False for user in grant.get("access_edit", []): users[user] = True return flask.render_template( "access.html", title=f"Grant {grant['identifier']}", url=flask.url_for(".access", gid=grant["identifier"]), users=users, back_url=flask.url_for(".display", gid=grant["identifier"]), ) elif utils.http_POST(): try: with GrantSaver(doc=grant) as saver: saver.set_access(form=flask.request.form) except ValueError as error: utils.flash_error(error) return flask.redirect(flask.url_for(".access", gid=grant["identifier"])) elif utils.http_DELETE(): try: with GrantSaver(doc=grant) as saver: saver.remove_access(form=flask.request.form) except ValueError as error: utils.flash_error(error) return flask.redirect(flask.url_for(".access", gid=grant["identifier"]))
def create(pid): "Create a decision for the proposal." proposal = anubis.proposal.get_proposal(pid) if proposal is None: return utils.error("No such proposal.", flask.url_for("home")) try: if not allow_create(proposal): raise ValueError("You may not create a decision for the proposal.") decision = get_decision(proposal.get("decision")) if decision is not None: utils.flash_message("The decision already exists.") return flask.redirect( flask.url_for(".display", iuid=decision["_id"])) with DecisionSaver(proposal=proposal) as saver: pass decision = saver.doc with anubis.proposal.ProposalSaver(proposal) as saver: saver["decision"] = decision["_id"] except ValueError as error: utils.flash_error(error) return flask.redirect(flask.url_for(".display", iuid=decision["_id"]))
def access(pid): "Edit the access privileges for the proposal record." proposal = get_proposal(pid) if proposal is None: return utils.error("No such proposal.", flask.url_for("home")) if not allow_edit(proposal): return utils.error("You are not allowed to edit this proposal.") call = anubis.call.get_call(proposal["call"]) if utils.http_GET(): users = {} for user in proposal.get("access_view", []): users[user] = False for user in proposal.get("access_edit", []): users[user] = True return flask.render_template( "access.html", title=f"Proposal {proposal['identifier']}", url=flask.url_for(".access", pid=proposal["identifier"]), users=users, back_url=flask.url_for(".display", pid=proposal["identifier"]), ) elif utils.http_POST(): try: with ProposalSaver(doc=proposal) as saver: saver.set_access(form=flask.request.form) except ValueError as error: utils.flash_error(error) return flask.redirect( flask.url_for(".access", pid=proposal["identifier"])) elif utils.http_DELETE(): try: with ProposalSaver(doc=proposal) as saver: saver.remove_access(form=flask.request.form) except ValueError as error: utils.flash_error(error) return flask.redirect( flask.url_for(".access", pid=proposal["identifier"]))
def unarchive(iuid): "Unarchive the review for the proposal. Requires 'delete' privilege." try: review = get_review(iuid) except KeyError: return utils.error("No such archived review.", flask.url_for("home")) if not allow_delete(review): return utils.error("You are not allowed to unarchive this review.") if get_reviewer_review( anubis.proposal.get_proposal(review["proposal"]), anubis.user.get_user(review["reviewer"]), ): return utils.error( "Unarchived review exists for proposal and reviewer.") if utils.http_POST(): try: with ReviewSaver(doc=review) as saver: saver.set_unarchived() except ValueError as error: utils.flash_error(error) return flask.redirect(flask.url_for(".display", iuid=review["_id"]))
def create(pid): "Create a grant dossier for the proposal." proposal = anubis.proposal.get_proposal(pid) if proposal is None: return utils.error("No such proposal.") try: if not allow_create(proposal): raise ValueError( "You may not create a grant dossier for the proposal.") grant = get_grant_proposal(pid) if grant is not None: utils.flash_message("The grant dossier already exists.") return flask.redirect( flask.url_for(".display", gid=grant["identifier"])) with GrantSaver(proposal=proposal) as saver: pass grant = saver.doc with anubis.proposal.ProposalSaver(proposal) as saver: saver["grant"] = grant["identifier"] except ValueError as error: utils.flash_error(error) return flask.redirect(flask.url_for(".display", gid=grant["identifier"]))
def grant_field(cid, fid): "Edit or delete the grant field definition." call = get_call(cid) if not call: return utils.error("No such call.", flask.url_for("home")) if not allow_edit(call): return utils.error("You are not allowed to edit the call.") if utils.http_POST(): try: with CallSaver(call) as saver: saver.edit_grant_field(fid, flask.request.form) except (KeyError, ValueError) as error: utils.flash_error(error) return flask.redirect(flask.url_for(".grant", cid=call["identifier"])) elif utils.http_DELETE(): try: with CallSaver(call) as saver: saver.delete_grant_field(fid) except ValueError as error: utils.flash_error(error) return flask.redirect(flask.url_for(".grant", cid=call["identifier"]))
def access(cid): "Edit the access privileges for the call." call = get_call(cid) if call is None: return utils.error("No such call.") if not allow_change_access(call): return utils.error("You are not allowed to change access for this call.") if utils.http_GET(): users = {} for user in call.get("access_view", []): users[user] = False for user in call.get("access_edit", []): users[user] = True return flask.render_template( "access.html", title=f"Call {call['identifier']}", url=flask.url_for(".access", cid=call["identifier"]), users=users, back_url=flask.url_for(".display", cid=call["identifier"]), ) elif utils.http_POST(): try: with CallSaver(doc=call) as saver: saver.set_access(form=flask.request.form) except ValueError as error: utils.flash_error(error) return flask.redirect(flask.url_for(".access", cid=call["identifier"])) elif utils.http_DELETE(): try: with CallSaver(doc=call) as saver: saver.remove_access(form=flask.request.form) except ValueError as error: utils.flash_error(error) return flask.redirect(flask.url_for(".access", cid=call["identifier"]))
def edit(pid): "Edit the proposal." proposal = get_proposal(pid) if proposal is None: return utils.error("No such proposal.", flask.url_for("home")) call = anubis.call.get_call(proposal["call"]) if utils.http_GET(): if not allow_edit(proposal): return utils.error("You are not allowed to edit this proposal.") return flask.render_template("proposal/edit.html", proposal=proposal, call=call) elif utils.http_POST(): if not allow_edit(proposal): return utils.error("You are not allowed to edit this proposal.") try: with ProposalSaver(proposal) as saver: saver["title"] = flask.request.form.get("_title") or None saver.set_fields_values(call["proposal"], form=flask.request.form) except ValueError as error: return utils.error(error) # If a repeat field was changed, then redisplay edit page. if saver.repeat_changed: return flask.redirect( flask.url_for(".edit", pid=proposal["identifier"])) if flask.request.form.get("_save") == "submit": proposal = get_proposal(pid, refresh=True) # Get up-to-date info. try: with ProposalSaver(proposal) as saver: saver.set_submitted() # Tests whether allowed or not. except ValueError as error: utils.flash_error(error) else: utils.flash_message("Proposal saved and submitted.") send_submission_email(proposal) elif allow_submit(proposal) and not proposal.get("submitted"): utils.flash_warning("Proposal was saved but not submitted." " You must explicitly submit it!") return flask.redirect( flask.url_for(".display", pid=proposal["identifier"])) elif utils.http_DELETE(): if not allow_delete(proposal): return utils.error("You are not allowed to delete this proposal.") decision = anubis.decision.get_decision(proposal.get("decision")) if decision: utils.delete(decision) reviews = utils.get_docs_view("reviews", "proposal", proposal["identifier"]) for review in reviews: utils.delete(review) utils.delete(proposal) utils.flash_message(f"Deleted proposal {pid}.") if flask.g.am_admin or flask.g.am_staff: url = flask.url_for("proposals.call", cid=call["identifier"]) else: url = flask.url_for("proposals.user", username=proposal["user"]) return flask.redirect(url)