diff --git a/src/main/python/crowd_server/amt/interface.py b/src/main/python/crowd_server/amt/interface.py index 9b379f9..b26261d 100644 --- a/src/main/python/crowd_server/amt/interface.py +++ b/src/main/python/crowd_server/amt/interface.py @@ -72,6 +72,7 @@ def get_assignment_context(request): def get_response_context(request): # Extract data from the request return {'answers': request.POST.get('answers'), + 'metrics': request.POST.get('metrics'), 'task_id': request.POST.get('HITId'), 'worker_id': request.POST.get('workerId'), 'assignment_id': request.POST.get('assignmentId') diff --git a/src/main/python/crowd_server/basecrowd/interface.py b/src/main/python/crowd_server/basecrowd/interface.py index 7e0c5eb..fdecbd9 100644 --- a/src/main/python/crowd_server/basecrowd/interface.py +++ b/src/main/python/crowd_server/basecrowd/interface.py @@ -114,7 +114,8 @@ def get_response_context(request): return {'task_id': request.POST.get('task_id', None), 'worker_id': request.POST.get('worker_id', None), 'assignment_id': request.POST.get('assignment_id', None), - 'answers': request.POST.get('answers', None) + 'answers': request.POST.get('answers', None), + 'metrics': request.POST.get('metrics', None) } diff --git a/src/main/python/crowd_server/basecrowd/models.py b/src/main/python/crowd_server/basecrowd/models.py index 3c4e93b..7151c38 100644 --- a/src/main/python/crowd_server/basecrowd/models.py +++ b/src/main/python/crowd_server/basecrowd/models.py @@ -102,6 +102,9 @@ class AbstractCrowdWorkerResponse(models.Model): # The content of the response (specific to the task type). content = models.TextField() + # The content of recorded experimental metrics + metrics = models.TextField() + # The assignment id of this response assignment_id = models.CharField(max_length=200) diff --git a/src/main/python/crowd_server/basecrowd/templates/basecrowd/base.html b/src/main/python/crowd_server/basecrowd/templates/basecrowd/base.html index 3f68d05..f40a5f5 100644 --- a/src/main/python/crowd_server/basecrowd/templates/basecrowd/base.html +++ b/src/main/python/crowd_server/basecrowd/templates/basecrowd/base.html @@ -13,6 +13,14 @@ return $(".label_container :input"); } {% endblock get_answer_inputs_func %} + + {% block get_task_divs_func %} + function get_task_divs() + { + return $(".panel.panel-default"); + } + {% endblock get_task_divs_func%} + {% block validate_func %} function validate_answers() { @@ -32,6 +40,14 @@ return answers; } {% endblock build_answer_data_func %} + + //make metric dictionary + {% block build_metric_data_func %} + function build_metric_data() + { + return {"time" : time}; + } + {% endblock build_metric_data_func %} {% block get_submit_context_func %} function get_submit_context(urlParamStrings) @@ -47,12 +63,15 @@ { // build the user's answers into the right format var answers = build_answer_data(); - + var metrics = build_metric_data(); + // get additional context from the URL or page var paramstr = window.location.search.substring(1); var parampairs = paramstr.split("&"); var data = get_submit_context(parampairs); data.answers = JSON.stringify(answers); + data.metrics = JSON.stringify(metrics); + return data; } {% endblock prepare_submit_data_func %} @@ -86,6 +105,41 @@ } {% endblock handle_is_accepted_func %} + {% block initialize_metric_func %} + function initialize_metric() + { + {% block create_global_variables %} + + // A map that maps task_id to the time the worker spent on it. + time = {} + // The task_id of the task the mouse is currently on, empty if the mouse is outside any task. + focus = ""; + // The update freqency of the setInterval function, in ms. + delay = 10; + + {% endblock %} + + {% block Register_event_listeners %} + + // Register a mouseenter event listener for each task divs. + get_task_divs().mouseenter(function(){ + focus = $(this).find(":radio:first").attr("id"); + }); + + // Use setInterval to track timing + setInterval(function(){ + if (focus != "") + if (focus in time) + time[focus] += delay; + else + time[focus] = delay; + }, delay); + + {% endblock %} + + } + {% endblock initialize_metric_func %} + {% block initialize_form_validation_func %} function initialize_form_validation() { @@ -137,6 +191,9 @@ // Prepare form validation initialize_form_validation(); + + // Prepare metric collection + initialize_metric(); }); {% endblock ready_func %} @@ -179,15 +236,15 @@
{% block instruction %} - {% if group_context.instruction %} - {{group_context.instruction | safe}} - {% else %} - {% block default_instruction %} - Hey, I am an instruction! + {% if group_context.instruction %} + {{group_context.instruction | safe}} + {% else %} + {% block default_instruction %} + Hey, I am an instruction! {% endblock %} {% endif %} - {% endblock %} + {% endblock %}
{% endblock instruction_panel %} diff --git a/src/main/python/crowd_server/basecrowd/views.py b/src/main/python/crowd_server/basecrowd/views.py index 1db0e64..3686a30 100644 --- a/src/main/python/crowd_server/basecrowd/views.py +++ b/src/main/python/crowd_server/basecrowd/views.py @@ -178,7 +178,7 @@ def post_response(request, crowd_name): # validate context interface.require_context( - context, ['assignment_id', 'task_id', 'worker_id', 'answers'], + context, ['assignment_id', 'task_id', 'worker_id', 'answers', 'metrics'], ValueError("Response context missing required keys.")) # Check if this is a duplicate response @@ -196,6 +196,7 @@ def post_response(request, crowd_name): task=current_task, worker=current_worker, content=context['answers'], + metrics=context['metrics'], assignment_id=context['assignment_id']) interface.response_pre_save(current_response) current_response.save()