def get_open_calls(): "Return a list of open calls, sorted according to configuration." # More computationally efficient to use closes date for first selection. result = [ anubis.call.set_tmp(r.doc) for r in flask.g.db.view( "calls", "closes", startkey=utils.normalized_local_now(), endkey="ZZZZZZ", include_docs=True, ) ] # Exclude not yet open calls. result = [ doc for doc in result if (doc["tmp"]["is_open"] or doc["tmp"]["is_closed"]) ] order_key = flask.current_app.config["CALLS_OPEN_ORDER_KEY"] if order_key == "closes": result.sort(key=lambda k: (k["closes"], k["title"])) elif order_key == "title": result.sort(key=lambda k: k["title"]) elif order_key == "identifier": result.sort(key=lambda k: k["identifier"]) else: result.sort(key=lambda k: k["identifier"]) return result
def unpublished(): "Unpublished calls; undefined opens and/or closes date, or not yet published." calls = [ anubis.call.set_tmp(r.doc) for r in flask.g.db.view("calls", "undefined", include_docs=True) ] calls.extend([ anubis.call.set_tmp(r.doc) for r in flask.g.db.view( "calls", "opens", startkey=utils.normalized_local_now(), endkey="ZZZZZZ", include_docs=True, ) ]) return flask.render_template("calls/unpublished.html", calls=calls)
def allow_view_decisions(call): """The admin, staff and call owner may view all decisions in the call. Reviewer may view all decisions in a call once the review due date has passed; this should reduce confusion. """ if not flask.g.current_user: return False if flask.g.am_admin: return True if flask.g.am_staff: return True if am_owner(call): return True due = call.get("reviews_due") if due: return am_reviewer(call) and utils.normalized_local_now() > due return False
def closed(): "Closed calls." calls = [ anubis.call.set_tmp(r.doc) for r in flask.g.db.view( "calls", "closes", startkey="", endkey=utils.normalized_local_now(), include_docs=True, ) ] return flask.render_template( "calls/closed.html", calls=calls, # Functions, not values, are passed. allow_view_proposals=anubis.call.allow_view_proposals, allow_view_reviews=anubis.call.allow_view_reviews, allow_view_grants=anubis.call.allow_view_grants, )
def set_tmp(call): """Set the temporary, non-saved values for the call. Returns the call object. """ tmp = {} # Set the current state of the call, computed from open/close and today. if call["opens"]: if call["opens"] > utils.normalized_local_now(): tmp["is_open"] = False tmp["is_closed"] = False tmp["text"] = "Not yet open." tmp["color"] = "secondary" elif call["closes"]: remaining = utils.days_remaining(call["closes"]) if remaining > 7: tmp["is_open"] = True tmp["is_closed"] = False tmp["text"] = f"{remaining:.0f} days remaining." tmp["color"] = "success" elif remaining >= 2: tmp["is_open"] = True tmp["is_closed"] = False tmp["text"] = f"{remaining:.0f} days remaining." tmp["color"] = "warning" elif remaining >= 5.0 / 24.0: tmp["is_open"] = True tmp["is_closed"] = False tmp["text"] = f"{int(24*remaining):.0f} hours remaining." tmp["color"] = "danger" elif remaining >= 1.0 / 24.0: tmp["is_open"] = True tmp["is_closed"] = False tmp["text"] = f"{24*remaining:.1f} hours remaining." tmp["color"] = "danger" elif remaining >= 0: tmp["is_open"] = True tmp["is_closed"] = False tmp["text"] = f"{24*60*remaining:.0f} minutes remaining." tmp["color"] = "danger" else: tmp["is_open"] = False tmp["is_closed"] = True tmp["text"] = "Closed." tmp["color"] = "dark" else: tmp["is_open"] = True tmp["is_closed"] = False tmp["text"] = "No closing date set." tmp["color"] = "secondary" else: if call["closes"]: tmp["is_open"] = False tmp["is_closed"] = False tmp["text"] = "No open date set." tmp["color"] = "secondary" else: tmp["is_open"] = False tmp["is_closed"] = False tmp["text"] = "No open or close dates set." tmp["color"] = "secondary" tmp["is_published"] = tmp["is_open"] or tmp["is_closed"] call["tmp"] = tmp return call