def _upload_to_db( exercise_number: int, course_id: int, user_id: int, files: List[File], solution_hash: Optional[str] = None, ) -> Solution: exercise = Exercise.get_or_none(course=course_id, number=exercise_number) user = User.get_by_id(user_id) if exercise is None: raise UploadError(f'No such exercise id: {exercise_number}') elif not user.has_course(course_id): raise UploadError( f'Exercise {exercise_number} is invalid for this user.', ) elif not exercise.open_for_new_solutions(): raise UploadError( f'Exercise {exercise_number} is closed for new solutions.') if solution_hash and _is_uploaded_before(user, exercise, solution_hash): raise AlreadyExists('You try to reupload an old solution.') elif not files: raise UploadError( f'There are no files to upload for {exercise_number}.', ) return Solution.create_solution( exercise=exercise, solver=user, files=files, hash_=solution_hash, )
def test_new_solution_override_old_solutions( self, exercise: Exercise, student_user: User, ): first_solution = Solution.create_solution(exercise, student_user) second_solution = Solution.create_solution(exercise, student_user) assert second_solution.state == self.created_state assert first_solution.refresh().state == self.old_solution_state assert Solution.next_unchecked().id == second_solution.id next_unchecked = Solution.next_unchecked_of(exercise.id) assert next_unchecked.id == second_solution.id assert next_unchecked.start_checking() assert next_unchecked.refresh().state == self.in_checking_state assert Solution.next_unchecked() is None assert Solution.next_unchecked_of(exercise.id) is None general_tasks.reset_solution_state_if_needed(second_solution.id) assert Solution.next_unchecked().id == second_solution.id assert Solution.next_unchecked_of(exercise.id).id == second_solution.id
def create_solution( exercise: Exercise, student_user: User, code: Optional[str] = None, ) -> Solution: if code is None: code = ''.join(random.choices(string.printable, k=100)) return Solution.create_solution( exercise=exercise, solver=student_user, files=[File('exercise.py', code)], )
def upload(): user_id = current_user.id user = User.get_or_none(User.id == user_id) # should never happen if user is None: return fail(404, 'user not found') if request.content_length > MAX_REQUEST_SIZE: return fail(413, 'File is too heavy. 500KB allowed') file: FileStorage = request.files.get('file') if not file: return fail(422, 'No file was given') json_file_data = file.read() try: file_content = json.loads(json_file_data) exercises = list(extract_exercises(file_content)) except (ValueError, json.JSONDecodeError): return fail(422, 'Invalid file format - must be ipynb') if not exercises: msg = 'No exercises were found in the notebook' desc = 'did you use Upload <number of exercise> ? (example: Upload 1)' return fail(422, f'{msg}, {desc}') matches, misses = set(), set() for exercise_id, code in exercises: exercise = Exercise.get_or_none(Exercise.id == exercise_id) if exercise is None: misses.add(exercise_id) continue if not exercise.open_for_new_solutions(): misses.add(exercise_id) continue if Solution.solution_exists( exercise=exercise, solver=user, json_data_str=code, ): continue solution = Solution.create_solution( exercise=exercise, solver=user, json_data_str=code, ) flake8_tasks.run_flake8_on_solution.apply_async(args=(solution.id, )) identical_tests_tasks.solve_solution_with_identical_code.apply_async( args=(solution.id, )) matches.add(exercise_id) return jsonify({ 'exercise_matches': list(matches), 'exercise_misses': list(misses), })
def _upload_to_db( exercise_id: int, user: User, files: List[File], solution_hash: Optional[str] = None, ) -> Solution: exercise = Exercise.get_or_none(exercise_id) if exercise is None: raise UploadError(f'No such exercise id: {exercise_id}') elif not exercise.open_for_new_solutions(): raise UploadError( f'Exercise {exercise_id} is closed for new solutions.') elif not files: raise UploadError(f'There are no files to upload for {exercise_id}.') return Solution.create_solution( exercise=exercise, solver=user, files=files, hash_=solution_hash, )
def solution(exercise, student_user): return Solution.create_solution( exercise=exercise, solver=student_user, )