diff --git a/expdj/apps/experiments/views.py b/expdj/apps/experiments/views.py index 9fa0e38..54f0497 100644 --- a/expdj/apps/experiments/views.py +++ b/expdj/apps/experiments/views.py @@ -409,7 +409,7 @@ def serve_battery(request,bid,userid=None): missing_batteries, blocking_batteries = check_battery_dependencies(battery, userid) if missing_batteries or blocking_batteries: return render_to_response( - "experiments/battery_requirements_not_met.html", + "turk/battery_requirements_not_met.html", context={'missing_batteries': missing_batteries, 'blocking_batteries': blocking_batteries} ) diff --git a/expdj/apps/turk/forms.py b/expdj/apps/turk/forms.py index eb35dad..c40dfb6 100644 --- a/expdj/apps/turk/forms.py +++ b/expdj/apps/turk/forms.py @@ -31,3 +31,13 @@ def __init__(self, *args, **kwargs): self.helper.layout = Layout() tab_holder = TabHolder() self.helper.add_input(Submit("submit", "Save")) + +class WorkerContactForm(forms.Form): + subject = forms.CharField(label="Subject") + message = forms.CharField(widget=forms.Textarea, label="Message") + + def __init__(self, *args, **kwargs): + super(WorkerContactForm, self).__init__(*args, **kwargs) + self.helper = FormHelper(self) + self.helper.layout = Layout() + self.helper.add_input(Submit("submit", "Send")) diff --git a/expdj/apps/turk/models.py b/expdj/apps/turk/models.py index 5319836..940da73 100644 --- a/expdj/apps/turk/models.py +++ b/expdj/apps/turk/models.py @@ -407,7 +407,6 @@ class Assignment(models.Model): (True, 'Completed')), default=False,verbose_name="participant completed the entire assignment") - def create(self): init_connection_callback(sender=self.hit) diff --git a/expdj/apps/turk/templates/turk/contact_worker_modal.html b/expdj/apps/turk/templates/turk/contact_worker_modal.html new file mode 100644 index 0000000..7fd4eae --- /dev/null +++ b/expdj/apps/turk/templates/turk/contact_worker_modal.html @@ -0,0 +1,19 @@ +{% load crispy_forms_tags %} + diff --git a/expdj/apps/turk/templates/turk/manage_hit.html b/expdj/apps/turk/templates/turk/manage_hit.html index d6e7fde..7673b43 100644 --- a/expdj/apps/turk/templates/turk/manage_hit.html +++ b/expdj/apps/turk/templates/turk/manage_hit.html @@ -73,6 +73,7 @@

In Progress

Worker ID Status Accept Time + Contact @@ -82,6 +83,7 @@

In Progress

{{ assignment.worker }} {{ assignment.status }} {{ assignment.accept_time | localize }} + Contact Worker {% endfor %} @@ -158,6 +160,7 @@

Approved

Worker ID Status Accept Time + Contact @@ -167,6 +170,7 @@

Approved

{{ assignment.worker }} {{ assignment.status }} {{ assignment.accept_time | localize }} + Contact Worker {% endfor %} @@ -175,6 +179,8 @@

Approved

{% endif %} + {% endblock %} @@ -190,6 +196,11 @@

Approved

$('.collapse').collapse('hide'); }) +$('.contact_worker').on("click", function(e) { + e.preventDefault(); + $('#contact_modal').modal("show").load(this.href); +}); + }) {% endblock %} diff --git a/expdj/apps/turk/urls.py b/expdj/apps/turk/urls.py index 1bdf124..73c84d8 100644 --- a/expdj/apps/turk/urls.py +++ b/expdj/apps/turk/urls.py @@ -1,6 +1,6 @@ -from expdj.apps.turk.views import edit_hit, delete_hit, expire_hit, preview_hit, \ -serve_hit, multiple_new_hit, end_assignment, finished_view, not_consent_view, \ -survey_submit, manage_hit +from expdj.apps.turk.views import (edit_hit, delete_hit, expire_hit, + preview_hit, serve_hit, multiple_new_hit, end_assignment, finished_view, + not_consent_view, survey_submit, manage_hit, contact_worker) from expdj.apps.experiments.views import sync from django.views.generic.base import TemplateView from django.conf.urls import patterns, url @@ -8,9 +8,21 @@ urlpatterns = patterns('', # HITS url(r'^hits/(?P\d+|[A-Z]{8})/new$',edit_hit,name='new_hit'), - url(r'^hits/(?P\d+|[A-Z]{8})/(?P\d+|[A-Z]{8})/manage$',manage_hit,name='manage_hit'), - url(r'^hits/(?P\d+|[A-Z]{8})/multiple$',multiple_new_hit,name='multiple_new_hit'), - url(r'^hits/(?P\d+|[A-Z]{8})/(?P\d+|[A-Z]{8})/edit$',edit_hit,name='edit_hit'), + url( + r'^hits/(?P\d+|[A-Z]{8})/(?P\d+|[A-Z]{8})/manage$', + manage_hit, + name='manage_hit' + ), + url( + r'^hits/(?P\d+|[A-Z]{8})/multiple$', + multiple_new_hit, + name='multiple_new_hit' + ), + url( + r'^hits/(?P\d+|[A-Z]{8})/(?P\d+|[A-Z]{8})/edit$', + edit_hit, + name='edit_hit' + ), url(r'^hits/(?P\d+|[A-Z]{8})/delete$',delete_hit,name='delete_hit'), url(r'^hits/(?P\d+|[A-Z]{8})/expire$',expire_hit,name='expire_hit'), @@ -18,9 +30,18 @@ url(r'^accept/(?P\d+|[A-Z]{8})',serve_hit,name='serve_hit'), url(r'^turk/(?P\d+|[A-Z]{8})',preview_hit,name='preview_hit'), url(r'^turk/preview',not_consent_view,name='not_consent_view'), - url(r'^turk/end/(?P\d+|[A-Z]{8})',end_assignment,name='end_assignment'), - url(r'^surveys/(?P\d+|[A-Z]{8})/(?P[A-Za-z0-9]{30})/submit$',survey_submit,name='survey_submit'), + url( + r'^turk/end/(?P\d+|[A-Z]{8})', + end_assignment, + name='end_assignment' + ), + url( + r'^surveys/(?P\d+|[A-Z]{8})/(?P[A-Za-z0-9]{30})/submit$', + survey_submit, + name='survey_submit' + ), url(r'^sync/(?P\d+|[A-Z]{8})/$',sync,name='sync_data'), url(r'^sync/$',sync,name='sync_data'), - url(r'^finished$', finished_view, name="finished_view") + url(r'^finished$', finished_view, name="finished_view"), + url(r'^worker/contact/(?P\d+)',contact_worker,name='contact_worker') ) diff --git a/expdj/apps/turk/utils.py b/expdj/apps/turk/utils.py index 6ec8592..1f9b803 100644 --- a/expdj/apps/turk/utils.py +++ b/expdj/apps/turk/utils.py @@ -1,16 +1,19 @@ -from expdj.apps.experiments.models import Experiment -from boto.mturk.connection import MTurkConnection -from expdj.settings import BASE_DIR, MTURK_ALLOW -from boto.mturk.question import ExternalQuestion -from boto.mturk.price import Price import ConfigParser import datetime -import pandas import json import os +from boto.mturk.connection import MTurkConnection +from boto.mturk.price import Price +from boto.mturk.question import ExternalQuestion +import pandas + from django.conf import settings +from expdj.apps.experiments.models import Experiment +from expdj.settings import BASE_DIR, MTURK_ALLOW + + # RESULTS UTILS def to_dict(input_ordered_dict): @@ -132,3 +135,6 @@ def get_time_difference(d1,d2,format='%Y-%m-%d %H:%M:%S'): if isinstance(d2,str): d2 = datetime.datetime.strptime(d2, format) return (d2 - d1).total_seconds() / 60 + + + diff --git a/expdj/apps/turk/views.py b/expdj/apps/turk/views.py index c8e337c..88720ad 100644 --- a/expdj/apps/turk/views.py +++ b/expdj/apps/turk/views.py @@ -9,21 +9,22 @@ from django.contrib.auth.decorators import login_required from django.core.management.base import BaseCommand -from django.http.response import HttpResponseRedirect, HttpResponseForbidden, HttpResponse, Http404 +from django.http.response import (HttpResponseRedirect, HttpResponseForbidden, + HttpResponse, Http404, HttpResponseNotAllowed) from django.shortcuts import get_object_or_404, render_to_response, render, redirect from django.utils import timezone from django.views.decorators.csrf import ensure_csrf_cookie -from expdj.apps.experiments.models import Battery, ExperimentTemplate -from expdj.apps.experiments.views import check_battery_edit_permission, check_mturk_access, \ -get_battery_intro, deploy_battery +from expdj.apps.experiments.models import (Battery, ExperimentTemplate) +from expdj.apps.experiments.views import (check_battery_edit_permission, + check_mturk_access, get_battery_intro, deploy_battery) from expdj.apps.experiments.utils import get_experiment_type, select_experiments -from expdj.apps.turk.forms import HITForm +from expdj.apps.turk.forms import HITForm, WorkerContactForm from expdj.apps.turk.models import Worker, HIT, Assignment, Result, get_worker from expdj.apps.turk.tasks import (assign_experiment_credit, - check_battery_dependencies, get_unique_experiments) -from expdj.apps.turk.utils import (get_connection, get_host, get_worker_url, - get_worker_experiments) + get_unique_experiments) +from expdj.apps.turk.utils import (get_connection, get_credentials, get_host, + get_worker_url, get_worker_experiments) from expdj.settings import BASE_DIR,STATIC_ROOT,MEDIA_ROOT media_dir = os.path.join(BASE_DIR,MEDIA_ROOT) @@ -339,6 +340,42 @@ def edit_hit(request, bid, hid=None): else: return HttpResponseForbidden() +@login_required +def contact_worker(request, aid): + mturk_permission = check_mturk_access(request) + + if mturk_permission == False: + return HttpResponseForbidden() + + assignment = Assignment.objects.get(id=aid) + worker = assignment.worker + if request.method == "GET": + form = WorkerContactForm() + context = { + "form": form, + "worker": worker, + "assignment": assignment + } + return render(request, "turk/contact_worker_modal.html", context) + elif request.method == "POST": + form = WorkerContactForm(request.POST) + if form.is_valid(): + AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY_ID = get_credentials( + battery=assignment.hit.battery + ) + conn = get_connection( + AWS_ACCESS_KEY_ID, + AWS_SECRET_ACCESS_KEY_ID, + hit=assignment.hit + ) + subject = form.cleaned_data['subject'] + message = form.cleaned_data['message'] + conn.notify_workers([worker.id], subject, message) + return redirect('manage_hit', bid=assignment.hit.battery.id, + hid=assignment.hit.id) + else: + return HttpResponseNotAllowed() + # Expire a hit @login_required def expire_hit(request, hid):