def wrapper(request, *args, **kwargs): assignmentId = request.GET.get('assignmentId') print("numround: ", NUMROUNDS) if assignmentId is not None and assignmentId != 'ASSIGNMENT_ID_NOT_AVAILABLE': hitObj = HIT.objects.only('data').get_or_create( assignment_id=assignmentId, defaults={'data': { 'startTime': datetime.now() }})[0] request.hit = hitObj.data roundnums = request.hit.setdefault('roundnums', {}) numInPhase = roundnums.get( func.__name__, 0) # this line is pretty unsafe, but it will do whits = HIT.objects.filter( data__workerId=request.GET['workerId']).exclude( data__hitId=request.GET['hitId']).exists() if whits: return over(request, func.__name__) # increment roundsnum by 1 if request.method == 'POST': roundnums[func.__name__] = numInPhase + 1 request.hit['hitId'] = request.GET['hitId'] request.hit['workerId'] = request.GET['workerId'] hitObj.save() # either pay the worker or move onto the next round if numInPhase >= ROUNDSMAX[func.__name__]: return over(request, func.__name__) else: return func(request, *args, **kwargs) elif request.user.is_staff or request.user.is_superuser: assignmentId = f"{request.user.username}__{uuid.uuid4().hex}"[:31] hitId = 'admin' workerId = 'admin' return redirect( f"{request.path_info}?assignmentId={assignmentId}&hitId={hitId}&workerId={workerId}&turkSubmitTo=" ) elif assignmentId == 'ASSIGNMENT_ID_NOT_AVAILABLE': return func(request, *args, previewMode=True, **kwargs) else: raise Http404
def wrapper(request, *args, **kwargs): assignmentId = request.GET.get('assignmentId') is_mturker = assignmentId not in (None, 'ASSIGNMENT_ID_NOT_AVAILABLE') if is_mturker: request.session['assignmentId'] = assignmentId if (request.user.is_staff or request.user.is_superuser) and "assignmentId" not in request.session: request.session['assignmentId'] = request.user.username if "assignmentId" in request.session: hitObj = HIT.objects.only('data').get_or_create(session=request.session.session_key, defaults={'data': {}})[0] hit = hitObj.data roundnums = hit.setdefault('roundnums', {}) numInPhase = roundnums.get(func.__name__, 0) # this line is pretty unsafe, but it will do if request.method == 'POST': output = func(request, *args, **kwargs) roundnums[func.__name__] = numInPhase + 1 hitObj.data = hit hitObj.save() return output else: return over(request) if numInPhase >= NUMROUNDS else func(request, *args, **kwargs) else: return func(request, *args, **{'previewMode': True, **kwargs})
def wrapper(request, *args, **kwargs): assignmentId = request.GET.get('assignmentId') if assignmentId == 'ASSIGNMENT_ID_NOT_AVAILABLE': assignmentId = None if assignmentId: hitObj = HIT.objects.only('data').get_or_create(assignment_id=assignmentId, defaults={'data': {'startTime': datetime.now()}})[0] request.hit = hitObj.data roundnums = request.hit.setdefault('roundnums', {}) numInPhase = roundnums.get(func.__name__, 0) # this line is pretty unsafe, but it will do if request.method == 'POST': roundnums[func.__name__] = numInPhase + 1 request.hit['hitId'] = request.GET['hitId'] request.hit['workerId'] = request.GET['workerId'] hitObj.save() return func(request, *args, **kwargs) else: if numInPhase >= ROUNDSMAX[func.__name__]: return over(request, func.__name__) else: return func(request, *args, **kwargs) elif request.user.is_staff or request.user.is_superuser: assignmentId = f"{request.user.username}__{uuid.uuid4().hex}"[:31] hitId = 'admin' workerId = 'admin' return redirect(f"{request.path_info}?assignmentId={assignmentId}&hitId={hitId}&workerId={workerId}&turkSubmitTo=") else: return func(request, *args, previewMode=True, **kwargs)
def step03(request, previewMode=False): url_list = [] assignmentId = request.GET.get('assignmentId') feature = Feature.objects.filter(is_bias__gt=-3).order_by('feature') feature_list = list(feature.values_list('feature', flat=True)) print(feature_list) if request.method == 'POST': result = int(request.POST.get('data')) round = int(request.POST.get('round')) Feature.objects.filter(feature=feature_list[round]).update( count=F('count') + result) print("round:", round, " feature:", feature_list[round], " post result:", result, len(feature_list) - 1) if round < len(feature_list) - 1: return HttpResponse(status=201) else: return render(request, 'feedback.html') else: # Get rounds played in total and by the current player rounds, roundsnum = popGetList(ImageModel.objects.filter( img__startswith=KEYRING).values_list('id', flat=True), count=21, phase=3) if len(rounds.post) >= ImageModel.objects.filter( img__startswith=KEYRING).count(): # push all to waiting page return over(request, 'step03') # Single image that will be sent to front-end, will expire in 300 seconds (temporary) # sending 21 images at a time data = [i.img.url for i in ImageModel.objects.filter(id__in=roundsnum)] data.extend([None] * (21 - len(data))) instructions = Phase03_instruction.get_queryset( Phase03_instruction) or ['none'] return render( request, 'step03.html', { 'feature': feature_list, 'image_url': data, 'roundnum': len(feature_list), 'previewMode': previewMode, 'instructions': instructions })
def phase01b(request, previewMode=False): # Only show people all the question and the answer. Keep in mind that people have the chance to click skip for different questions # There should be an array of question that got skipped. Each entry should the final question value assignmentId = request.GET.get('assignmentId') if request.method == 'POST': # Get the answer array for different # Update the rounds posted for phase 01b imgsets = step2_push(request) #pushPostList(request, '²') # get the dictionary from the front-end back dictionary = json.loads(request.POST.get('data[dict]')) print("I got the QA dict: ", dictionary) for imgset, (question, answer) in zip(imgsets, dictionary): print("Answer: ", answer) # if the answer is not empty, add into database que = Question.objects.get(text=question, isFinal=True) new_Ans = Answer.objects.create(text=answer, question=que, hit_id=assignmentId, imgset=imgset) # Check if the question has skip count reach some threshold (5 for example), isFinal=False QQ = Question.objects.get(text=question, isFinal=True) if QQ.answers.filter(text='').count() >= 5: QQ.isFinal = False QQ.save() return HttpResponse(status=201) # Get rounds played in total and by the current player roundsnum, imin, questions, stopGame = step2_pop(NUMROUNDS[phase01b.__name__]) if stopGame or not questions: return over(request, 'phase01b') # sending 4 images at a time data = [[i.img.url for i in ImageModel.objects.filter(id__in=rounds)] for rounds in roundsnum] data.extend([None] * (4 - len(data))) # Get all the insturctions sets instructions = Phase02_instruction.get_queryset(Phase02_instruction) or ['none'] #Get text instructions text_inst = TextInstruction.objects.get(phase='01b') #allQuestions = dict(Question.objects.filter(id__in=[*ids for ids in questions]).values_list('id', 'text')) #questions = [[allQuestions[id] for id in ids] for ids in questions] return render(request, 'phase01b.html', {'phase': 'PHASE 01b', 'image_url' : data, 'imgnum': imin, 'question_list' : [q.text for q in questions], 'assignmentId': assignmentId, 'previewMode': previewMode, 'instructions': instructions,'answer_list': [[i for i in q.answers.distinct().values_list('text', flat=True) if i != ''] for q in questions], 'text_inst':text_inst})
def step01(request, previewMode=False): url_list = [] if request.method == 'POST': # result = request.POST.getlist('features[]') result = request.POST.getlist('data[]') feature = Feature.objects.all().order_by('feature') feature_list = list(feature.values_list('feature', flat=True)) for feature in result: if feature not in feature_list: Feature.objects.bulk_create( [Feature(feature=feature, count=0, is_bias=0)]) print("post result: ", result) # replace this with either payment or going on to the next round messages.success(request, 'Submitted!') return render(request, 'feedback.html') else: # form = featureForm() # Get rounds played in total and by the current player rounds, roundsnum = popGetList( ImageModel.objects.filter(img__startswith=KEYRING).values_list( 'id', flat=True)) if len(rounds.post) >= ImageModel.objects.filter( img__startswith=KEYRING).count(): # push all to waiting page return over(request, 'step01') # Single image that will be sent to front-end, will expire in 300 seconds (temporary) # sending 4 images at a time data = [i.img.url for i in ImageModel.objects.filter(id__in=roundsnum)] data.extend([None] * (9 - len(data))) instructions = Phase01_instruction.get_queryset( Phase01_instruction) or ['none'] return render( request, 'step01.html', { 'url': data, 'previewMode': previewMode, 'instructions': instructions, 'NUMROUNDS': NUMROUNDS[step01.__name__], 'imgnum': roundsnum })
def phase03(request, previewMode=False): if not Attribute.objects.exists(): return over(request, 'phase03') # Update count if request.method == 'POST': words = request.POST.getlist('data[]') Attribute.objects.filter(word__in=words).update(count=F('count') - 1) return HttpResponse(status=201) else: assignmentId = request.GET.get('assignmentId') attributes = list(Attribute.objects.values_list('word', flat=True)) instructions = Phase03_instruction.get_queryset( Phase03_instruction) or ['none'] return render( request, 'phase03-update.html', { 'statements': attributes, 'instructions': instructions, 'assignmentId': assignmentId, 'previewMode': previewMode, 'PRODUCTION': PRODUCTION })
def phase01a(request, previewMode=False): # assignmentID for front-end submit javascript assignmentId = request.GET.get('assignmentId') # Need to check if request.method == 'POST': postList = pushPostList(request) # Get the Q and Ans for the current question, they should be at least one Q&A for all of the set questions = request.POST.getlist('data_q[]') answers = request.POST.getlist('data_a[]') # print("I got questions: ", questions) # print("I got answers: ", answers) # retrieve the json data for updating skip count for the previous questions validation_list = request.POST.getlist('data[]') correct_qs = [] for q in questions: text = q.replace(' ', '+') url = f'https://api.textgears.com/check.php?text={text}&key=SFCKdx4GHmSC1j6H' response = requests.get(url) wordsC = response.json() # print(wordsC) for err in wordsC['errors']: bad = err['bad'] good = err['better'] if good: q = q.replace(bad, good[0]) correct_qs.append(q) # Query list for the old data in the table old_Qs = list( Question.objects.filter(isFinal=True).values_list('text', 'id')) # print("old questions", old_Qs) questions = Question.objects.bulk_create([ Question(text=que, isFinal=False, imageID=list(ImageModel.objects.filter(id__in=postList)), hit_id=assignmentId) for que in correct_qs ]) new_Qs = [ (que.text, que.id) for que in questions ] #list(map(attrgetter('text', 'id'), questions)) # don't know which is better speedwise # print("new question", new_Qs) # Call the NLP function and get back with results, it should be something like wether it gets merged or kept # backend call NLP and get back the results, it should be a boolean and a string telling whether the new entry will be created or not # exist_q should be telling which new question got merged into acceptedList, id_merge, id_move = send__receive_data(new_Qs, old_Qs) id_merge = {int(k): v for k, v in id_merge.items()} id_move = {int(k): v for k, v in id_move.items()} # print("acceptedList is: ", acceptedList) #print("id_merge is: ", id_merge) # print("id_move is: ", id_move) Question.objects.filter(id__in=acceptedList).update(isFinal=True) #Question.objects.filter(id__in=[que.id for que in questions if que.id not in id_merge]).update(isFinal=True) # Store id_merge under mergeParent in the database id_merge_sql = Case( *[When(id=new, then=Value(old)) for new, old in id_merge.items()]) Question.objects.filter(id__in=id_merge).update( mergeParent=id_merge_sql) answers = Answer.objects.bulk_create([ Answer(question_id=id_merge.get(que.id, que.id), text=ans, hit_id=assignmentId, imgset=-1) for que, ans in zip(questions, answers) ]) with transaction.atomic(): id_move_sql = Case(*[ When(question_id=bad, then=Value(good)) for bad, good in id_move.items() ]) Answer.objects.filter(question_id__in=id_move).update( question_id=id_move_sql) id_move_sql = Case(*[ When(id=bad, then=Value(good)) for bad, good in id_move.items() ]) Question.objects.filter(id__in=id_move).update( isFinal=False, mergeParent=id_move_sql) Question.objects.filter(id__in=id_move.values()).update( isFinal=True) return HttpResponse(status=201) # Get rounds played in total and by the current player rounds, roundsnum = popGetList(ImageModel.objects.filter( img__startswith=KEYRING).values_list('id', flat=True), recycle=True) if len(rounds.post) >= ImageModel.objects.filter( img__startswith=KEYRING).count(): # push all to waiting page return over(request, 'phase01a') # Single image that will be sent to front-end, will expire in 300 seconds (temporary) # sending 4 images at a time data = [i.img.url for i in ImageModel.objects.filter(id__in=roundsnum)] data.extend([None] * (3 - len(data))) # print("I got: ", serving_img_url) # Previous all question pairs that will be sent to front-end # Get all the instructions instructions = Phase01_instruction.get_queryset(Phase01_instruction) or [ 'none' ] #Get text instructions text_inst = TextInstruction.objects.get(phase='01a') # Get all of the questions previous_questions = list( Question.objects.filter(isFinal=True).values_list('text', flat=True)) return render( request, 'phase01a.html', { 'url': data, 'imgnum': roundsnum, 'questions': previous_questions, 'assignmentId': assignmentId, 'previewMode': previewMode, 'instructions': instructions, 'text_inst': text_inst, 'PRODUCTION': PRODUCTION, 'NUMROUNDS': NUMROUNDS[phase01a.__name__], 'object': OBJECT_NAME_PLURAL })