Example #1
0
def serve_battery(request,bid,userid=None):

    battery = get_battery(bid,request)
    next_page = None
    uncompleted_experiments=None
    result=None

    # No robots allowed!
    if request.user_agent.is_bot:
        return render_to_response("robot_sorry.html")

    # Is userid not defined, this is a preview
    if userid == None:
        template = "serve_battery_preview.html"
        task_list = [battery.experiments.all()[0]]
        context = dict()
        deployment = "docker-preview"

    # admin a battery for a new user
    else:
        template = "serve_battery.html"
        worker = get_worker(userid)

        # Try to get some info about browser, language, etc.
        browser = "%s,%s" %(request.user_agent.browser.family,request.user_agent.browser.version_string)
        platform = "%s,%s" %(request.user_agent.os.family,request.user_agent.os.version_string)
        deployment = "docker-local"

        # Does the worker have experiments remaining for the hit?
        uncompleted_experiments = get_worker_experiments(worker,battery)
        if len(uncompleted_experiments) == 0:
            # Thank you for your participation - no more experiments!
            return render_to_response("worker_sorry.html")

        task_list = select_random_n(uncompleted_experiments,1)
        experimentTemplate = ExperimentTemplate.objects.filter(exp_id=task_list[0])[0]
        task_list = battery.experiments.filter(template=experimentTemplate)

        # Generate a new results object for the worker, assignment, experiment
        result,_ = Result.objects.update_or_create(worker=worker,
                                                   experiment=experimentTemplate,
                                                   battery=battery,
                                                   defaults={"browser":browser,"platform":platform})
        result.save()

        context = {"worker_id": worker.id,
                   "uniqueId":result.id}

        # If this is the last experiment, the finish button will link to a thank you page.
        if len(uncompleted_experiments) == 1:
            next_page = "/finished"

    return deploy_battery(deployment=deployment,
                          battery=battery,
                          context=context,
                          task_list=task_list,
                          template=template,
                          uncompleted_experiments=uncompleted_experiments,
                          next_page=next_page,
                          result=result)
Example #2
0
def serve_battery(request,bid,userid=None):
    '''prepare for local serve of battery'''

    next_page = None
    battery = get_battery(bid,request)

    # No robots allowed!
    if request.user_agent.is_bot:
        return render_to_response("turk/robot_sorry.html")

    # Is userid not defined, redirect them to preview
    if userid == None:
        return preview_battery(request,bid)

    worker = get_worker(userid,create=False)
    if isinstance(worker,list): # no id means returning []
        return render_to_response("turk/invalid_id_sorry.html")

    # Try to get some info about browser, language, etc.
    browser = "%s,%s" %(request.user_agent.browser.family,request.user_agent.browser.version_string)
    platform = "%s,%s" %(request.user_agent.os.family,request.user_agent.os.version_string)
    deployment = "docker-local"

    # Does the worker have experiments remaining?
    uncompleted_experiments = get_worker_experiments(worker,battery)
    if len(uncompleted_experiments) == 0:
        # Thank you for your participation - no more experiments!
        return render_to_response("turk/worker_sorry.html")

    task_list = select_experiments(battery,uncompleted_experiments)
    experimentTemplate = ExperimentTemplate.objects.filter(exp_id=task_list[0].template.exp_id)[0]
    experiment_type = get_experiment_type(experimentTemplate)
    task_list = battery.experiments.filter(template=experimentTemplate)

    # Generate a new results object for the worker, assignment, experiment
    result,_ = Result.objects.update_or_create(worker=worker,
                                               experiment=experimentTemplate,
                                               battery=battery,
                                               defaults={"browser":browser,"platform":platform})
    result.save()

    context = {"worker_id": worker.id,
               "uniqueId":result.id}

    # If this is the last experiment, the finish button will link to a thank you page.
    if len(uncompleted_experiments) == 1:
        next_page = "/finished"

    # Determine template name based on template_type
    template = "%s/serve_battery.html" %(experiment_type)

    return deploy_battery(deployment="docker-local",
                          battery=battery,
                          experiment_type=experiment_type,
                          context=context,
                          task_list=task_list,
                          template=template,
                          next_page=next_page,
                          result=result)
Example #3
0
def assign_reward(worker_id):
    '''THIS FUNCTION NOT YET IMPLEMENTED, TESTED, etc.'''

    # Look up all result objects for worker
    worker = get_worker(worker_id)
    results = Result.objects.filter(worker=worker)

    # rejection criteria
    additional_dollars = 0.0
    rejection = False

    for result in results:
        if result.completed == True:
            # Get all experiments
            battery_experiments = result.assignment.hit.battery.experiments.all(
            )
            experiment_ids = get_unique_experiments([result])
            experiments = ExperimentTemplate.objects.filter(
                exp_id__in=experiment_ids)
            for template in experiments:
                experiment = [
                    b for b in battery_experiments if b.template == template
                ]
                # If an experiment is deleted from battery, we have no way to know to reject/bonus
                if len(experiment) > 0:
                    experiment = experiment[0]
                    do_catch = True if template.rejection_variable != None and experiment.include_catch == True else False
                    do_bonus = True if template.performance_variable != None and experiment.include_bonus == True else False
                    for credit_condition in experiment.credit_conditions.all():
                        variable_name = credit_condition.variable.name
                        variables = get_variables(result, variable_name)
                        func = [
                            x[1] for x in credit_condition.OPERATOR_CHOICES
                            if x[0] == credit_condition.operator
                        ][0]
                        # Needs to be tested for non numeric types
                        for variable in variables:
                            comparator = credit_condition.value
                            if isinstance(variable, float) or isinstance(
                                    variable, int):
                                variable = float(variable)
                                comparator = float(comparator)
                            if func(comparator, variable):
                                # For credit conditions, add to bonus!
                                if credit_condition.variable == template.performance_variable and do_bonus:
                                    additional_dollars = additional_dollars + credit_condition.amount
                                if credit_condition.variable == template.rejection_variable and do_catch:
                                    rejection = True
            # We remember granting credit on the level of results
            result.credit_granted = True
            result.save()

    if len(results) > 0:
        # Update HIT assignments - all results point to the same hit, so use the last one
        result.assignment.hit.update_assignments()
        assignment = Assignment.objects.filter(id=result.assignment.id)[0]
Example #4
0
def serve_battery_anon(request,bid,keyid):
    '''serve an anonymous local battery, userid is generated upon going to link'''
    # Check if the keyid is correct
    battery = get_battery(bid,request)
    uid=hashlib.md5(battery.name).hexdigest()
    if uid==keyid:
        userid = uuid.uuid4()
        worker = get_worker(userid,create=True)
        return redirect("intro_battery",bid=bid,userid=userid)
    else:
        return render_to_response("turk/robot_sorry.html")
Example #5
0
def serve_battery_anon(request, bid, keyid):
    '''serve an anonymous local battery, userid is generated upon going to link'''
    # Check if the keyid is correct
    battery = get_battery(bid, request)
    uid = hashlib.md5(battery.name).hexdigest()
    if uid == keyid:
        userid = uuid.uuid4()
        worker = get_worker(userid, create=True)
        return redirect("intro_battery", bid=bid, userid=userid)
    else:
        return render_to_response("turk/robot_sorry.html")
Example #6
0
def assign_experiment_credit(worker_id):
    '''Function to parse all results for a worker, assign credit or bonus if needed,
    and either flag result or mark as completed. Should be fired if:
      1) worker completes full battery and expfactory.djstatus variable is finished
      2) worker does not accept Consent ("Disagree") and ends battery
      3) worker is deemed to have poorly completed some N experiments in a row
      4) worker does not complete experiments, HIT time runs out
    '''
    # Look up all result objects for worker
    worker = get_worker(worker_id)
    results = Result.objects.filter(worker=worker)
    if len(results) > 0:
        if results[0].assignment != None:
            if results[0].assignment.status == "S":
                results[0].assignment.approve()
Example #7
0
def assign_experiment_credit(worker_id):
    '''Function to parse all results for a worker, assign credit or bonus if needed,
    and either flag result or mark as completed. Should be fired if:
      1) worker completes full battery and expfactory.djstatus variable is finished
      2) worker does not accept Consent ("Disagree") and ends battery
      3) worker is deemed to have poorly completed some N experiments in a row
      4) worker does not complete experiments, HIT time runs out
    '''
    # Look up all result objects for worker
    worker = get_worker(worker_id)
    results = Result.objects.filter(worker=worker)
    if len(results)>0:
        if results[0].assignment != None:
            if results[0].assignment.status == "S":
                results[0].assignment.approve()
Example #8
0
def assign_reward(worker_id):
    '''THIS FUNCTION NOT YET IMPLEMENTED, TESTED, etc.'''

    # Look up all result objects for worker
    worker = get_worker(worker_id)
    results = Result.objects.filter(worker=worker)

    # rejection criteria
    additional_dollars = 0.0
    rejection = False

    for result in results:
        if result.completed == True:
            # Get all experiments
            battery_experiments = result.assignment.hit.battery.experiments.all()
            experiment_ids = get_unique_experiments([result])
            experiments = ExperimentTemplate.objects.filter(exp_id__in=experiment_ids)
            for template in experiments:
                experiment = [b for b in battery_experiments if b.template == template]
                # If an experiment is deleted from battery, we have no way to know to reject/bonus
                if len(experiment)>0:
                    experiment = experiment[0]
                    do_catch = True if template.rejection_variable != None and experiment.include_catch == True else False
                    do_bonus = True if template.performance_variable != None and experiment.include_bonus == True else False
                    for credit_condition in experiment.credit_conditions.all():
                        variable_name = credit_condition.variable.name
                        variables = get_variables(result,variable_name)
                        func = [x[1] for x in credit_condition.OPERATOR_CHOICES if x[0] == credit_condition.operator][0]
                        # Needs to be tested for non numeric types
                        for variable in variables:
                            comparator = credit_condition.value
                            if isinstance(variable,float) or isinstance(variable,int):
                                variable = float(variable)
                                comparator = float(comparator)
                            if func(comparator,variable):
                                # For credit conditions, add to bonus!
                                if credit_condition.variable == template.performance_variable and do_bonus:
                                    additional_dollars = additional_dollars + credit_condition.amount
                                if credit_condition.variable == template.rejection_variable and do_catch:
                                    rejection = True
            # We remember granting credit on the level of results
            result.credit_granted = True
            result.save()

    if len(results) > 0:
        # Update HIT assignments - all results point to the same hit, so use the last one
        result.assignment.hit.update_assignments()
        assignment = Assignment.objects.filter(id=result.assignment.id)[0]
Example #9
0
def serve_battery_gmail(request,bid):
    '''serves a battery, creating user with gmail'''
    # Check if the keyid is correct
    battery = get_battery(bid,request)
    uid = hashlib.md5(battery.name).hexdigest()
    if "keyid" in request.POST and "gmail" in request.POST:
        keyid = request.POST["keyid"]
        address = request.POST["gmail"]
        if uid==keyid:
            userid = hashlib.md5(address).hexdigest()
            worker = get_worker(userid,create=True)
            return redirect("intro_battery",bid=bid,userid=userid)
        else:
            return render_to_response("turk/robot_sorry.html")
    else:
        return render_to_response("turk/robot_sorry.html")
Example #10
0
def serve_battery_gmail(request, bid):
    '''serves a battery, creating user with gmail'''
    # Check if the keyid is correct
    battery = get_battery(bid, request)
    uid = hashlib.md5(battery.name).hexdigest()
    if "keyid" in request.POST and "gmail" in request.POST:
        keyid = request.POST["keyid"]
        address = request.POST["gmail"]
        if uid == keyid:
            userid = hashlib.md5(address).hexdigest()
            worker = get_worker(userid, create=True)
            return redirect("intro_battery", bid=bid, userid=userid)
        else:
            return render_to_response("turk/robot_sorry.html")
    else:
        return render_to_response("turk/robot_sorry.html")
Example #11
0
def generate_battery_user(request,bid):
    '''add a new user login url to take a battery'''

    battery = get_battery(bid,request)
    context = {"battery":battery,
              "domain":settings.DOMAIN_NAME}

    if check_battery_edit_permission(request,battery) == True:

            # Create a user result object
            userid = uuid.uuid4()
            worker = get_worker(userid)
            context["new_user"] = userid

            return render_to_response('generate_battery_user.html', context)

    else:
            return HttpResponseRedirect(battery.get_absolute_url())
Example #12
0
def generate_battery_user(request, bid):
    '''add a new user login url to take a battery'''

    battery = get_battery(bid, request)
    context = {"battery": battery, "domain": settings.DOMAIN_NAME}

    if check_battery_edit_permission(request, battery) == True:

        # Create a user result object
        userid = uuid.uuid4()
        worker = get_worker(userid)
        context["new_user"] = userid
        worker.save()

        return render_to_response('experiments/generate_battery_user.html',
                                  context)

    else:
        return HttpResponseRedirect(battery.get_absolute_url())
Example #13
0
def serve_hit(request,hid):
    '''serve_hit runs the experiment after accepting a hit
    :param hid: the hit id
    :param wid: the worker id
    :param aid: the assignment id
    '''

    # No robots allowed!
    if request.user_agent.is_bot:
        return render_to_response("turk/robot_sorry.html")

    # Not allowed on tablet or phone
    if request.user_agent.is_pc:

        hit =  get_hit(hid,request)

        # Update the hit, only allow to continue if HIT is valid
        hit.update()
        if hit.status in ["D"]:
            return render_to_response("turk/hit_expired.html")

        battery = hit.battery
        aws = get_amazon_variables(request)

        if "" in [aws["worker_id"],aws["hit_id"]]:
            return render_to_response("turk/error_sorry.html")

        # Get Experiment Factory objects for each
        worker = get_worker(aws["worker_id"])

        check_battery_response = check_battery_view(battery, aws["worker_id"])
        if (check_battery_response):
            return check_battery_response

        # This is the submit URL, either external or sandbox
        host = get_host(hit)

        # Only supporting chrome
        if request.user_agent.browser.family != "Chrome":
            return render_to_response("turk/browser_sorry.html")

        # Try to get some info about browser, language, etc.
        browser = "%s,%s" %(request.user_agent.browser.family,request.user_agent.browser.version_string)
        platform = "%s,%s" %(request.user_agent.os.family,request.user_agent.os.version_string)

        # Initialize Assignment object, obtained from Amazon, and Result
        assignment,already_created = Assignment.objects.get_or_create(mturk_id=aws["assignment_id"],
                                                                      worker=worker,
                                                                      hit=hit)

        # if the assignment is new, we need to set up a task to run when the worker time runs out to allocate credit
        if already_created == True:
            assignment.accept_time = datetime.now()
            if hit.assignment_duration_in_hours != None:
                assign_experiment_credit.apply_async([worker.id],countdown=360*(hit.assignment_duration_in_hours))
            assignment.save()

        # Does the worker have experiments remaining for the hit?
        uncompleted_experiments = get_worker_experiments(worker,hit.battery)
        experiments_left = len(uncompleted_experiments)  
        if experiments_left == 0:
            # Thank you for your participation - no more experiments!
            return render_to_response("turk/worker_sorry.html")

        # if it's the last experiment, we will submit the result to amazon (only for surveys)
        last_experiment = False
        if experiments_left == 1:
            last_experiment = True

        task_list = select_experiments(battery,uncompleted_experiments)
        experimentTemplate = ExperimentTemplate.objects.filter(exp_id=task_list[0].template.exp_id)[0]
        experiment_type = get_experiment_type(experimentTemplate)
        task_list = battery.experiments.filter(template=experimentTemplate)
        template = "%s/mturk_battery.html" %(experiment_type)

        # Generate a new results object for the worker, assignment, experiment
        result,_ = Result.objects.update_or_create(worker=worker,
                                                   experiment=experimentTemplate,
                                                   assignment=assignment, # assignment has record of HIT
                                                   battery=hit.battery,
                                                   defaults={"browser":browser,"platform":platform})
        result.save()

        # Add variables to the context
        aws["amazon_host"] = host
        aws["uniqueId"] = result.id

        # If this is the last experiment, the finish button will link to a thank you page.
        if experiments_left == 1:
            next_page = "/finished"

        return deploy_battery(
            deployment="docker-mturk",
            battery=battery,
            experiment_type=experiment_type,
            context=aws,
            task_list=task_list,
            template=template,
            next_page=None,
            result=result,
            last_experiment=last_experiment,
            experiments_left=experiments_left-1
        )

    else:
        return render_to_response("turk/error_sorry.html")
Example #14
0
def serve_battery(request, bid, userid=None):
    '''prepare for local serve of battery'''

    next_page = None
    battery = get_battery(bid, request)

    # No robots allowed!
    if request.user_agent.is_bot:
        return render_to_response("turk/robot_sorry.html")

    # Is userid not defined, redirect them to preview
    if userid == None:
        return preview_battery(request, bid)

    worker = get_worker(userid, create=False)
    if isinstance(worker, list):  # no id means returning []
        return render_to_response("turk/invalid_id_sorry.html")

    # Try to get some info about browser, language, etc.
    browser = "%s,%s" % (request.user_agent.browser.family,
                         request.user_agent.browser.version_string)
    platform = "%s,%s" % (request.user_agent.os.family,
                          request.user_agent.os.version_string)
    deployment = "docker-local"

    # Does the worker have experiments remaining?
    uncompleted_experiments = get_worker_experiments(worker, battery)
    if len(uncompleted_experiments) == 0:
        # Thank you for your participation - no more experiments!
        return render_to_response("turk/worker_sorry.html")

    task_list = select_experiments(battery, uncompleted_experiments)
    experimentTemplate = ExperimentTemplate.objects.filter(
        exp_id=task_list[0].template.exp_id)[0]
    experiment_type = get_experiment_type(experimentTemplate)
    task_list = battery.experiments.filter(template=experimentTemplate)

    # Generate a new results object for the worker, assignment, experiment
    result, _ = Result.objects.update_or_create(worker=worker,
                                                experiment=experimentTemplate,
                                                battery=battery,
                                                defaults={
                                                    "browser": browser,
                                                    "platform": platform
                                                })
    result.save()

    context = {"worker_id": worker.id, "uniqueId": result.id}

    # If this is the last experiment, the finish button will link to a thank you page.
    if len(uncompleted_experiments) == 1:
        next_page = "/finished"

    # Determine template name based on template_type
    template = "%s/serve_battery.html" % (experiment_type)

    return deploy_battery(deployment="docker-local",
                          battery=battery,
                          experiment_type=experiment_type,
                          context=context,
                          task_list=task_list,
                          template=template,
                          next_page=next_page,
                          result=result)
Example #15
0
def assign_experiment_credit(worker_id):
    '''Function to parse all results for a worker, assign credit or bonus if needed,
    and either flag result or mark as completed. Should be fired if:
      1) worker completes full battery and expfactory.djstatus variable is finished
      2) worker does not accept Consent ("Disagree") and ends battery
      3) worker is deemed to have poorly completed some N experiments in a row
      4) worker does not complete experiments, HIT time runs out
    '''
    # Look up all result objects for worker
    worker = get_worker(worker_id)
    results = Result.objects.filter(worker=worker)

    # rejection criteria
    additional_dollars = 0.0
    rejection = False

    for result in results:

        if result.completed == True and result.credit_granted == False:
            # Get all experiments
            battery_experiments = result.assignment.hit.battery.experiments.all()
            experiment_ids = get_unique_experiments([result])
            experiments = ExperimentTemplate.objects.filter(tag__in=experiment_ids)

            for template in experiments:
                experiment = [b for b in battery_experiments if b.template == template]
                # If an experiment is deleted from battery, we have no way to know to reject/bonus
                if len(experiment)>0:
                    experiment = experiment[0]
                    do_catch = True if template.rejection_variable != None and experiment.include_catch == True else False
                    do_bonus = True if template.performance_variable != None and experiment.include_bonus == True else False
                    for credit_condition in experiment.credit_conditions.all():
                        variable_name = credit_condition.variable.name
                        variables = get_variables(result.taskdata,template.tag,variable_name)
                        func = [x[1] for x in credit_condition.OPERATOR_CHOICES if x[0] == credit_condition.operator][0]
                        # Needs to be tested for non numeric types
                        for variable in variables:
                            comparator = credit_condition.value
                            if isinstance(variable,float) or isinstance(variable,int):
                                variable = float(variable)
                                comparator = float(comparator)
                            if func(comparator,variable):
                                # For credit conditions, add to bonus!
                                if credit_condition.variable == template.performance_variable and do_bonus:
                                    additional_dollars = additional_dollars + credit_condition.amount
                                if credit_condition.variable == template.rejection_variable and do_catch:
                                    rejection = True

            # We remember granting credit on the level of results
            result.credit_granted = True
            result.save()

    if len(results) > 0:
        # Update HIT assignments - all results point to the same hit, so use the last one
        result.assignment.hit.update_assignments()
        assignment = Assignment.objects.filter(id=result.assignment.id)[0]

        # Allocate bonus, if any
        if not rejection:
            if additional_dollars != 0:
                assignment.bonus(value=additional_dollars)
            if assignment.status == "SUBMITTED" and TURK["debug"] != 1:
                assignment.approve()
        # We currently don't reject off the bat - we show user in pending tab.
        #else:
            #assignment.reject()
        assignment.save()
        assignment.update() # We may only want to call one of these
Example #16
0
def serve_hit(request,hid):

    next_page=None
    uncompleted_experiments = None
    result = None

    # No robots allowed!
    if request.user_agent.is_bot:
        return render_to_response("robot_sorry.html")

    if request.user_agent.is_pc:

        hit =  get_hit(hid,request)
        battery = hit.battery

        # This is the submit URL, either external or sandbox
        host = get_host()

        # An assignmentID means that the worker has accepted the task
        assignment_id = request.GET.get("assignmentId","")

        # worker has not accepted the task
        if assignment_id in ["ASSIGNMENT_ID_NOT_AVAILABLE",""]:
            template = "mturk_battery_preview.html"
            task_list = [battery.experiments.all()[0]]
            context = dict()
            deployment = "docker-preview"

        # worker has accepted the task
        else:
            template = "mturk_battery.html"
            worker_id = request.GET.get("workerId","")
            hit_id = request.GET.get("hitId","")
            turk_submit_to = request.GET.get("turkSubmitTo","")

            if "" in [worker_id,hit_id]:
                return render_to_response("error_sorry.html")

            # Get Experiment Factory objects for each
            worker = get_worker(worker_id)

            # Try to get some info about browser, language, etc.
            browser = "%s,%s" %(request.user_agent.browser.family,request.user_agent.browser.version_string)
            platform = "%s,%s" %(request.user_agent.os.family,request.user_agent.os.version_string)
            deployment = "docker"

            # Initialize Assignment object, obtained from Amazon, and Result
            assignment,already_created = Assignment.objects.get_or_create(mturk_id=assignment_id,hit=hit,worker=worker)

            # if the assignment is new, we need to set up a task to run when the worker time runs out to allocate credit
            if already_created == False:
                assign_experiment_credit.apply_async(countdown=hit.assignment_duration_in_seconds)
            assignment.save()

            # Does the worker have experiments remaining for the hit?
            uncompleted_experiments = get_worker_experiments(worker,hit.battery)
            if len(uncompleted_experiments) == 0:
                # Thank you for your participation - no more experiments!
                return render_to_response("worker_sorry.html")

            task_list = select_random_n(uncompleted_experiments,1)
            experimentTemplate = ExperimentTemplate.objects.filter(exp_id=task_list[0])[0]
            task_list = battery.experiments.filter(template=experimentTemplate)

            # Generate a new results object for the worker, assignment, experiment
            result,_ = Result.objects.update_or_create(worker=worker,
                                                       experiment=experimentTemplate,
                                                       assignment=assignment, # assignment has record of HIT
                                                       battery=hit.battery,
                                                       defaults={"browser":browser,"platform":platform})
            result.save()

            context = {
                "worker_id": worker_id,
                "assignment_id": assignment_id,
                "amazon_host": host,
                "hit_id": hit_id,
                "uniqueId":result.id
            }

            # If this is the last experiment, the finish button will link to a thank you page.
            if len(uncompleted_experiments) == 1:
                next_page = "/finished"

        return deploy_battery(deployment=deployment,
                              battery=battery,
                              context=context,
                              task_list=task_list,
                              template=template,
                              uncompleted_experiments=uncompleted_experiments,
                              next_page=next_page,
                              result=result)

    else:
        return render_to_response("pc_sorry.html")