Exemplo n.º 1
0
def _toggle_shift_entry(user, shift):
    res = {}
    shift_entry = ShiftEntry.query.filter_by(user_id=user.id,
                                             shift_id=shift.id).first()

    if shift.role == Role.get_by_name('Bar') and \
      Role.get_by_name('Bar') not in Volunteer.get_for_user(current_user).trained_roles:
        return {
            'warning':
            'Missing required training',
            'message':
            'You must complete bar training before you can sign up for this shift'
        }

    if shift_entry:
        db.session.delete(shift_entry)
        res['operation'] = 'delete'
        res['message'] = 'Cancelled %s shift' % shift.role.name
    else:
        for v_shift in user.shift_entries:
            if shift.is_clash(v_shift.shift):
                res['warning'] = "WARNING: Clashes with an existing shift"

        shift.entries.append(ShiftEntry(user=user, shift=shift))
        res['operation'] = 'add'
        res['message'] = 'Signed up for %s shift' % shift.role.name

    return res
Exemplo n.º 2
0
def role(role_id):
    role = Role.query.get_or_404(role_id)
    current_volunteer = VolunteerUser.get_for_user(current_user)

    if request.method == "POST":
        if role_id in current_volunteer.interested_roles:
            current_volunteer.interested_roles.remove(role)
        else:
            current_volunteer.interested_roles.append(role)
        db.session.commit()
        flash("Your role list has been updated", "info")
        return redirect(url_for(".choose_role"))

    role_description_file = role_name_to_markdown_file(role.name)

    if path.exists(role_description_file):
        content = open(role_description_file, "r").read()
        description = Markup(
            markdown.markdown(content, extensions=["markdown.extensions.nl2br"])
        )
    else:
        description = None

    return render_template(
        "volunteer/role.html",
        description=description,
        role=role,
        current_volunteer=current_volunteer,
    )
Exemplo n.º 3
0
def choose_role():
    form = RoleSignupForm()

    current_volunteer = VolunteerUser.get_for_user(current_user)
    if not current_volunteer.over_18:
        roles = Role.query.filter_by(over_18_only=False)
    else:
        roles = Role.query

    form.add_roles(roles.order_by(Role.name).all())

    if form.validate_on_submit():
        current_role_ids = [r.id for r in current_volunteer.interested_roles]

        for r in form.roles:
            r_id = r._role.id
            if r.signup.data and r_id not in current_role_ids:
                current_volunteer.interested_roles.append(r._role)

            elif not r.signup.data and r_id in current_role_ids:
                current_volunteer.interested_roles.remove(r._role)

        db.session.commit()
        flash("Your role list has been updated", 'info')
        return redirect(url_for('.choose_role'))

    current_roles = current_volunteer.interested_roles.all()
    if current_roles:
        role_ids = [r.id for r in current_roles]
        form.select_roles(role_ids)

    return render_template('volunteer/choose_role.html', form=form)
Exemplo n.º 4
0
def choose_role():
    form = RoleSignupForm()

    current_volunteer = VolunteerUser.get_for_user(current_user)
    if not current_volunteer.over_18:
        roles = Role.query.filter_by(over_18_only=False)
    else:
        roles = Role.query

    form.add_roles(roles.order_by(Role.name).all())

    if form.validate_on_submit():
        current_role_ids = [r.id for r in current_volunteer.interested_roles]

        for r in form.roles:
            r_id = r._role.id
            if r.signup.data and r_id not in current_role_ids:
                current_volunteer.interested_roles.append(r._role)

            elif not r.signup.data and r_id in current_role_ids:
                current_volunteer.interested_roles.remove(r._role)

        db.session.commit()
        flash("Your role list has been updated", "info")
        return redirect(url_for(".choose_role"))

    current_roles = current_volunteer.interested_roles.all()
    if current_roles:
        role_ids = [r.id for r in current_roles]
        form.select_roles(role_ids)

    return render_template("volunteer/choose_role.html", form=form)
Exemplo n.º 5
0
def choose_role():
    form = RoleSignupForm()

    form.add_roles(Role.get_all())
    current_volunteer = VolunteerUser.get_for_user(current_user)

    if form.validate_on_submit():
        current_role_ids = [r.id for r in current_volunteer.interested_roles]

        for r in form.roles:
            r_id = r._role.id
            if r.signup.data and r_id not in current_role_ids:
                current_volunteer.interested_roles.append(r._role)

            elif not r.signup.data and r_id in current_role_ids:
                current_volunteer.interested_roles.remove(r._role)

        db.session.commit()
        flash("Your role list has been updated", 'info')
        return redirect(url_for('.choose_role'))

    current_roles = current_volunteer.interested_roles.all()
    if current_roles:
        role_ids = [r.id for r in current_roles]
        form.select_roles(role_ids)

    return render_template('volunteer/choose_role.html', form=form)
Exemplo n.º 6
0
def bar_training():
    bar = Role.query.filter_by(name="Bar").one()
    volunteer = Volunteer.get_for_user(current_user)

    trained = bar in volunteer.trained_roles

    params = {"token": current_user.bar_training_token, "name": current_user.name}
    url = app.config["BAR_TRAINING_FORM"] + "?" + urlencode(params)
    return render_template(
        "volunteer/training/bar-training.html", url=url, trained=trained
    )
Exemplo n.º 7
0
def bar_training():
    bar = Role.query.filter_by(name="Bar").one()
    volunteer = Volunteer.get_for_user(current_user)

    trained = (bar in volunteer.trained_roles)

    params = {
        'token': current_user.bar_training_token,
        'name': current_user.name,
    }
    url = app.config['BAR_TRAINING_FORM'] + '?' + urlencode(params)
    return render_template('volunteer/training/bar-training.html', url=url, trained=trained)
Exemplo n.º 8
0
def _get_interested_roles(user):
    roles = Role.get_all()
    volunteer = Volunteer.get_for_user(user)
    res = []

    for r in roles:
        to_add = r.to_dict()
        to_add["is_interested"] = r in volunteer.interested_roles
        to_add["is_trained"] = r in volunteer.trained_roles

        res.append(to_add)

    return res
Exemplo n.º 9
0
def bar_training():
    bar = Role.query.filter_by(name="Bar").one()
    volunteer = Volunteer.get_for_user(current_user)

    trained = (bar in volunteer.trained_roles)

    params = {
        'token': current_user.bar_training_token,
        'name': current_user.name,
    }
    url = app.config['BAR_TRAINING_FORM'] + '?' + urlencode(params)
    return render_template('volunteer/training/bar-training.html',
                           url=url,
                           trained=trained)
Exemplo n.º 10
0
def shift_json(shift_id):
    shift = Shift.query.get_or_404(shift_id)

    if request.method == "POST":
        override_user_id = request.args.get("override_user", default=None)
        if (current_user.has_permission("volunteer:admin")
                and override_user_id is not None):
            override_user = User.query.get_or_404(override_user_id)
            msg = _toggle_shift_entry(override_user, shift)
            msg["user"] = Volunteer.get_for_user(override_user).nickname
        else:
            msg = _toggle_shift_entry(current_user, shift)

        db.session.commit()
        return jsonify(msg)

    return jsonify(shift)
Exemplo n.º 11
0
def account():
    volunteer = VolunteerUser.get_for_user(current_user)
    if volunteer is None:
        return redirect(url_for('.sign_up'))

    form = VolunteerSignUpForm()

    if form.validate_on_submit():
        update_volunteer_from_form(volunteer, form)
        db.session.commit()
        return redirect(url_for('.account'))

    form.name.data = volunteer.nickname
    form.email.data = volunteer.volunteer_email
    form.phone_number.data = volunteer.volunteer_phone
    form.age.data = volunteer.age
    form.arrival.data = volunteer.planned_arrival
    form.departure.data = volunteer.planned_departure

    return render_template('volunteer/sign-up.html',
                            user=current_user, form=form)
Exemplo n.º 12
0
def choose_role():
    form = RoleSignupForm()

    current_volunteer = VolunteerUser.get_for_user(current_user)
    if not current_volunteer.over_18:
        roles = Role.query.filter_by(over_18_only=False)
    else:
        roles = Role.query

    form.add_roles(roles.order_by(Role.name).all())

    if form.validate_on_submit():
        current_role_ids = [r.id for r in current_volunteer.interested_roles]

        for r in form.roles:
            r_id = r._role.id
            if r.signup.data and r_id not in current_role_ids:
                current_volunteer.interested_roles.append(r._role)

            elif not r.signup.data and r_id in current_role_ids:
                current_volunteer.interested_roles.remove(r._role)

        db.session.commit()
        flash("Your role list has been updated", "info")
        return redirect(url_for(".choose_role"))

    current_roles = current_volunteer.interested_roles.all()
    if current_roles:
        role_ids = [r.id for r in current_roles]
        form.select_roles(role_ids)
    if uninterested_roles := [
        se.shift.role
        for se in current_user.shift_entries
        if se.shift.role not in current_roles
    ]:
        ui_roles_str = ", ".join([uir.name for uir in uninterested_roles])
        flash(
            f"You are still signed up for shifts for {ui_roles_str}. "
            + "Please cancel them from Shift sign-up if you don't want to do them."
        )
Exemplo n.º 13
0
def role(role_id):
    role = Role.query.get_or_404(role_id)
    current_volunteer = VolunteerUser.get_for_user(current_user)

    if request.method == "POST":
        if role_id in current_volunteer.interested_roles:
            current_volunteer.interested_roles.remove(role)
        else:
            current_volunteer.interested_roles.append(role)
        db.session.commit()
        flash("Your role list has been updated", "info")
        return redirect(url_for('.choose_role'))

    role_description_file = role_name_to_markdown_file(role.name)

    if path.exists(role_description_file):
        content = open(role_description_file, 'r').read()
        description = Markup(markdown.markdown(content, extensions=["markdown.extensions.nl2br"]))
    else:
        description = None

    return render_template('volunteer/role.html', description=description,
                           role=role, current_volunteer=current_volunteer)
Exemplo n.º 14
0
def bar_training():
    bar = Role.query.filter_by(name="Bar").one_or_none()
    cybar = Role.query.filter_by(name="Cybar").one_or_none()
    if bar is None or cybar is None:
        abort(404)
    volunteer = Volunteer.get_for_user(current_user)
    trained = bar in volunteer.trained_roles

    training_json_path = app.config.get("BAR_TRAINING_JSON",
                                        "models/fixtures/training/bar.json")
    training_json = load_training_json(training_json_path)
    if training_json is None:  # Error loading training data
        app.logger.error(
            f"Bar training failed -- unable to load JSON: '{training_json_path}'"
        )
        abort(404)

    global question_data  # Otherwise we can't access it in the form validator
    question_data = build_questions(training_json)
    form = TrainingForm()
    form.add_questions(question_data)

    if form.validate_on_submit():
        if trained:  # The user might be re-doing the traing, no need to rewrite DB
            flash("You answered all the questions correctly!")
        else:
            app.logger.info(f"{str(current_user)} passed the bar training.")
            bar.trained_volunteers.append(volunteer)
            cybar.trained_volunteers.append(volunteer)
            db.session.commit()
            flash("Your completion of bar training has been saved.")
        return redirect(url_for(".bar_training"))

    # The template takes a list of pages which it will build sequentially, start
    # building this list now.
    pages = []
    page_num = 0

    for json_page in training_json["pages"]:
        page = {}
        page_num += 1
        page["number"] = page_num
        page["content"] = load_training_markdown(json_page["content"])

        if page["content"] is None:
            app.logger.error(
                f"Bar training failed -- unable to load Markdown: '{json_page['content']}'"
            )
            abort(404)

        page["questions"] = json_page["questions"]
        pages.append(page)

    return render_template(
        "volunteer/training/bar-training.html",
        trained=trained,
        form=form,
        pages=pages,
        last_page=len(pages),
        volunteer=volunteer,
    )
Exemplo n.º 15
0
def bar_training_check():
    volunteer = Volunteer.get_for_user(current_user)
    bar = Role.query.filter_by(name="Bar").one()
    return json.dumps(bar in volunteer.trained_roles)
Exemplo n.º 16
0
def bar_training_webhook(tag):
    if not hmac.compare_digest(get_auth_tag(), tag):
        abort(401)

    if request.method == 'GET':
        return ('', 200)

    app.logger.debug('Bar training webhook called with %s', request.data)
    json_data = json.loads(request.data.decode('utf-8'))
    if json_data.get('event_type') != 'form_response':
        # Don't care about this event type
        return ('', 200)

    response = json_data['form_response']
    form_id = response['form_id']
    if form_id != app.config['BAR_TRAINING_FORM'].rsplit('/', 1)[1]:
        return ('', 200)

    app.logger.info("Received form with hidden parameters %s",
                    response['hidden'])
    token = response['hidden'].get('token')
    if not token:
        return ('', 200)
    user = User.get_by_bar_training_token(token)

    if not user.volunteer:
        return ('', 200)

    assert response['definition']['id'] == form_id

    # response['calculated']['score'] is the number of answered questions
    # the "correct" answers have just been implemented as flow redirects

    answers = response['answers']
    actual_answers = {
        'IqrW3FemheSD': "More than 0.5%",
        'tp0LL9XwEu41': "Protection of the environment",
        'tb9aGkLhJCJ0':
        "In day-to-day control of a particular licensed premises",
        'yB9izDMlu8N6': "No",
        'xy8AJqMKZAOH': "PASS hologram",
        'YHOch7ksAKax': "£90",
        'YX1fDJQOKOmQ': "60 minutes",
        'z5RRMJhZiYJG':
        "Details of the licensable activities to be held at the premises",
        'bmfSCzY4xQHe': "Outside the times stated in the premises licence",
        'ODyrmHU3XR2f': "2",
        'lToop6d3nun2': "18",
        'iZeKUVN9n33f': "Staggering or an inability to walk",
    }
    answers = {}
    for answer in response['answers']:
        if answer['type'] == 'choice':
            answers[answer['field']['id']] = answer['choice']['label']

    correct_answers = [
        id for id, a in answers.items() if actual_answers[id] == a
    ]

    if len(correct_answers) == len(actual_answers):
        app.logger.info("%s passed the training", user)
        bar = Role.query.filter_by(name="Bar").one()
        bar.trained_volunteers.append(Volunteer.get_for_user(user))
        db.session.commit()

    app.logger.info("%s failed the training", user)

    return ('', 200)
Exemplo n.º 17
0
def bar_training_check():
    volunteer = Volunteer.get_for_user(current_user)
    bar = Role.query.filter_by(name="Bar").one()
    return json.dumps(bar in volunteer.trained_roles)
Exemplo n.º 18
0
def bar_training_webhook(tag):
    if not hmac.compare_digest(get_auth_tag(), tag):
        abort(401)

    if request.method == 'GET':
        return ('', 200)

    app.logger.debug('Bar training webhook called with %s', request.data)
    json_data = json.loads(request.data.decode('utf-8'))
    if json_data.get('event_type') != 'form_response':
        # Don't care about this event type
        return ('', 200)

    response = json_data['form_response']
    form_id = response['form_id']
    if form_id != app.config['BAR_TRAINING_FORM'].rsplit('/', 1)[1]:
        return ('', 200)

    app.logger.info("Received form with hidden parameters %s", response['hidden'])
    token = response['hidden'].get('token')
    if not token:
        return ('', 200)
    user = User.get_by_bar_training_token(token)

    if not user.volunteer:
        return ('', 200)

    assert response['definition']['id'] == form_id

    # response['calculated']['score'] is the number of answered questions
    # the "correct" answers have just been implemented as flow redirects

    answers = response['answers']
    actual_answers = {
        'IqrW3FemheSD': "More than 0.5%",
        'tp0LL9XwEu41': "Protection of the environment",
        'tb9aGkLhJCJ0': "In day-to-day control of a particular licensed premises",
        'yB9izDMlu8N6': "No",
        'xy8AJqMKZAOH': "PASS hologram",
        'YHOch7ksAKax': "£90",
        'YX1fDJQOKOmQ': "60 minutes",
        'z5RRMJhZiYJG': "Details of the licensable activities to be held at the premises",
        'bmfSCzY4xQHe': "Outside the times stated in the premises licence",
        'ODyrmHU3XR2f': "2",
        'lToop6d3nun2': "18",
        'iZeKUVN9n33f': "Staggering or an inability to walk",
    }
    answers = {}
    for answer in response['answers']:
        if answer['type'] == 'choice':
            answers[answer['field']['id']] = answer['choice']['label']

    correct_answers = [id for id, a in answers.items() if actual_answers[id] == a]

    if len(correct_answers) == len(actual_answers):
        app.logger.info("%s passed the training", user)
        bar = Role.query.filter_by(name="Bar").one()
        bar.trained_volunteers.append(Volunteer.get_for_user(user))
        db.session.commit()

    app.logger.info("%s failed the training", user)

    return ('', 200)
Exemplo n.º 19
0
def bar_training_webhook(tag):
    if not hmac.compare_digest(get_auth_tag(), tag):
        abort(401)

    if request.method == "GET":
        return ("", 200)

    app.logger.debug("Bar training webhook called with %s", request.data)
    json_data = json.loads(request.data.decode("utf-8"))
    if json_data.get("event_type") != "form_response":
        # Don't care about this event type
        return ("", 200)

    response = json_data["form_response"]
    form_id = response["form_id"]
    if form_id != app.config["BAR_TRAINING_FORM"].rsplit("/", 1)[1]:
        return ("", 200)

    app.logger.info("Received form with hidden parameters %s",
                    response["hidden"])
    token = response["hidden"].get("token")
    if not token:
        return ("", 200)
    user = User.get_by_bar_training_token(token)

    if not user.volunteer:
        return ("", 200)

    assert response["definition"]["id"] == form_id

    # response['calculated']['score'] is the number of answered questions
    # the "correct" answers have just been implemented as flow redirects

    answers = response["answers"]
    actual_answers = {
        "IqrW3FemheSD": "More than 0.5%",
        "tp0LL9XwEu41": "Protection of the environment",
        "tb9aGkLhJCJ0":
        "In day-to-day control of a particular licensed premises",
        "yB9izDMlu8N6": "No",
        "xy8AJqMKZAOH": "PASS hologram",
        "YHOch7ksAKax": "£90",
        "YX1fDJQOKOmQ": "60 minutes",
        "z5RRMJhZiYJG":
        "Details of the licensable activities to be held at the premises",
        "bmfSCzY4xQHe": "Outside the times stated in the premises licence",
        "ODyrmHU3XR2f": "2",
        "lToop6d3nun2": "18",
        "iZeKUVN9n33f": "Staggering or an inability to walk",
    }
    answers = {}
    for answer in response["answers"]:
        if answer["type"] == "choice":
            answers[answer["field"]["id"]] = answer["choice"]["label"]

    correct_answers = [
        id for id, a in answers.items() if actual_answers[id] == a
    ]

    if len(correct_answers) == len(actual_answers):
        app.logger.info("%s passed the training", user)
        bar = Role.query.filter_by(name="Bar").one()
        bar.trained_volunteers.append(Volunteer.get_for_user(user))
        db.session.commit()

    app.logger.info("%s failed the training", user)

    return ("", 200)