Beispiel #1
0
def sync(request,rid=None):
    '''sync
    view/method for running experiments to get data from the server
    :param rid: the result object ID, obtained before user sees page
    '''

    if request.method == "POST":

        data = json.loads(request.body)

        if rid != None:
        # Update the result, already has worker and assignment ID stored
            result,_ = Result.objects.get_or_create(id=data["taskdata"]["uniqueId"])
            battery = result.battery
            result.taskdata = data["taskdata"]["data"]
            result.current_trial = data["taskdata"]["currenttrial"]
            result.save()

            # if the worker finished the current experiment
            if data["djstatus"] == "FINISHED":
                # Mark experiment as completed
                result.completed = True
                result.save()

                # if the worker has completed all tasks, give final credit
                completed_experiments = get_worker_experiments(result.worker,battery,completed=True)
                if len(completed_experiments) == battery.experiments.count():
                    assignment = Assignment.objects.filter(id=result.assignment_id)[0]
                    assignment.update()
                    assign_experiment_credit.apply_async(args=[result.worker.id])

            data = json.dumps(data)

    else:
        data = json.dumps({"message":"received!"})
    return HttpResponse(data, content_type='application/json')
Beispiel #2
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")
Beispiel #3
0
def sync(request,rid=None):
    '''localsync
    view/method for running experiments to get data from the server
    :param rid: the result object ID, obtained before user sees page
    '''

    if request.method == "POST":

        if rid != None:
        # Update the result, already has worker and assignment ID stored
            result,_ = Result.objects.get_or_create(id=rid)
            battery = result.battery
            experiment_template = get_experiment_type(result.experiment)
            if experiment_template == "experiments":
                data = json.loads(request.body)
                result.taskdata = data["taskdata"]["data"]
                result.current_trial = data["taskdata"]["currenttrial"]
                djstatus = data["djstatus"]
            elif experiment_template == "games":
                data = json.loads(request.body)
                redirect_url = data["redirect_url"]
                result.taskdata = data["taskdata"]
                djstatus = data["djstatus"]
            elif experiment_template == "surveys":
                data = request.POST
                redirect_url = data["url"]
                djstatus = data["djstatus"]
                # Remove keys we don't want
                data = remove_keys(data,["process","csrfmiddlewaretoken","url","djstatus"])
                result.taskdata = complete_survey_result(result.experiment.exp_id,data)

            result.save()

            # if the worker finished the current experiment
            if djstatus == "FINISHED":

                # Mark experiment as completed
                result.completed = True
                result.finishtime = timezone.now()
                result.version = result.experiment.version
                result.save()

                # Fire a task to check blacklist status, add bonus
                check_blacklist.apply_async([result.id])
                experiment_reward.apply_async([result.id])

                data = dict()
                data["finished_battery"] = "NOTFINISHED"
                data["djstatus"] = djstatus
                completed_experiments = get_worker_experiments(result.worker,battery,completed=True)
                completed_experiments = numpy.unique([x.template.exp_id for x in completed_experiments]).tolist()
                if len(completed_experiments) == battery.experiments.count():
                    assign_experiment_credit.apply_async([result.worker.id],countdown=60)
                    data["finished_battery"] = "FINISHED"

                # Refresh the page if we've completed a survey or game
                if experiment_template in ["surveys"]:
                    return redirect(redirect_url)

            data = json.dumps(data)

    else:
        data = json.dumps({"message":"received!"})

    return HttpResponse(data, content_type='application/json')
Beispiel #4
0
def sync(request, rid=None):
    '''localsync
    view/method for running experiments to get data from the server
    :param rid: the result object ID, obtained before user sees page
    '''

    if request.method == "POST":

        if rid != None:
            # Update the result, already has worker and assignment ID stored
            result, _ = Result.objects.get_or_create(id=rid)
            battery = result.battery
            experiment_template = get_experiment_type(result.experiment)
            if experiment_template == "experiments":
                data = json.loads(request.body)
                result.taskdata = data["taskdata"]["data"]
                result.current_trial = data["taskdata"]["currenttrial"]
                djstatus = data["djstatus"]
            elif experiment_template == "games":
                data = json.loads(request.body)
                redirect_url = data["redirect_url"]
                result.taskdata = data["taskdata"]
                djstatus = data["djstatus"]
            elif experiment_template == "surveys":
                data = request.POST
                redirect_url = data["url"]
                djstatus = data["djstatus"]
                # Remove keys we don't want
                data = remove_keys(
                    data,
                    ["process", "csrfmiddlewaretoken", "url", "djstatus"])
                result.taskdata = complete_survey_result(
                    result.experiment.exp_id, data)

            result.save()

            # if the worker finished the current experiment
            if djstatus == "FINISHED":

                # Mark experiment as completed
                result.completed = True
                result.finishtime = timezone.now()
                result.version = result.experiment.version
                result.save()

                # Fire a task to check blacklist status
                check_blacklist.apply_async([result.id])

                data = dict()
                data["finished_battery"] = "NOTFINISHED"
                data["djstatus"] = djstatus
                completed_experiments = get_worker_experiments(result.worker,
                                                               battery,
                                                               completed=True)
                completed_experiments = numpy.unique([
                    x.template.exp_id for x in completed_experiments
                ]).tolist()
                if len(completed_experiments) == battery.experiments.count():
                    assign_experiment_credit.apply_async([result.worker.id],
                                                         countdown=60)
                    data["finished_battery"] = "FINISHED"

                # Refresh the page if we've completed a survey or game
                if experiment_template in ["surveys"]:
                    return redirect(redirect_url)

            data = json.dumps(data)

    else:
        data = json.dumps({"message": "received!"})

    return HttpResponse(data, content_type='application/json')
Beispiel #5
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")