3 # Copyright (C) 2013 FinalsClub Foundation
4 from boto.mturk.qualification import PercentAssignmentsApprovedRequirement, Qualifications
5 from boto.mturk.question import Overview, FormattedContent, QuestionContent, Question, FreeTextAnswer, QuestionForm, \
7 from celery import task
8 from celery.utils.log import get_task_logger
9 from boto.mturk.connection import MTurkConnection
10 from django.contrib.sites.models import Site
11 from django.core.exceptions import ObjectDoesNotExist
12 from karmaworld.apps.notes.models import Note
13 from karmaworld.apps.quizzes.models import Keyword
15 logger = get_task_logger(__name__)
17 HIT_TITLE = 'Help people learn by finding keywords in college course notes'
18 HIT_DESCRIPTION = "Read students' course notes on KarmaNotes.org and " \
19 "identify 10 keywords along with descriptions of them"
20 HIT_OVERVIEW_TEMPLATE = \
21 '<p>Go to the page at KarmaNotes.org by clicking the link provided below. ' \
22 '<strong>Identify 10 key words (or short phrases) that are the most important to the document</strong> ' \
23 'on the page. This requires reading and understanding the document. Write these words in the boxes below. ' \
24 'Then, write definitions or descriptions of these keywords as they are provided in the page. ' \
25 'If the page does not provide a definition or description, leave the box blank. ' \
26 'For example, keywords might be "John Locke," "the Protestant reformation," ' \
27 'or "existentialism." Their respective definitions or descriptions might be "life, ' \
28 'liberty, and property," "schism in Christianity started by Martin Luther," and ' \
29 '"existence precedes essence."</p>' \
30 '<p>Notes link: <strong><a href="http://{domain}{link}">' \
31 'http://{domain}{link}</a></strong></p>'
32 HIT_KEYWORDS = 'writing, summary, keywords'
33 HIT_DURATION = 60 * 60 * 24 * 7
35 HIT_PERCENT_APPROVED_REQUIREMENT = PercentAssignmentsApprovedRequirement(comparator='GreaterThan', integer_value=95)
36 HIT_QUALIFICATION = Qualifications(requirements=[HIT_PERCENT_APPROVED_REQUIREMENT])
39 ('keyword01', 'Keyword 1'),
40 ('keyword02', 'Keyword 2'),
41 ('keyword03', 'Keyword 3'),
42 ('keyword04', 'Keyword 4'),
43 ('keyword05', 'Keyword 5'),
44 ('keyword06', 'Keyword 6'),
45 ('keyword07', 'Keyword 7'),
46 ('keyword08', 'Keyword 8'),
47 ('keyword09', 'Keyword 9'),
48 ('keyword10', 'Keyword 10'),
52 ('definition01', 'Definition 1'),
53 ('definition02', 'Definition 2'),
54 ('definition03', 'Definition 3'),
55 ('definition04', 'Definition 4'),
56 ('definition05', 'Definition 5'),
57 ('definition06', 'Definition 6'),
58 ('definition07', 'Definition 7'),
59 ('definition08', 'Definition 8'),
60 ('definition09', 'Definition 9'),
61 ('definition10', 'Definition 10'),
65 def submit_extract_keywords_hit(note):
66 """Create a Mechanical Turk HIT that asks a worker to
67 choose keywords and definitions from the given note."""
70 from karmaworld.secret.mturk import AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, MTURK_HOST
72 logger.warn('Could not find Mechanical Turk secrets, not running submit_extract_keywords_hit')
75 connection = MTurkConnection(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY,
79 overview.append(FormattedContent(HIT_OVERVIEW_TEMPLATE.format(domain=Site.objects.get_current(),
80 link=note.get_absolute_url())))
82 keyword_fta = FreeTextAnswer()
83 keyword_fta.num_lines = 1
85 definition_fta = FreeTextAnswer()
86 definition_fta.num_lines = 3
88 question_form = QuestionForm()
89 question_form.append(overview)
91 for i in range(min(len(KEYWORD_FIELDS), len(DEFINITION_FIELDS))):
92 keyword_content = QuestionContent()
93 keyword_content.append_field('Title', KEYWORD_FIELDS[i][1])
94 keyword_question = Question(identifier=KEYWORD_FIELDS[i][0],
95 content=keyword_content,
96 answer_spec=AnswerSpecification(keyword_fta),
98 question_form.append(keyword_question)
100 definition_content = QuestionContent()
101 definition_content.append_field('Title', DEFINITION_FIELDS[i][1])
102 definition_question = Question(identifier=DEFINITION_FIELDS[i][0],
103 content=definition_content,
104 answer_spec=AnswerSpecification(definition_fta),
106 question_form.append(definition_question)
108 connection.create_hit(questions=question_form, max_assignments=1,
109 title=HIT_TITLE, description=HIT_DESCRIPTION,
110 keywords=HIT_KEYWORDS, duration=HIT_DURATION,
111 reward=HIT_REWARD, qualifications=HIT_QUALIFICATION,
112 annotation=str(note.id))
115 @task(name='get_extract_keywords_results')
116 def get_extract_keywords_results():
119 from karmaworld.secret.mturk import AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, MTURK_HOST
121 logger.warn('Could not find Mechanical Turk secrets, not running get_extract_keywords_results')
124 connection = MTurkConnection(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY,
127 reviewable_hits = connection.get_reviewable_hits(page_size=100)
128 for hit in reviewable_hits:
130 note_id = connection.get_hit(hit.HITId)[0].RequesterAnnotation
131 except AttributeError:
132 logger.error('HIT {0} does not have a RequesterAnnotation, '
133 'so we cannot determine which note it references'.format(hit.HITId))
137 note = Note.objects.get(id=note_id)
138 except ObjectDoesNotExist:
139 logger.error('Could not find note {0} which was referenced by HIT {1}'.format(note_id, hit.HITId))
143 assignments = [a for a in connection.get_assignments(hit.HITId) if a.AssignmentStatus == 'Submitted']
144 for assignment in assignments:
145 for question_form_answer in assignment.answers[0]:
146 answers[question_form_answer.qid] = question_form_answer.fields[0]
148 for i in range(min(len(KEYWORD_FIELDS), len(DEFINITION_FIELDS))):
149 keyword_qid = KEYWORD_FIELDS[i][0]
150 definition_qid = DEFINITION_FIELDS[i][0]
152 keyword = answers[keyword_qid]
153 definition = answers[definition_qid]
154 Keyword.objects.create(word=keyword, definition=definition, note=note, unreviewed=True)
158 for assignment in assignments:
159 connection.approve_assignment(assignment.AssignmentId)
161 connection.dispose_hit(hit.HITId)