def clear_annotations(request,rid,report=None): '''clear all annotations for a specific report and user''' if report == None: report = get_report(rid) # Right now, only owners allowed to contribute annotate_permission = has_collection_annotate_permission(request,report.collection) if annotate_permission: if request.method == 'POST': try: clear_user_annotations(request.user,report) response_data = {'result':'Annotations successfully cleared'} except: response_data = {'result':'Error clearing annotations.'} return JsonResponse(response_data) else: return JsonResponse({"have you ever seen...": "a radiologist rigatoni?"}) else: context = {"message":"You are not authorized to perform this action"} return render(request, "messages/not_authorized.html", context)
def delete_report(request,rid): report = get_report(rid) collection = report.collection if request.user == collection.owner: report.delete() else: messages.warning(request, "You are not authorized to perform this operation.") return HttpResponseRedirect(collection.get_absolute_url())
def view_report(request,rid): report = get_report(rid) #TODO: In the future if we ever want to allow counting across collection, this needs to change annotation_counts = get_annotation_counts(report.collection,reports=[report]) context = {"report":report, "annotation_counts":annotation_counts, "collection":report.collection} # Get all permissions, context must have collection as key context = get_permissions(request,context) return render(request, 'reports/report_details.html', context)
def annotate_report_testing(request,rid,sid=None,report=None,next=None,allowed_annotations=None): '''annotate_report_testing is the view to return a report annotation interface to test an id :param sid: a report set id, if coming from annotate_random with a report set :param report_set: a report set. :param next: the next page to show (annotate/reports/{{ collection.id }}/{{ next }} :param allowed_annotations: a custom set of allowed annotations to use. If not provided, the entire set of a collection is used. ''' if report == None: report = get_report(rid) collection = report.collection context = {"collection":collection, "report":report} if sid != None: next = "%s/set" %(sid) context['sid'] = sid # If next is None, return random elif next == None: next = "%s/random" %(collection.id) # If it's not None, we still need to add collection id else: next = "%s/%s" %(collection.id,next) # Next url will direct to either set, or random context['next'] = next # Get the concise annotations annotations = get_annotations(user=request.user, report=report) annotations = summarize_annotations(annotations) if "labels" in annotations: context["annotations"] = annotations['labels'] if "counts" in annotations: context["counts"] = annotations['counts'] # Get the allowed_annotations, and organize them into a lookup dictionary with key:options if allowed_annotations == None: allowed_annotations = report.collection.allowed_annotations.all() context["allowed_annotations"] = group_allowed_annotations(allowed_annotations) # Format markup context["markup"] = ["%s" %(x) for x in report.collection.markup.split(",")] # Get all permissions, context must have collection as key context = get_permissions(request,context) return render(request, "annotate/testing_random.html", context)
def update_annotation(request,rid,report=None): '''update_annotation is the view to update an annotation when it changes. It should return a JSON response. ''' if report == None: report = get_report(rid) # Does the user have permission to annotate the collection? annotate_permission = has_collection_annotate_permission(request,report.collection) if annotate_permission: if request.method == 'POST': try: new_annotations = json.loads(request.POST.get('annotations')) except: return JsonResponse({"error": "error parsing array!"}) # Update the annotations for new_annotation in new_annotations: if new_annotation['value'] == "on": aname,alabel = new_annotation['name'].split('||') annotation_object = AllowedAnnotation.objects.get(name=aname, label=alabel) annot = update_user_annotation(user=request.user, allowed_annotation=annotation_object, report=report) response_data = {'result':'Create post successful!'} return JsonResponse(response_data) else: return JsonResponse({"have you ever seen...": "a radiologist ravioli?"}) else: context = {"message":"You are not authorized to annotate this collection."} return render(request, "messages/not_authorized.html", context)
def get_object(self, report_id): report = get_report(report_id) if report != None: return report else: return Http404
def test_annotator(request, sid, rid=None): '''test_annotator will ask an annotator to answer the specified number of questions to be granted access to annotate a collection. The data is stored in a session, and the session expires (and is reset) when the user has viewed the total number of required questions :param sid: the id of the report set :param rid: the report id that was tested ''' from whatisit.apps.wordfish.views import (annotate_report_testing, annotate_set, get_permissions, view_report_collection) from whatisit.apps.users.models import Credential if rid != None: # scoring is needed completed_report = get_report(rid) user = request.user report_set = get_report_set(sid) context = {'collection': report_set.collection} permissions = get_permissions(request, context) # Double check that user has permission to annotate if permissions["annotate_permission"] == True: # Also check that user hasn't previously failed. credential = Credential.objects.get(user=user, report_set=report_set) # Double check user status user_status = get_annotation_status(report_set=report_set, user=user) # Only continue if user_status is TESTING if user_status == "TESTING": # Get session variable session = get_testing_session(user=user, report_set=report_set) session_key = 'reports_testing_%s' % (session.id) # testing set is stored in request.session with corresponding id testing_set = request.session.get(session_key, None) testing_report = None testing_correct = session.correct testing_incorrect = session.incorrect # Total reports required for taking, and for passing N = report_set.number_tests N_pass = report_set.passing_tests ########################################################### # NEW TESTING SESSION ########################################################### if testing_set == None: messages.info( request, '''This is the start of the test. You will be asked to annotate %s reports. You should click on the correct label below, and then you can use your right arrow key (or the arrow at the bottom) to submit your answer. ''' % (N)) # Randomly select N reports from the set testing_reports = select_random_reports( reports=report_set.reports.all(), N=N) testing_reports = list(testing_reports) # Remove the first for testing testing_report = testing_reports.pop(0) request.session[session_key] = testing_reports ########################################################### # RESUME TESTING SESSION ########################################################### else: # If the testing set session is not empty, get any updated answers if request.method == "POST": # Get the correct annotations from the database correct_annotations = get_annotations( user=report_set.gold_standard, report=completed_report) answers = summarize_annotations( correct_annotations)['labels'] post_keys = list(request.POST.keys()) for post_key in post_keys: # The annotation labels have a '||' if re.search('[||]', post_key): new_annotation = request.POST[post_key] user_selected = False if new_annotation == "on": selected_name, selected_label = post_key.split( '||') user_selected = True # If we have an answer option_chosen = '' if selected_name in answers: correct_answer = answers[selected_name] # The user selected the right answer if user_selected and correct_answer == selected_label: testing_correct += 1 # The user selected, but not right answer elif user_selected and correct_answer != selected_label: testing_incorrect += 1 # The user didn't select, is right answer elif not user_selected and correct_answer == selected_label: testing_incorrect += 1 # The user didn't select, is not right answer elif not user_selected and correct_answer != selected_label: continue # If the total number tests (correct and incorrect) if len(testing_set) == 0: # Did the user pass? if testing_correct >= N_pass: user_status = credential.status = "PASSED" else: user_status = credential.status = "DENIED" credential.save() # Update the counts session.correct = testing_correct session.incorrect = testing_incorrect session.save() # If user status is (still) TESTING, start or continue if user_status == "TESTING": # If we didn't select a testing report if testing_report == None: testing_report = testing_set.pop(0) request.session[session_key] = testing_set # Update the user with remaining reports remaining_tests = N - (testing_correct + testing_incorrect) messages.info( request, 'You have %s reports remaining in this session' % (remaining_tests)) # Get allowed annotations for set testing_annotations = get_testing_annotations(report_set) # Start testing the user return annotate_report_testing( request=request, rid=testing_report.id, sid=report_set.id, report=testing_report, allowed_annotations=testing_annotations) # If the user status was approved, either previously or aboved, move on to annotation elif user_status == "PASSED": messages.info( request, "Congratulations, you have passed the testing! You are now annotating the collection set." ) request = delete_testing_session( request, session) # deletes session, sets reports to None # Add the user to the set if request.user not in report_set.annotators.all(): report_set.annotators.add(request.user) report_set.save() return annotate_set(request, report_set.id) elif user_status == "DENIED": messages.info(request, "You are not qualified to annotate this set.") session = get_testing_session(user=user, report_set=report_set) request = delete_testing_session( request, session) # deletes session, sets reports to None return view_report_collection(request, report_set.collection.id) # User does not have permission to annotate, return to collection view else: messages.info( request, "You do not have permissions to perform this operation.") # Denied, or not annotate permission returns to see collection return view_report_collection(request, report_set.collection.id)
def annotate_report(request,rid,sid=None,report=None,next=None,template=None, allowed_annotations=None,show_count=True): '''annotate_report is the view to return a report annotation interface for a particular report id :param rid: report id to annotate :param sid: a report set id, if coming from annotate_random with a report set :param report_set: a report set. :param show_count: if true, will show the user the total reports annotated :param next: the next page to show (annotate/reports/{{ collection.id }}/{{ next }} :param template: an optional template, if not provided, default is used :param allowed_annotations: a custom set of allowed annotations to use. If not provided, the entire set of a collection is used. ''' if report == None: report = get_report(rid) collection = report.collection if template == None: template = "annotate/annotate_random.html" context = {"collection":collection, "report":report} if sid != None: next = "%s/set" %(sid) context['sid'] = sid # If next is None, return random elif next == None: next = "%s/random" %(collection.id) # If it's not None, we still need to add collection id else: next = "%s/%s" %(collection.id,next) # Tell the user how many annotated / remaining if show_count == True: remaining_message = count_remaining_reports(user=request.user, collection=collection, sid=sid, return_message=True) messages.info(request,remaining_message) # Next url will direct to either set, or random context['next'] = next # Get the concise annotations annotations = get_annotations(user=request.user, report=report) annotations = summarize_annotations(annotations) if "labels" in annotations: context["annotations"] = annotations['labels'] if "counts" in annotations: context["counts"] = annotations['counts'] # Get the allowed_annotations, and organize them into a lookup dictionary with key:options if allowed_annotations == None: allowed_annotations = report.collection.allowed_annotations.all() context["allowed_annotations"] = group_allowed_annotations(allowed_annotations) # Format markup context["markup"] = ["%s" %(x) for x in report.collection.markup.split(",")] # Get all permissions, context must have collection as key context = get_permissions(request,context) return render(request, template, context)