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)
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)
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]
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")
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")
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()
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()
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]
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")
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")
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())
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())
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")
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)
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
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")