def save(self, *args, **kwargs): super(GraderLib, self).save(*args, **kwargs) name = self.lib_upload.name.split("/")[-1] f = self.lib_upload.read() for ps in ProblemSet.objects.all(): for problem in ps.problems.all().filter(autograde_problem=True): tango.upload(problem, ps, name, f)
def save(self, *args, **kwargs): super(GraderLib, self).save(*args, **kwargs) name = self.lib_upload.name.split("/")[-1] f = self.lib_upload.read() #(re)upload this library to all the problems in this course #to do: this should be a celery task for problem in Problem.objects.filter(cs_course=self.cs_course, autograde_problem=True): for ps in problem.assigned_to(): tango.upload(problem, ps, name, f)
def _open_and_upload(self, obj): """ Helper function that gets called for response change and response add It opens a new courselab and then uploads the grading files """ for problem in obj.problems.all().filter(autograde_problem=True): # open (make) the courselab on tango server with the callback _upload_ps_files tango.open(problem, obj) # upload the grader librarires for lib in models.GraderLib.objects.all(): f = lib.lib_upload tango.upload(problem, obj, f.name.split("/")[-1], f.read()) # upload the grading script grading = problem.grade_script grading_name = grading.name.split("/")[-1] tango.upload(problem, obj, grading_name, grading.read()) # upload the makefile that will run the grading script makefile = "autograde:\n @python3 " + grading_name tango.upload(problem, obj, vrfy.settings.MAKEFILE_NAME, makefile) # upload all the other files for psfile in models.ProblemSolutionFile.objects.filter(problem=problem): f = psfile.file_upload tango.upload(problem, obj, f.name.split("/")[-1], f.read())
def _open_and_upload(self, obj): """ Helper function that gets called for response change and response add It opens a new courselab and then uploads the grading files """ for problem in obj.problems.all().filter(autograde_problem=True): # open (make) the courselab on tango server with the callback # _upload_ps_files tango.open(problem, obj) # upload the grader librarires for lib in models.GraderLib.objects.all(): f = lib.lib_upload tango.upload(problem, obj, f.name.split("/")[-1], f.read()) # upload the grading script grading = problem.grade_script grading_name = grading.name.split("/")[-1] tango.upload(problem, obj, grading_name, grading.read()) # upload the makefile that will run the grading script makefile = 'autograde:\n @python3 ' + grading_name tango.upload(problem, obj, vrfy.settings.MAKEFILE_NAME, makefile) # upload all the other files for psfile in models.ProblemSolutionFile.objects.filter( problem=problem): f = psfile.file_upload tango.upload(problem, obj, f.name.split("/")[-1], f.read())
def response_change(self, request, obj): """ Upload files to Tango I only need to do this when a problem is changed, because when a problem is added, it doesn't have a problem set yet. """ if obj.autograde_problem: for ps in obj.problemset_set.all(): # upload the grading script grading = obj.grade_script grading_name = grading.name.split("/")[-1] tango.upload(obj, ps, grading_name, grading.read()) grading.seek(0) # upload the makefile that will run the grading script makefile = 'autograde:\n @python3 ' + grading_name tango.upload(obj, ps, vrfy.settings.MAKEFILE_NAME, makefile) # upload problemsolutionfiles for psfile in models.ProblemSolutionFile.objects.filter( problem=obj): f = psfile.file_upload tango.upload(obj, ps, f.name.split("/")[-1], f.read()) return super(ProblemAdmin, self).response_change(request, obj)
def send_file_to_tango(self, ps_id, p_id, reedie_id, localfile, file_data): ''' given the pk for a :model:`course.StudentProblemSolution`, figure out if it needs to get sent to tango ''' #try to get the problem, the reedie, and the problem set reedie = Reedie.objects.get(pk=reedie_id) ps = ProblemSet.objects.get(pk=ps_id, pub_date__lte=timezone.now(), cs_section__in=reedie.enrolled.all()) problem = Problem.objects.get(pk=p_id) r = tango.upload(problem, ps, localfile, file_data) if r.status_code is not 200: message="Failed to upload file" self.retry(message=message, countdown=1) return r
def send_file_to_tango(self, ps_id, p_id, reedie_id, localfile, file_data): ''' given the pk for a :model:`course.StudentProblemSolution`, figure out if it needs to get sent to tango ''' #try to get the problem, the reedie, and the problem set reedie = Reedie.objects.get(pk=reedie_id) ps = ProblemSet.objects.get(pk=ps_id, pub_date__lte=timezone.now(), cs_section__in=reedie.enrolled.all()) problem = Problem.objects.get(pk=p_id) r = tango.upload(problem, ps, localfile, file_data) if r.status_code is not 200: message = "Failed to upload file" self.retry(message=message, countdown=1) return r
def problem_submit(request, ps_id, p_id): if request.method == 'POST':#make sure the user doesn't type this into the address bar ps = _get_problem_set(ps_id, request.user.reedie) problem = get_object_or_404(Problem, pk=p_id) #create / get the student problem set and update the submission time (reflects latest attempt) student_ps_sol, sp_set_created = StudentProblemSet.objects.get_or_create(problem_set=ps, user=request.user.reedie, defaults={'submitted': timezone.now()}) student_ps_sol.save() student_psol, sp_sol_created = StudentProblemSolution.objects.get_or_create(problem=problem, student_problem_set=student_ps_sol) student_psol.submitted = timezone.now() student_psol.attempt_num += 1 student_psol.save() #create the student result set & problem # result_set, prs_created = ProblemResultSet.objects.get_or_create(sp_set = student_ps_sol, user=request.user, problem_set=ps) mytimestamp = None if not problem.autograde_problem: #if its not being autograded, we should set the timestamp here; if it is, tango will set it mytimestamp = timezone.now() prob_result = ProblemResult.objects.create(attempt_num=student_psol.attempt_num, sp_sol=student_psol, sp_set=student_ps_sol, user=request.user.reedie, problem=problem, timestamp=mytimestamp) additional_files = 0 files = []#for the addJob #getting all the submitted files for name, f in request.FILES.items(): print(name, ADDITIONAL_FILE_NAME) if ADDITIONAL_FILE_NAME in name: required_pf = None print(additional_files) if additional_files < MAX_ADDITIONAL_FILES: additional_files += 1 else: return render(request, '403.html', {'exception': "You can't upload more than " + str(MAX_ADDITIONAL_FILES) + " additional files."}, status=403) #raise PermissionDenied() else: required_pf = RequiredProblemFilename.objects.get(problem=problem, file_title=name) if required_pf == None or not required_pf.force_rename: name = f.name#if the file should not be renamed, give it the name as it was uploaded #we also need to check if it has the same name as any of the grader files for gfile in chain(problem.problemsolutionfile_set.all(), GraderLib.objects.all(),[problem.grade_script.name.split("/")[-1]]): if name == str(gfile): return render(request, '403.html', {'exception': name + " is an invalid filename."}, status=403) #raise PermissionDenied(name + " is an invalid filename.") localfile = name + "-"+ request.user.username if problem.autograde_problem: r = tango.upload(problem, ps, localfile, f.read()) files.append({"localFile" : localfile, "destFile":name})#for the addJob command attempts = student_psol.attempt_num new_prob_file = StudentProblemFile.objects.create(required_problem_filename=required_pf, student_problem_solution = student_psol, submitted_file=f, attempt_num = attempts) new_prob_file.save() if problem.autograde_problem:#these operatons are only required for autograding #add grader libraries for lib in GraderLib.objects.all(): name = lib.lib_upload.name.split("/")[-1] files.append({"localFile" : name, "destFile": name}) #getting all the grader files grading = problem.grade_script name = grading.name.split("/")[-1] files.append({"localFile" : name, "destFile": name}) for psfile in ProblemSolutionFile.objects.filter(problem=problem): name = psfile.file_upload.name.split("/")[-1] files.append({"localFile" : name, "destFile": name}) #upload the json data object tango_data = json.dumps({"attempts": student_psol.attempt_num, "timedelta": student_psol.is_late()}) data_name = "data.json" + "-" + request.user.username tango.upload(problem, ps, data_name, tango_data) files.append({"localFile" : data_name, "destFile": "data.json"}) #making Tango run the files jobName = tango.get_jobName(problem, ps, request.user.username) r = tango.addJob(problem, ps, files, jobName, jobName) if r.status_code is not 200: return redirect('500.html') else: response = r.json() student_psol.job_id = response["jobId"] prob_result.job_id = response["jobId"] student_psol.save() prob_result.save() return redirect('course:submit_success', ps_id, p_id) else: raise Http404("Don't do that")