def get_next_task_view(self): self.client.login(username="******", password="******") ## get the next task self.task_expectation.check(self) ## tweak the database to put a response and a review in response = Response(task=self.t, user=self.user, start_time=timezone.now()) response.full_clean() response.save() review = Review(response=response, comment="I have reviewed this task.") review.full_clean() review.save() ## check to see if next_task now redirects to review ## if we actually execute the view code, we will get an error, ## because the task associated with the review has no result; ## therefore the code below is a bit hackish review_target = WebTarget("GET", main.views.base.next_task, statuses=(301, 302)) def redirects_to_review(input_context, output_context): return "/review/next/" in output_context["__redirected_to__"] review_expectation = ViewExpectation( Conditions.post(redirects_to_review), review_target) review_expectation.check(self) ## tweak the database to complete the review review.complete = True review.full_clean() review.save() ## try getting the next task again self.task_expectation.check(self)
def get_next_task_view(self): self.client.login(username="******", password="******") ## get the next task self.task_expectation.check(self) ## tweak the database to put a response and a review in response = Response(task=self.t, user=self.user, start_time=datetime.datetime.now()) response.full_clean() response.save() review = Review(response=response, comment="I have reviewed this task.") review.full_clean() review.save() ## check to see if next_task now redirects to review ## if we actually execute the view code, we will get an error, ## because the task associated with the review has no result; ## therefore the code below is a bit hackish review_target = WebTarget("GET", main.views.base.next_task, statuses=(301, 302)) def redirects_to_review(input_context, output_context): return "/review/next/" in output_context["__redirected_to__"] review_expectation = ViewExpectation(Conditions.post(redirects_to_review), review_target) review_expectation.check(self) ## tweak the database to complete the review review.complete = True review.full_clean() review.save() ## try getting the next task again self.task_expectation.check(self)
def task_view(get, guts, task_id): """View a given task ID or submit a response to it; in either case, this should dispatch appropriately based on the task's type.""" import main.views.base task = Task.objects.get(pk=task_id) project_type = type_list[task.project.type] task = project_type.cast(task) try: wip = WorkInProgress.objects.get(task=task, user=guts.user) except WorkInProgress.DoesNotExist: if task.project.auto_review: try: ## Tasks in auto-review projects have a kludgey workflow: ## the task is responsible for noticing that it is in an ## auto-review project and adjusting the output of template() ## and template_data accordingly. ## When GETting the page, if a Response object already exists, then ## the output should be appropriate for displaying a review. auto_review = AutoReview.objects.get(task=task, user=guts.user) if get: ## If the Task subclass has not been retrofitted to handle ## auto-review projects, then this line will throw an exception ## "TypeError: ... unexpected keyword argument 'auto_review_user'" return TemplateResponse( task.template(), task.template_data(auto_review_user=guts.user)) else: ## NOTE: does the downcasting of task screw this query up? response_query = Response.objects.filter(user=guts.user, task=task) if not response_query.exists(): ## No response? Ask the task to make one! kwargs = { "user": guts.user, "task": task, "start_time": auto_review.start_time, } task.handle_response(guts, **kwargs) ## (Note that this code path does NOT update the task's ## completed_assignments field, because auto-review projects ## do not have a limit on how many responses they can have.) ## ## And then GET this page again, so the user can see the review. return ViewResponse('main:view-task', task_id) else: ## The user must have clicked the "I read this review" button. auto_review.end_time = timezone.now() auto_review.full_clean() auto_review.save() return ViewResponse('main:next-task') except AutoReview.DoesNotExist: ## fall through to the case below, since an admin is allowed to ## look at someone else's auto-review pass ## an admin can look at any task, but not even an admin ## can submit a response or result to a task without getting a WIP first if not (task.viewable_by(guts.user) and get): return ForbiddenResponse("You are not allowed to view %s." % six.text_type(task)) if get: return TemplateResponse(task.template(), task.template_data()) else: ## TODO: if we successfully make handle_response a method of the task, ## then we don't have to pass the task in kwargs kwargs = { "user": guts.user, "task": task, "start_time": wip.start_time } try: task.handle_response(guts, **kwargs) if task.completed: if 'review_user' in guts.parameters: users = guts.parameters.getlist('review_user') for user in users: user_obj = User.objects.get(pk=user) comment = guts.parameters.get("comment_%s" % user, "") rev = Review( response=task.response_set.get(user=user_obj), comment=comment, ) rev.full_clean() rev.save() else: task.completed_assignments = task.completed_assignments + 1 task.full_clean() task.save() wip.delete() if 'stop_working' in guts.parameters: return ViewResponse('main:home') else: return ViewResponse('main:next-task') except MultiValueDictKeyError: ## translate the MultiValueDict into a list of (key, list) pairs params = guts.parameters.lists() exc_type, exc_value, exc_traceback = sys.exc_info() tb_info = traceback.extract_tb(exc_traceback) template = get_template("parameter-error-in-task.html") context = { "task": str(task), "params": params, "exc_value": exc_value, "traceback": tb_info, } guts.log_error("Bad form? " + repr(context)) return TemplateResponse(template, context, status=500)
def task_view(get, guts, task_id): """View a given task ID or submit a response to it; in either case, this should dispatch appropriately based on the task's type.""" import main.views.base task = Task.objects.get(pk=task_id) project_type = type_list[task.project.type] task = project_type.cast(task) try: wip = WorkInProgress.objects.get(task=task, user=guts.user) except WorkInProgress.DoesNotExist: if task.project.auto_review: try: ## Tasks in auto-review projects have a kludgey workflow: ## the task is responsible for noticing that it is in an ## auto-review project and adjusting the output of template() ## and template_data accordingly. ## When GETting the page, if a Response object already exists, then ## the output should be appropriate for displaying a review. auto_review = AutoReview.objects.get(task=task, user=guts.user) if get: ## If the Task subclass has not been retrofitted to handle ## auto-review projects, then this line will throw an exception ## "TypeError: ... unexpected keyword argument 'auto_review_user'" return TemplateResponse(task.template(), task.template_data(auto_review_user=guts.user)) else: ## NOTE: does the downcasting of task screw this query up? response_query = Response.objects.filter(user=guts.user, task=task) if not response_query.exists(): ## No response? Ask the task to make one! kwargs = {"user": guts.user, "task": task, "start_time": auto_review.start_time} task.handle_response(guts, **kwargs) ## (Note that this code path does NOT update the task's ## completed_assignments field, because auto-review projects ## do not have a limit on how many responses they can have.) ## ## And then GET this page again, so the user can see the review. return ViewResponse(task_view, task_id) else: ## The user must have clicked the "I read this review" button. auto_review.end_time = datetime.datetime.now() auto_review.full_clean() auto_review.save() return ViewResponse(main.views.base.next_task) except AutoReview.DoesNotExist: ## fall through to the case below, since an admin is allowed to ## look at someone else's auto-review pass ## an admin can look at any task, but not even an admin ## can submit a response or result to a task without getting a WIP first if not (task.viewable_by(guts.user) and get): return ForbiddenResponse(u"You are not allowed to view %s" % unicode(task)) if get: return TemplateResponse(task.template(), task.template_data()) else: ## TODO: if we successfully make handle_response a method of the task, ## then we don't have to pass the task in kwargs kwargs = {"user": guts.user, "task": task, "start_time": wip.start_time} try: task.handle_response(guts, **kwargs) if task.completed: if 'review_user' in guts.parameters: users = guts.parameters.getlist('review_user') for user in users: user_obj = User.objects.get(pk=user) comment = guts.parameters.get("comment_%s" % user, "") rev = Review(response=task.response_set.get(user=user_obj), comment=comment) rev.full_clean() rev.save() else: task.completed_assignments = task.completed_assignments + 1 task.full_clean() task.save() wip.delete() if 'stop_working' in guts.parameters: return ViewResponse(main.views.base.home) else: return ViewResponse(main.views.base.next_task) except MultiValueDictKeyError: ## translate the MultiValueDict into a list of (key, list) pairs params = guts.parameters.lists() exc_type, exc_value, exc_traceback = sys.exc_info() tb_info = traceback.extract_tb(exc_traceback) template = get_template("parameter-error-in-task.html") context = {"task": str(task), "params": params, "exc_value": exc_value, "traceback": tb_info} guts.log_error("Bad form? " + repr(context)) return TemplateResponse(template, context, status=500)