Exemple #1
0
def handle_done(treatment, template=None, response_to_result_func=None):
    app.logger.debug("handle_done")
    if template is None:
        template = f"txx/{BASE}.done.html"
    if response_to_result_func is None:
        response_to_result_func = prop_to_prop_result
    worker_code_key = f"{BASE}_worker_code"
    worker_bonus_key = f"{BASE}_worker_bonus"
    cookie_obj = get_cookie_obj(BASE)
    ai_cookie_obj = get_cookie_obj(AI_COOKIE_KEY)
    if not cookie_obj.get(BASE, None):
        flash("Sorry, you are not allowed to use this service. ^_^")
        return render_template("error.html")
    if not (cookie_obj.get("worker_code")):
        job_id = cookie_obj["job_id"]
        worker_code = generate_completion_code(base=BASE, job_id=job_id)
        proposal = cookie_obj["proposal"]
        proposal["completion_code"] = worker_code
        proposal.update(ai_cookie_obj.get("ai_proposal", {}))
        row_info = cookie_obj["row_info"]
        worker_id = cookie_obj["worker_id"]
        row_info = get_row(get_db(), job_id, worker_id, TREATMENT)
        offer = proposal["offer_dss"]

        min_offer = row_info["min_offer"]
        worker_bonus = 0
        if offer >= min_offer:
            worker_bonus = 5
        prop_result = response_to_result_func(proposal,
                                              job_id=job_id,
                                              worker_id=worker_id,
                                              row_data=row_info)
        prop_result["worker_bonus"] = worker_bonus
        try:
            save_result2file(
                get_output_filename(base=BASE,
                                    job_id=job_id,
                                    treatment=treatment), prop_result)
        except Exception as err:
            app.log_exception(err)
        try:
            save_result2db(table=get_table(base=BASE,
                                           job_id=job_id,
                                           schema="result",
                                           treatment=treatment),
                           response_result=prop_result,
                           unique_fields=["worker_id"])
            #increase_worker_bonus(job_id=job_id, worker_id=worker_id, bonus_cents=worker_bonus, con=get_db("DB"))
        except Exception as err:
            app.log_exception(err)
        cookie_obj.clear()

        cookie_obj[BASE] = True
        cookie_obj["worker_id"] = worker_id
        cookie_obj[worker_bonus_key] = cents_repr(worker_bonus)
        cookie_obj[worker_code_key] = worker_code
    req_response = make_response(
        render_template(template, worker_code=cookie_obj[worker_code_key]))
    set_cookie_obj(req_response, BASE, cookie_obj)
    return req_response
Exemple #2
0
def handle_check(treatment):
    app.logger.debug("handle_check")
    MODEL_INFOS_KEY = f"{TREATMENTS_MODEL_REFS[treatment.upper()]}_MODEL_INFOS"
    cookie_obj = get_cookie_obj(BASE)
    if not cookie_obj.get(BASE):
        flash("Sorry, you are not allowed to use this service. ^_^")
        return render_template("error.html")
    ai_cookie_obj = get_cookie_obj(AI_COOKIE_KEY)
    if not ai_cookie_obj.get(BASE):
        # Use another cookie to reduce chances of growing over the cookie limit
        ai_cookie_obj[BASE] = True
        ai_proposal = {
            "ai_calls_best_offer_probability": [],
            "ai_calls_acceptance_probability": [],
            "ai_calls_offer": [],
            "ai_calls_time": [],
            "ai_calls_count_repeated": 0
        }
        ai_cookie_obj["row_info"] = {
            "ai_offer": cookie_obj["row_info"]["ai_offer"]
        }
        ai_cookie_obj["ai_proposal"] = ai_proposal
    ai_proposal = ai_cookie_obj["ai_proposal"]
    offer = int(request.args.get("offer", 0))
    ai_offer = int(ai_cookie_obj["row_info"]["ai_offer"])
    model_infos = app.config[MODEL_INFOS_KEY]
    acceptance_probability = get_acceptance_probability(
        ai_offer=ai_offer,
        offer=offer,
        accuracy=model_infos["acc"],
        train_err_pdf=model_infos["train_err_pdf"],
        train_pdf=model_infos["pdf"])
    best_offer_probability = get_best_offer_probability(
        ai_offer=ai_offer,
        offer=offer,
        accuracy=model_infos["acc"],
        train_err_pdf=model_infos["train_err_pdf"])

    ai_proposal["ai_calls_count_repeated"] += 1
    if offer not in ai_proposal["ai_calls_offer"]:
        ai_proposal["ai_calls_offer"].append(offer)
        ai_proposal["ai_calls_time"].append(time.time())
        ai_proposal["ai_calls_best_offer_probability"].append(
            round(best_offer_probability, 4))
        ai_proposal["ai_calls_acceptance_probability"].append(
            round(acceptance_probability, 4))
    ai_cookie_obj["ai_proposal"] = ai_proposal

    resp_data = {
        "offer": offer,
        "acceptance_probability": acceptance_probability,
        "best_offer_probability": best_offer_probability
    }
    if request.args.get("secret_key_hash") == get_secret_key_hash():
        resp_data["ai_offer"] = ai_offer
    req_response = make_response(jsonify(resp_data))
    set_cookie_obj(req_response, AI_COOKIE_KEY, ai_cookie_obj)
    return req_response
Exemple #3
0
def handle_feedback(treatment,
                    template=None,
                    messages=None,
                    feedback_accuracy_scalas=None,
                    resp_feedback_fields=None):
    app.logger.debug("handle_index_dss")
    cookie_obj = get_cookie_obj(BASE)
    if resp_feedback_fields is None:
        resp_feedback_fields = [
            "feedback_alternative", "feedback_fairness", "feedback_accuracy"
        ]
    if messages is None:
        messages = []
    if template is None:
        template = f"txx/resp_dss_feedback.html"
    if feedback_accuracy_scalas is None:
        feedback_accuracy_scalas = AI_FEEDBACK_ACCURACY_RESPONDER_SCALAS
    if request.method == "POST":
        response = cookie_obj["response"]
        for field in resp_feedback_fields:
            response[field] = request.form[field]
        cookie_obj['response'] = response
        req_response = make_response(
            redirect(url_for(f"{treatment}.resp.done", **request.args)))
        set_cookie_obj(req_response, BASE, cookie_obj)
        return req_response
    req_response = make_response(
        render_template(template,
                        offer_values=OFFER_VALUES,
                        scalas=AI_FEEDBACK_SCALAS,
                        accuracy_scalas=feedback_accuracy_scalas,
                        form=FlaskForm()))
    set_cookie_obj(req_response, BASE, cookie_obj)
    return req_response
Exemple #4
0
def handle_feedback(treatment,
                    template=None,
                    messages=None,
                    alternative_affirmation=None):
    app.logger.debug("handle_index_dss")
    cookie_obj = get_cookie_obj(BASE)
    worker_code_key = f"{BASE}_worker_code"
    worker_id = request.args.get("worker_id", "na")
    if messages is None:
        messages = []
    if template is None:
        template = f"txx/prop_dss_feedback.html"
    if request.method == "POST":
        proposal = cookie_obj["proposal"]
        # for some treatment there is no alternative feedback
        proposal["feedback_alternative"] = request.form.get(
            "feedback_alternative")
        proposal["feedback_understanding"] = request.form[
            "feedback_understanding"]
        proposal["feedback_explanation"] = request.form["feedback_explanation"]
        proposal["feedback_accuracy"] = request.form["feedback_accuracy"]
        req_response = make_response(
            redirect(url_for(f"{treatment}.prop.done", **request.args)))
        set_cookie_obj(req_response, BASE, cookie_obj)
        return req_response
    req_response = make_response(
        render_template(template,
                        offer_values=OFFER_VALUES,
                        scalas=AI_FEEDBACK_SCALAS,
                        accuracy_scalas=AI_FEEDBACK_ACCURACY_PROPOSER_SCALAS,
                        alternative_affirmation=alternative_affirmation))
    set_cookie_obj(req_response, BASE, cookie_obj)
    return req_response
Exemple #5
0
def handle_done(treatment, template=None, no_features=None):
    app.logger.debug("handle_done")
    if template is None:
        template = f"txx/resp.done.html"

    if no_features is None:
        completion_code_base = BASE
    else:
        # survey should not require tasks
        completion_code_base = BASE + "NF"
    cookie_obj = get_cookie_obj(BASE)
    worker_code_key = f"{BASE}_worker_code"
    if not cookie_obj.get(BASE, None):
        flash("Sorry, you are not allowed to use this service. ^_^")
        return render_template("error.html")
    if not cookie_obj.get(worker_code_key):
        job_id = cookie_obj["job_id"]
        worker_code = generate_completion_code(completion_code_base, job_id)
        response = cookie_obj["response"]
        response["completion_code"] = worker_code
        worker_id = cookie_obj["worker_id"]
        resp_result = resp_to_resp_result(response,
                                          job_id=job_id,
                                          worker_id=worker_id)
        try:
            #save_resp_result(TUBE_RES_FILENAME, resp_result)
            save_result2file(
                get_output_filename(BASE, job_id, treatment=treatment),
                resp_result)
        except Exception as err:
            app.log_exception(err)
        try:
            #save_resp_result2db(get_db("RESULT"), resp_result, job_id)
            save_result2db(table=get_table(base=BASE,
                                           job_id=job_id,
                                           schema="result",
                                           treatment=treatment),
                           response_result=resp_result,
                           unique_fields=["worker_id"])
            increase_worker_bonus(job_id=job_id,
                                  worker_id=worker_id,
                                  bonus_cents=0)
        except Exception as err:
            app.log_exception(err)
        cookie_obj.clear()

        cookie_obj[BASE] = True
        cookie_obj["worker_id"] = worker_id
        cookie_obj[worker_code_key] = worker_code

        auto_finalize = cookie_obj.get("auto_finalize",
                                       request.args.get("auto_finalize"))
        if auto_finalize and no_features:  # and base=="hexaco":
            #NOTE: there is an import here ^_^
            finalize_resp(job_id, worker_id, treatment)

    req_response = make_response(
        render_template(template, worker_code=cookie_obj[worker_code_key]))
    set_cookie_obj(req_response, BASE, cookie_obj)
    return req_response
Exemple #6
0
def handle_index_dss(treatment,
                     template=None,
                     messages=None,
                     dss_only=False,
                     feedback_accuracy_scalas=None):
    app.logger.debug("handle_index_dss")
    if messages is None:
        messages = []
    if template is None:
        template = f"txx/resp_dss.html"
    if feedback_accuracy_scalas is None:
        feedback_accuracy_scalas = AI_FEEDBACK_ACCURACY_RESPONDER_SCALAS
    cookie_obj = get_cookie_obj(BASE)
    worker_code_key = f"{BASE}_worker_code"
    worker_id = request.args.get("worker_id", "na")
    job_id = request.args.get("job_id", "na")
    # The task was already completed, so we skip to the completion code display
    if cookie_obj.get(BASE) and cookie_obj.get(
            worker_code_key) and cookie_obj.get("worker_id") == worker_id:
        req_response = redirect(url_for(f"{treatment}.resp.done"))
        return req_response
    if request.method == "GET":
        app.logger.debug(
            f"handle_index: job_id:{job_id}, worker_id:{worker_id} ")
        if dss_only:
            # for treatments T2x
            cookie_obj['response'] = HHI_Resp_ADM()
            cookie_obj["worker_id"] = worker_id
            cookie_obj["job_id"] = job_id

        else:
            cookie_obj["response"]["time_start_dss"] = time.time()

        for message in messages:
            flash(message)
    if request.method == "POST":
        response = cookie_obj["response"]
        if dss_only:
            response["time_stop"] = time.time()
            response["min_offer"] = int(request.form["min_offer"])
        response["time_stop_dss"] = time.time()
        response["min_offer_dss"] = int(request.form["min_offer"])
        cookie_obj['response'] = response
        req_response = make_response(
            redirect(url_for(f"{treatment}.resp.feedback", **request.args)))
        set_cookie_obj(req_response, BASE, cookie_obj)
        return req_response

    cookie_obj[BASE] = True
    req_response = make_response(
        render_template(template,
                        offer_values=OFFER_VALUES,
                        form=ResponderForm(),
                        scalas=AI_FEEDBACK_SCALAS,
                        accuracy_scalas=feedback_accuracy_scalas))
    set_cookie_obj(req_response, BASE, cookie_obj)
    return req_response
Exemple #7
0
def handle_index(treatment,
                 template=None,
                 messages=None,
                 has_dss_component=False):
    app.logger.debug("handle_index")
    if messages is None:
        messages = []
    if template is None:
        template = f"txx/resp.html"
    cookie_obj = get_cookie_obj(BASE)
    worker_code_key = f"{BASE}_worker_code"
    worker_id = request.args.get("worker_id", "na")
    job_id = request.args.get("job_id", "na")

    close_row(get_db(), job_id, 2, treatment)

    # The task was already completed, so we skip to the completion code display
    if cookie_obj.get(BASE) and cookie_obj.get(
            worker_code_key) and cookie_obj.get("worker_id") == worker_id:
        req_response = redirect(url_for(f"{treatment}.resp.done"))
        return req_response
    if request.method == "GET":
        app.logger.debug(
            f"handle_index: job_id:{job_id}, worker_id:{worker_id} ")
        cookie_obj['response'] = HHI_Resp_ADM()
        cookie_obj["worker_id"] = worker_id
        cookie_obj["job_id"] = job_id
        cookie_obj["auto_finalize"] = request.args.get("auto_finalize")

        for message in messages:
            flash(message)
    if request.method == "POST":
        response = cookie_obj["response"]
        response["time_stop"] = time.time()
        response["min_offer"] = int(request.form["min_offer"])
        cookie_obj['response'] = response
        if has_dss_component:
            req_response = make_response(
                redirect(url_for(f"{treatment}.resp.index_dss",
                                 **request.args)))
        else:
            req_response = make_response(
                redirect(url_for(f"{treatment}.resp.done", **request.args)))
        set_cookie_obj(req_response, BASE, cookie_obj)
        return req_response

    cookie_obj[BASE] = True
    req_response = make_response(
        render_template(template,
                        offer_values=OFFER_VALUES,
                        form=ResponderForm()))
    set_cookie_obj(req_response, BASE, cookie_obj)
    return req_response
Exemple #8
0
def check():
    cookie_obj = get_cookie_obj(BASE)
    if not cookie_obj.get(BASE, None):
        flash("Sorry, you are not allowed to use this service. ^_^")
        return render_template("error.html")
    cell = request.args.get("cell")
    cells = cookie_obj["cells"]
    cells[cell] = 1
    cookie_obj["cells"] = cells
    req_response = make_response("")
    set_cookie_obj(req_response, BASE, cookie_obj)
    return req_response
Exemple #9
0
def select_adapter():
    cookie_obj = get_cookie_obj(BASE)
    adapter_cookie = get_adapter_from_dict(cookie_obj.get("adapter", {}))
    adapter_args = get_adapter_from_dict(request.args)
    adapter_referrer = get_adapter()

    if adapter_referrer.job_id not in {"", "na", None}:
        adapter = adapter_referrer
    elif adapter_cookie.job_id not in {"", "na", None}:
        adapter = adapter_cookie
    else:
        adapter = adapter_args
    return adapter
Exemple #10
0
def check():
    app.logger.debug("index cc check")
    cookie_obj = get_cookie_obj(BASE)
    if not cookie_obj.get(BASE, None):
        flash("Sorry, you are not allowed to use this service. ^_^")
        return render_template("error.html")
    #data: {"letters":[], "delays":[], "clicked":[]}
    result = json.loads(request.data)
    cookie_obj["result"] = result
    req_response = make_response("")
    set_cookie_obj(req_response, BASE, cookie_obj)
    app.logger.debug("index cc check - done")
    return req_response
Exemple #11
0
def index():
    #return handle_task_index(f"{BASE}", validate_response=validate_response)

    cookie_obj = get_cookie_obj(BASE)
    worker_code_key = f"{BASE}_worker_code"
    worker_id = request.args.get("worker_id", "na")
    job_id = request.args.get("job_id", "na")
    # The task was already completed, so we skip to the completion code display
    if cookie_obj.get(BASE) and cookie_obj.get(
            worker_code_key) and cookie_obj.get("worker_id") == worker_id:
        req_response = make_response(redirect(url_for(f"tasks.{BASE}.done")))
        return req_response

    cookie_obj = get_cookie_obj(BASE)
    g.cookie_obj = cookie_obj
    if request.method == "GET":
        cookie_obj[BASE] = True
        cookie_obj["worker_id"] = worker_id
        cookie_obj["job_id"] = job_id
        cookie_obj["time_start"] = time.time()
        cookie_obj["cells"] = {f"cell{cid}": 0 for cid in range(1, 51)}
    if request.method == "POST":
        #response = request.form.to_dict()
        response = cookie_obj["cells"]
        if validate_response is not None and validate_response(response):
            response["time_stop"] = time.time()
            response["time_start"] = cookie_obj.get("time_start")
            cookie_obj["response"] = response
            req_response = make_response(
                redirect(url_for(f"tasks.{BASE}.done")))
            set_cookie_obj(req_response, BASE, cookie_obj)
            return req_response

    req_response = make_response(render_template(f"tasks/{BASE}.html"))
    cookie_obj[BASE] = True
    set_cookie_obj(req_response, BASE, cookie_obj)
    return req_response
Exemple #12
0
def index():
    app.logger.debug("index cc")
    # return handle_task_index(f"{BASE}", validate_response=validate_response, template_kwargs={"callback_url": url_for(f"tasks.{BASE}.check")})

    cookie_obj = get_cookie_obj(BASE)
    worker_code_key = f"{BASE}_worker_code"
    worker_id = request.args.get("worker_id", "na")
    job_id = request.args.get("job_id", "na")
    # The task was already completed, so we skip to the completion code display
    if cookie_obj.get(BASE) and cookie_obj.get(
            worker_code_key) and cookie_obj.get("worker_id") == worker_id:
        req_response = make_response(redirect(url_for(f"tasks.{BASE}.done")))
        return req_response
    if request.method == "GET":
        app.logger.debug("index cc get")
        cookie_obj[BASE] = True
        cookie_obj["worker_id"] = worker_id
        cookie_obj["job_id"] = job_id
        cookie_obj["time_start"] = time.time()
    if request.method == "POST":
        app.logger.debug("index cc post")
        #response = request.form.to_dict()
        response = cookie_obj["result"]
        if validate_response is not None and validate_response(response):
            response["time_stop"] = time.time()
            response["time_start"] = cookie_obj.get("time_start")
            response[
                "time_spent"] = response["time_stop"] - response["time_start"]
            cookie_obj["response"] = response
            req_response = make_response(
                redirect(url_for(f"tasks.{BASE}.done")))
            set_cookie_obj(req_response, BASE, cookie_obj)
            return req_response

    req_response = make_response(
        render_template(f"tasks/{BASE}.html",
                        callback_url=url_for(f"tasks.{BASE}.check"),
                        items=ITEMS,
                        start_delays=START_DELAYS,
                        time_show=TIME_SHOW,
                        time_wait=TIME_WAIT,
                        time_hide=TIME_HIDE,
                        delay_missed=DELAY_MISSED,
                        letter_signal_bonus=LETTER_SIGNAL_BONUS,
                        letter_noise_bonus=LETTER_NOISE_BONUS))
    cookie_obj[BASE] = True
    set_cookie_obj(req_response, BASE, cookie_obj)
    return req_response
Exemple #13
0
def handle_task_index(base, validate_response=None, template_kwargs=None):
    app.logger.debug(f"handle_task_index: {base}")
    if template_kwargs is None:
        template_kwargs = dict()
    req_response = make_response(render_template(f"tasks/{base}.html", **template_kwargs))
    cookie_obj = get_cookie_obj(base)

    worker_code_key = f"{base}_worker_code"
    worker_id = request.args.get("worker_id", "na")
    job_id = request.args.get("job_id", "na")
    # The user has already processed this task. So we skip to the "done" page.
    if cookie_obj.get(base) and cookie_obj.get(worker_code_key) and cookie_obj.get("worker_id") == worker_id:
        req_response = make_response(redirect(url_for(f"tasks.{base}.done", **request.args)))
        return req_response

    if request.method == "GET":
        cookie_obj[base] = True
        cookie_obj["worker_id"] = worker_id
        cookie_obj["job_id"] = job_id
        cookie_obj["time_start"] = time.time()
        cookie_obj["auto_finalize"] = request.args.get("auto_finalize")
        cookie_obj["treatment"] = request.args.get("treatment")
    if request.method == "POST":
        response = request.form.to_dict()
        if validate_response is not None and validate_response(response):
            response["time_stop"] = time.time()
            response["time_start"] = cookie_obj["time_start"]
            response["time_spent"] = round(response["time_stop"] - response["time_start"])
            response[f"{base}_time_spent"]  = response["time_spent"]
            req_response = make_response(redirect(url_for(f"tasks.{base}.done", **request.args)))
            cookie_obj["response"] = response
            set_cookie_obj(req_response, base, cookie_obj)
            return req_response
        else:
            flash("Please check your fields")
    set_cookie_obj(req_response, base, cookie_obj)
    return req_response
Exemple #14
0
def handle_survey_feedback_done(template=None):
    """ Only used for treatment t10_feedback"""
    if template is None:
        template = "txx/survey.done.html"
    cookie_obj = get_cookie_obj(BASE)
    if not cookie_obj.get(BASE):
        flash("Sorry, you are not allowed to use this service. ^_^")
        return render_template("error.html")
    worker_code_key = f"{BASE}_worker_code"
    worker_code = WORKER_CODE_DROPPED
    if True or not cookie_obj.get(worker_code_key):
        job_id = cookie_obj["job_id"]
        worker_id = cookie_obj["worker_id"]
        treatment = cookie_obj["treatment"]
        assignment_id = cookie_obj.get("assignment_id")

        worker_code = generate_completion_code(base=treatment, job_id=job_id)
        response = cookie_obj["response"]
        app.logger.debug("DONE_response: {response}")
        dropped = response.get("drop")
        if dropped == "1":
            worker_code = WORKER_CODE_DROPPED
            flash(
                f"You have been disqualified as you made more than {MAXIMUM_CONTROL_MISTAKES} mistakes on the control questions. Close this window and don't submit any completion on MTurk to avoid getting a REJECTION."
            )
        response["worker_id"] = worker_id
        response["job_id"] = job_id
        response["assignment_id"] = assignment_id
        response["completion_code"] = worker_code
        result = {
            k: v
            for k, v in response.items() if k not in {'csrf_token', 'drop'}
        }
        try:
            save_result2file(
                get_output_filename(base=BASE,
                                    job_id=job_id,
                                    treatment=treatment), result)
        except Exception as err:
            app.log_exception(err)
        try:
            save_result2db(table=get_table(base=BASE,
                                           job_id=job_id,
                                           schema="result",
                                           treatment=treatment),
                           response_result=result,
                           unique_fields=["worker_id"])
        except Exception as err:
            app.log_exception(err)

        adapter = get_adapter_from_dict(cookie_obj["adapter"])
        #adapter = get_adapter()
        app.logger.debug(f"adapter: {cookie_obj['adapter']}")
        cookie_obj.clear()

        #save_worker_id(job_id=job_id, worker_id=worker_id, worker_code=worker_code, assignment_id=adapter.assignment_id)

        app.logger.debug(
            f"request-args: {request.args}, adapter: {adapter.to_dict()} ")
        try:
            expected_max_judgments = request.args.get("expected_max_judgments")
            if expected_max_judgments is not None:
                expected_max_judgments = int(expected_max_judgments)
                api = adapter.get_api()
                max_judgments = api.get_max_judgments()
                app.logger.debug(
                    f"survey.done: max_judgments: {max_judgments} - {type(max_judgments)}, expected_max_judgments: {expected_max_judgments} - {type(expected_max_judgments)}"
                )
                if max_judgments < expected_max_judgments:
                    app.logger.debug(f"try create new assignments")
                    create_res = api.create_additional_assignments(1)
                    app.logger.debug(
                        f"post assignment creation: new-max: {api.get_max_judgments()} , mturk-api-res: {create_res}"
                    )
        except Exception as err:
            app.log_exception(err)

        app.logger.info(
            f"handle_survey_feedback_done: saved new survey - job_id: {job_id}, worker_id: {worker_id}"
        )
    req_response = make_response(
        render_template(template, worker_code=worker_code, dropped=True))
    set_cookie_obj(req_response, BASE, cookie_obj)
    for cookie in session.get(ALL_COOKIES_KEY, []):
        req_response.set_cookie(cookie, expires=0)
    session[ALL_COOKIES_KEY] = []
    return req_response
Exemple #15
0
def handle_index(treatment,
                 template=None,
                 proposal_class=None,
                 messages=None,
                 dss_available=None,
                 get_row_func=None):
    app.logger.debug("handle_index")
    if messages is None:
        messages = []
    if proposal_class is None:
        proposal_class = HHI_Prop_ADM
    if dss_available is None:
        MODEL_KEY = f"{TREATMENTS_MODEL_REFS[treatment.upper()]}_MODEL"
        dss_available = bool(app.config.get(MODEL_KEY))
    if template is None:
        template = f"txx/prop.html"
    if get_row_func is None:
        get_row_func = get_row
    cookie_obj = get_cookie_obj(BASE)
    worker_code_key = f"{BASE}_worker_code"
    worker_id = request.args.get("worker_id", "na")
    job_id = request.args.get("job_id", "na")
    # The task was already completed, so we skip to the completion code display
    if cookie_obj.get(BASE) and cookie_obj.get(
            worker_code_key) and cookie_obj.get("worker_id") == worker_id:
        req_response = make_response(
            redirect(url_for(f"{treatment}.prop.done", **request.args)))
        return req_response

    if request.method == "GET":
        cookie_obj['proposal'] = proposal_class()
        app.logger.debug(
            f"handle_index: job_id:{job_id}, worker_id:{worker_id} ")
        row_info = get_row_func(get_db("DATA"),
                                job_id,
                                worker_id,
                                treatment=treatment)

        cookie_obj["worker_id"] = worker_id
        cookie_obj["job_id"] = job_id
        cookie_obj["row_info"] = row_info

        #TODO: check if worker_id has started answering this unit
        if not row_info:
            warnings.warn(
                f"ERROR: The row can no longer be processed. job_id: {job_id} - worker_id: {worker_id}"
            )

            flash(
                f"There are either no more rows available or you already took part on this survey. Thank you for your participation"
            )
            return render_template("error.html")
        for message in messages:
            flash(message)
    if request.method == "POST":
        proposal = cookie_obj["proposal"]
        proposal["time_stop"] = time.time()
        offer = request.form["offer"]
        try:
            offer = int(offer)
        except ValueError as err:
            app.logger.warning(f"Conversion error: {err}")
            offer = None
        proposal["offer"] = offer
        cookie_obj['proposal'] = proposal
        if dss_available:
            req_response = make_response(
                redirect(url_for(f"{treatment}.prop.index_dss",
                                 **request.args)))
        else:
            req_response = make_response(
                redirect(url_for(f"{treatment}.prop.done", **request.args)))
        set_cookie_obj(req_response, BASE, cookie_obj)
        return req_response

    cookie_obj[BASE] = True
    prop_check_url = url_for(f"{treatment}.prop.check")
    req_response = make_response(
        render_template(template,
                        offer_values=OFFER_VALUES,
                        form=ProposerForm(),
                        prop_check_url=prop_check_url,
                        max_gain=MAX_GAIN))
    set_cookie_obj(req_response, BASE, cookie_obj)
    return req_response
Exemple #16
0
def handle_survey_feedback(treatment=None,
                           template=None,
                           code_prefixes=None,
                           form_class=None,
                           overview_url=None):
    app.logger.info("handle_survey_feedback")
    if code_prefixes is None:
        code_prefixes = {
            "code_cpc": "cpc:",
            "code_exp": "exp:",
            "code_risk": "risk:",
            "code_cc": "cc:",
            "code_ras": "ras:"
        }
    if form_class is None:
        form_class = MainFormFeeback
    if template is None:
        template = "txx/survey_feedback.html"
    if overview_url is None:
        if treatment and treatment.upper() in TREATMENTS_AUTO_DSS:
            overview_url = url_for("overview_auto_prop_feedback")
        else:
            overview_url = url_for("overview_feedback")
    cookie_obj = get_cookie_obj(BASE)

    adapter_cookie = get_adapter_from_dict(cookie_obj.get("adapter", {}))
    adapter_args = get_adapter_from_dict(request.args)
    adapter_referrer = get_adapter()

    if adapter_referrer.job_id not in {"", "na", None}:
        adapter = adapter_referrer
    elif adapter_cookie.job_id not in {"", "na", None}:
        adapter = adapter_cookie
    else:
        adapter = adapter_args

    app.logger.debug(f"adapter: {adapter.to_dict()}")
    worker_code_key = f"{BASE}_worker_code"

    arg_job_id = adapter.get_job_id()
    arg_worker_id = adapter.get_worker_id()
    job_id = arg_job_id or f"na"
    worker_id = arg_worker_id
    if worker_id in {"", "na", None}:
        worker_id = str(uuid.uuid4())
        adapter.worker_id = worker_id

    max_judgments = 0  #not set
    if adapter.has_api():
        api = adapter.get_api()
        max_judgments = api.get_max_judgments()
    else:
        try:
            max_judgments = int(
                request.args.get("max_judgments", max_judgments))
        except:
            pass
    job_config = get_job_config(get_db(), job_id)
    max_judgments = max(max_judgments, job_config.expected_judgments)
    next_player = check_is_proposer_next(job_id,
                                         worker_id,
                                         treatment,
                                         max_judgments=max_judgments)

    table_all = get_table("txx", "all", schema=None)
    # The task was already completed, so we skip to the completion code display
    if cookie_obj.get(BASE) and cookie_obj.get(worker_code_key):
        req_response = make_response(
            redirect(url_for(f"{treatment}.survey.survey_done",
                             **request.args)))
        set_cookie_obj(req_response, BASE, cookie_obj)
        return req_response
    if treatment is None:
        treatment = get_latest_treatment()
    cookie_obj["job_id"] = job_id
    cookie_obj["worker_id"] = worker_id
    cookie_obj["assignment_id"] = adapter.get_assignment_id()
    cookie_obj["treatment"] = treatment
    cookie_obj["adapter"] = adapter.to_dict()
    cookie_obj[BASE] = True
    form = form_class(request.form)
    drop = request.form.get("drop")
    con = get_db()
    # if table_exists(con, table_all):
    #     with con:
    #         res = con.execute(f"SELECT * from {table_all} WHERE worker_id=?", (worker_id,)).fetchone()
    #         if res:
    #             flash(f"You already took part on this survey. You can just ignore this HIT for the assignment to be RETURNED later to another worker or you can submit right now for a REJECTION using the survey code provided.")
    #             req_response = make_response(render_template("error.html", worker_code=WORKER_CODE_DROPPED))
    #             return req_response

    #The next player should be a proposer but some responders may still be processing data
    ## Should not matter in feedback surveys
    if next_player == NEXT_IS_WAITING:
        resp_table = get_table(base="resp",
                               job_id=job_id,
                               schema="result",
                               treatment=treatment)
        prop_table = get_table(base="prop",
                               job_id=job_id,
                               schema="result",
                               treatment=treatment)
        # We make sure the user didn't accidentaly refreshed the page after processing the main task
        if (not is_worker_available(worker_id, resp_table)
                and not is_worker_available(worker_id, prop_table)):
            flash(
                "Unfortunately there is no task available right now. Please check again in 15 minutes. Otherwise you can just ignore this HIT for the assignment to be RETURNED later to another worker or you can submit right now for a REJECTION using the survey code provided."
            )
            return render_template("error.html",
                                   worker_code=WORKER_CODE_DROPPED)

    if adapter.is_preview() or job_id == "na":
        flash(
            "Please do note that you are currently in the preview mode of the survey. You SHOULD NOT FILL NEITHER SUBMIT the survey in this mode. Please go back to Mturk and read the instructions about how to correctly start this survey."
        )

    if request.method == "POST" and (drop == "1" or form.validate_on_submit()):
        form = form_class(request.form)
        response = request.form.to_dict()
        response["timestamp"] = str(datetime.datetime.now())
        cookie_obj["response"] = response
        is_codes_valid = True
        # Responders have to fill and submit tasks
        if is_codes_valid and job_id != "na" and worker_id != "na":
            cookie_obj["response"] = response
            #NOTE: the url should be pointing to handle_survey_feedback_done
            req_response = make_response(
                redirect(
                    url_for(f"{treatment}.survey.survey_done",
                            **request.args)))
            set_cookie_obj(req_response, BASE, cookie_obj)
            return req_response
        elif is_codes_valid:
            flash(
                "Your data was submitted and validated but not save as you are currently in the preview mode of the survey. Please go back to Mturk and read the instructions about how to correctly start this survey."
            )

    req_response = make_response(
        render_template(template,
                        job_id=job_id,
                        worker_id=worker_id,
                        treatment=treatment,
                        form=form,
                        max_judgments=max_judgments,
                        max_gain=MAX_GAIN,
                        maximum_control_mistakes=MAXIMUM_CONTROL_MISTAKES,
                        overview_url=overview_url,
                        tasks=app.config["TASKS"]))
    set_cookie_obj(req_response, BASE, cookie_obj)
    return req_response
Exemple #17
0
def handle_start(treatment=None,
                 template=None,
                 code_prefixes=None,
                 form_class=None,
                 overview_url=None,
                 resp_only=None,
                 prop_only=None):
    app.logger.info("handle_start")
    if template is None:
        template = "txx/start.html"
    if overview_url is None:
        overview_url = url_for("overview")
    cookie_obj = get_cookie_obj(BASE)

    adapter = select_adapter()

    app.logger.debug(f"adapter: {adapter.to_dict()}")

    arg_job_id = adapter.get_job_id()
    arg_worker_id = adapter.get_worker_id()
    assignment_id = adapter.get_assignment_id()
    job_id = arg_job_id or f"na"
    worker_id = arg_worker_id
    if worker_id in {"", "na", None}:
        worker_id = str(uuid.uuid4())
        adapter.worker_id = worker_id

    table_all = get_table("txx", "all", schema=None)
    # The task was already completed, so we skip to the completion code display
    # if cookie_obj.get(BASE) and cookie_obj.get(worker_code_key):
    #     req_response = make_response(redirect(url_for(f"{treatment}.survey.survey_done", **request.args)))
    #     set_cookie_obj(req_response, BASE, cookie_obj)
    #     return req_response
    if treatment is None:
        treatment = get_latest_treatment()
    cookie_obj["job_id"] = job_id
    cookie_obj["worker_id"] = worker_id
    cookie_obj["treatment"] = treatment
    cookie_obj["adapter"] = adapter.to_dict()
    cookie_obj[BASE] = True

    con = get_db()
    if table_exists(con, table_all):
        with con:
            res = con.execute(f"SELECT * from {table_all} WHERE worker_id=?",
                              (worker_id, )).fetchone()
            if res:
                flash(f"You already took part on this survey.")
                flash(
                    "You can just ignore this HIT for the assignment to be RETURNED later to another worker."
                )
                req_response = make_response(
                    render_template("error.html",
                                    worker_code=WORKER_CODE_DROPPED))
                return req_response

    req_response = make_response(
        render_template(template,
                        job_id=job_id,
                        worker_id=worker_id,
                        assignment_id=assignment_id,
                        treatment=treatment,
                        submit_to_url=adapter.get_submit_to_URL()))
    set_cookie_obj(req_response, BASE, cookie_obj)
    return req_response
Exemple #18
0
def handle_done_no_prop(treatment, template=None, no_features=None):
    app.logger.debug("handle_done")
    if template is None:
        template = f"txx/resp.done.html"
    if no_features is None:
        completion_code_base = BASE
    else:
        # survey should not require tasks
        completion_code_base = BASE + "NF"

    cookie_obj = get_cookie_obj(BASE)
    worker_code_key = f"{BASE}_worker_code"
    if not cookie_obj.get(BASE, None):
        flash("Sorry, you are not allowed to use this service. ^_^")
        return render_template("error.html")
    if not cookie_obj.get(worker_code_key):
        job_id = cookie_obj["job_id"]
        worker_code = generate_completion_code(completion_code_base, job_id)
        response = cookie_obj["response"]
        response["completion_code"] = worker_code
        worker_id = cookie_obj["worker_id"]
        resp_result = resp_to_resp_result(response,
                                          job_id=job_id,
                                          worker_id=worker_id)
        try:
            #save_resp_result(TUBE_RES_FILENAME, resp_result)
            save_result2file(
                get_output_filename(BASE, job_id, treatment=treatment),
                resp_result)
        except Exception as err:
            app.log_exception(err)

        bonus_cents = 0
        row_id = None
        prop_row = {}
        try:
            prop_row = get_row_ignore_job(get_db(), job_id, worker_id,
                                          treatment)
            offer = prop_row.get("offer_final", prop_row["offer"])
            row_id = prop_row.get(PK_KEY)
            if offer >= response.get("min_offer_final", response["min_offer"]):
                bonus_cents = MAX_GAIN - offer
            else:
                bonus_cents = 0
        except Exception as err:
            app.log_exception(err)
        try:
            #save_resp_result2db(get_db("RESULT"), resp_result, job_id)
            save_result2db(table=get_table(base=BASE,
                                           job_id=job_id,
                                           schema="result",
                                           treatment=treatment),
                           response_result=resp_result,
                           unique_fields=["worker_id"])
            increase_worker_bonus(job_id=job_id,
                                  worker_id=worker_id,
                                  bonus_cents=bonus_cents)
            close_row(get_db(), job_id, row_id, treatment)

            prop_result = {
                k: v
                for k, v in resp_result.items() if k not in SKIP_RESP_KEYS
            }
            prop_result = {
                k: (v if "feedback" not in k and "time" not in k else None)
                for k, v in prop_result.items()
            }
            prop_result["resp_worker_id"] = worker_id
            prop_result["worker_id"] = prop_row["prop_worker_id"]
            prop_result.update(prop_row)
            save_result2db(table=get_table(base="prop",
                                           job_id=job_id,
                                           schema="result",
                                           treatment=treatment),
                           response_result=prop_result,
                           unique_fields=["worker_id"])
        except Exception as err:
            app.log_exception(err)
        cookie_obj.clear()
        cookie_obj[BASE] = True
        cookie_obj["worker_id"] = worker_id
        cookie_obj[worker_code_key] = worker_code

    req_response = make_response(
        render_template(template, worker_code=cookie_obj[worker_code_key]))
    set_cookie_obj(req_response, BASE, cookie_obj)
    return req_response
Exemple #19
0
def handle_index_dss(treatment,
                     template=None,
                     proposal_class=None,
                     messages=None):
    app.logger.debug("handle_index_dss")
    if messages is None:
        messages = []
    if proposal_class is None:
        proposal_class = HHI_Prop_ADM
    if template is None:
        template = f"txx/prop_dss.html"
    cookie_obj = get_cookie_obj(BASE)
    worker_code_key = f"{BASE}_worker_code"
    worker_id = request.args.get("worker_id", "na")
    job_id = request.args.get("job_id", "na")
    row_info = cookie_obj.get("row_info")
    # The task was already completed, so we skip to the completion code display
    if cookie_obj.get(BASE) and cookie_obj.get(
            worker_code_key) and cookie_obj.get("worker_id") == worker_id:
        req_response = make_response(
            redirect(url_for(f"{treatment}.prop.done", **request.args)))
        return req_response

    if request.method == "GET":
        #TODO: check if worker_id has started answering this unit
        proposal = cookie_obj["proposal"]
        proposal["time_start_dss"] = time.time()
        if not row_info:
            warnings.warn(
                f"ERROR: The row can no longer be processed. job_id: {job_id} - worker_id: {worker_id}"
            )

            flash(
                f"There are either no more rows available or you already took part on this survey. Thank you for your participation"
            )
            return render_template("error.html")
        for message in messages:
            flash(message)
    if request.method == "POST":
        proposal = cookie_obj["proposal"]
        proposal["time_stop_dss"] = time.time()
        offer_dss = request.form["offer_dss"]
        try:
            offer_dss = int(offer_dss)
        except ValueError as err:
            app.logger.warning(f"Conversion error: {err}")
            offer_dss = None
        proposal["offer_dss"] = offer_dss
        cookie_obj['proposal'] = proposal
        req_response = make_response(
            redirect(url_for(f"{treatment}.prop.feedback", **request.args)))
        set_cookie_obj(req_response, BASE, cookie_obj)
        return req_response

    cookie_obj[BASE] = True
    prop_check_url = url_for(f"{treatment}.prop.check")
    req_response = make_response(
        render_template(template,
                        offer_values=OFFER_VALUES,
                        form=ProposerForm(),
                        prop_check_url=prop_check_url,
                        max_gain=MAX_GAIN))
    set_cookie_obj(req_response, BASE, cookie_obj)
    return req_response
Exemple #20
0
def handle_done(treatment,
                template=None,
                response_to_result_func=None,
                ignore_job=None):
    app.logger.debug("handle_done")
    if template is None:
        template = f"txx/{BASE}.done.html"
    if response_to_result_func is None:
        response_to_result_func = prop_to_prop_result
    worker_code_key = f"{BASE}_worker_code"
    worker_bonus_key = f"{BASE}_worker_bonus"
    cookie_obj = get_cookie_obj(BASE)
    ai_cookie_obj = get_cookie_obj(AI_COOKIE_KEY)
    if not cookie_obj.get(BASE, None):
        flash("Sorry, you are not allowed to use this service. ^_^")
        return render_template("error.html")
    if not (cookie_obj.get("worker_code")):
        job_id = cookie_obj["job_id"]
        worker_code = generate_completion_code(base=BASE, job_id=job_id)
        proposal = cookie_obj["proposal"]
        proposal["completion_code"] = worker_code
        proposal.update(ai_cookie_obj.get("ai_proposal", {}))
        row_info = cookie_obj["row_info"]
        worker_id = cookie_obj["worker_id"]
        close_row(get_db("DATA"),
                  job_id,
                  row_info[PK_KEY],
                  treatment=treatment,
                  ignore_job=ignore_job)
        # worker_bonus = gain(int(row_info["min_offer"]), proposal["offer"])
        prop_result = response_to_result_func(proposal,
                                              job_id=job_id,
                                              worker_id=worker_id,
                                              row_data=row_info)
        try:
            save_result2file(
                get_output_filename(base=BASE,
                                    job_id=job_id,
                                    treatment=treatment), prop_result)
        except Exception as err:
            app.log_exception(err)
        try:
            save_result2db(table=get_table(base=BASE,
                                           job_id=job_id,
                                           schema="result",
                                           treatment=treatment),
                           response_result=prop_result,
                           unique_fields=["worker_id"])
            # increase_worker_bonus(job_id=job_id, worker_id=worker_id, bonus_cents=0, con=get_db("DB"))
        except Exception as err:
            app.log_exception(err)
        auto_finalize = request.args.get("auto_finalize")
        if auto_finalize:
            # url = url_for(f"{treatment}.webhook", job_id=job_id, worker_id=worker_id, auto_finalize=auto_finalize)
            # client = app.test_client()
            # client.get(url)
            finalize_round(job_id,
                           prop_worker_id=worker_id,
                           treatment=treatment)

        cookie_obj.clear()

        cookie_obj[BASE] = True
        cookie_obj["worker_id"] = worker_id
        # cookie_obj[worker_bonus_key] = cents_repr(worker_bonus)
        cookie_obj[worker_code_key] = worker_code
    req_response = make_response(
        render_template(template, worker_code=cookie_obj[worker_code_key]))
    set_cookie_obj(req_response, BASE, cookie_obj)
    return req_response
Exemple #21
0
def handle_task_done(base, response_to_result_func=None, response_to_bonus=None, numeric_fields=None, unique_fields=None):
    """
    :param base: (str)
    :param response_to_result_func: (func)
    :param response_to_bonus: (func)
    :param numeric_fields: (None| '*' | list)  if '*' all fields are converted to float
    :param unique_fields: (str|list)
    """
    app.logger.debug(f"handle_task_done: {base}")
    worker_code_key = f"{base}_worker_code"
    worker_bonus_key = f"{base}_worker_bonus"
    cookie_obj = get_cookie_obj(base)
    if response_to_result_func is None:
        response_to_result_func = response_to_result
    if not cookie_obj.get(base):
        flash("Sorry, you are not allowed to use this service. ^_^")
        return render_template("error.html")
    if response_to_bonus is None:
        response_to_bonus = lambda args, **kwargs: 0
    if not cookie_obj.get(worker_code_key) or (app.config["DEBUG"] and False):
        job_id = cookie_obj["job_id"]
        worker_code = generate_completion_code(base, job_id)
        response = cookie_obj["response"]
        if numeric_fields is not None:
            if isinstance(numeric_fields, (list, tuple)):
                for field in numeric_fields:
                    try:
                        response[field] = value_to_numeric(response[field])
                    except Exception as err:
                        app.log_exception(err)
            elif numeric_fields == "*":
                for field in response:
                    try:
                        response[field] = value_to_numeric(response[field])
                    except Exception as err:
                        app.log_exception(err)

        worker_id = cookie_obj["worker_id"]
        response["completion_code"] = worker_code
        response_result = response_to_result_func(response, job_id=job_id, worker_id=worker_id)
        worker_bonus = response_to_bonus(response)
        response_result["worker_bonus"] = worker_bonus
        try:
            save_result2file(get_output_filename(base, job_id, is_task=True), response_result)
        except Exception as err:
            app.log_exception(err)
        try:
            #TODO: check later
            save_result2db(get_table(base, job_id=job_id, schema="result", is_task=True), response_result, unique_fields=unique_fields)
            increase_worker_bonus(job_id=job_id, worker_id=worker_id, bonus_cents=worker_bonus)
        except Exception as err:
            app.log_exception(err)
        
        #NOTE: hexaco is the LAST task required from the user!!!
        auto_finalize = cookie_obj.get("auto_finalize")
        if auto_finalize:# and base=="hexaco":
            #NOTE: there is an import here ^_^
            from survey.txx.helpers import finalize_resp
            treatment = cookie_obj.get("treatment")
            finalize_resp(job_id, worker_id, treatment)
            # client = app.test_client()
            # url = url_for(f"{treatment}.webhook", job_id=job_id, worker_id=worker_id, auto_finalize=auto_finalize, _external=False)
            # app.logger.debug(f"WEBHOOK-URL: {url}")
            # response = client.get(url)
            # # response = requests.get(url)
            # # response = make_response(url)
            # if response.status_code != 200:
            #     app.logger.warning(f"handle_task_done: Something went wrong when: auto: {auto_finalize}, base: {base}, resp-status: {response.data}")
        cookie_obj.clear()
        cookie_obj[base] = True
        cookie_obj["worker_id"] = worker_id
        cookie_obj[worker_code_key] = worker_code
        cookie_obj[worker_bonus_key] = worker_bonus
    
    req_response = make_response(render_template("tasks/done.html", worker_code=cookie_obj[worker_code_key], worker_bonus=cents_repr(cookie_obj[worker_bonus_key])))
    set_cookie_obj(req_response, base, cookie_obj)
    return req_response