def view(solution_id): solution = Solution.get_or_none(Solution.id == solution_id) if solution is None: return fail(404, 'Solution does not exist.') is_manager = current_user.role.is_manager if solution.solver.id != current_user.id and not is_manager: return fail(403, 'This user has no permissions to view this page.') versions = solution.ordered_versions() view_params = { 'solution': model_to_dict(solution), 'is_manager': is_manager, 'role': current_user.role.name.lower(), 'versions': versions, } if is_manager: view_params = { **view_params, 'exercise_common_comments': _common_comments(exercise_id=solution.exercise), 'all_common_comments': _common_comments(), 'user_comments': _common_comments(user_id=current_user.id), } return render_template('view.html', **view_params)
def view( solution_id: int, file_id: Optional[int] = None, shared_url: str = '', ): solution = Solution.get_or_none(Solution.id == solution_id) if solution is None: return fail(404, 'Solution does not exist.') viewer_is_solver = solution.solver.id == current_user.id has_viewer_access = current_user.role.is_viewer if not shared_url and not viewer_is_solver and not has_viewer_access: return fail(403, 'This user has no permissions to view this page.') is_manager = current_user.role.is_manager solution_files = tuple(solution.files) if not solution_files: if not is_manager: return fail(404, 'There are no files in this solution.') return done_checking(solution.exercise.id, solution.id) try: view_params = solutions.get_view_parameters( solution, file_id, shared_url, is_manager, solution_files, viewer_is_solver, ) except LmsError as e: error_message, status_code = e.args return fail(status_code, error_message) return render_template('view.html', **view_params)
def download(download_id: str): """Downloading a zip file of the code files. Args: download_id (str): Can be on each side of a solution.id and sharedsolution.shared_url. """ solution = Solution.get_or_none(Solution.id == download_id) shared_solution = SharedSolution.get_or_none( SharedSolution.shared_url == download_id, ) if solution is None and shared_solution is None: return fail(404, 'Solution does not exist.') if shared_solution is None: viewer_is_solver = solution.solver.id == current_user.id has_viewer_access = current_user.role.is_viewer if not viewer_is_solver and not has_viewer_access: return fail(403, 'This user has no permissions to view this page.') files = solution.files filename = solution.exercise.subject else: files = shared_solution.solution.files filename = shared_solution.solution.exercise.subject response = make_response(solutions.create_zip_from_solution(files)) response.headers.set('Content-Type', 'zip') response.headers.set( 'Content-Disposition', 'attachment', filename=f'{filename}.zip', ) return response
def view( solution_id: int, file_id: Optional[int] = None, shared_url: str = '', ): solution = Solution.get_or_none(Solution.id == solution_id) if solution is None: return fail(404, 'Solution does not exist.') viewer_is_solver = solution.solver.id == current_user.id has_viewer_access = current_user.role.is_viewer if not shared_url and not viewer_is_solver and not has_viewer_access: return fail(403, 'This user has no permissions to view this page.') versions = solution.ordered_versions() test_results = solution.test_results() is_manager = current_user.role.is_manager solution_files = tuple(solution.files) if not solution_files: if not is_manager: return fail(404, 'There are no files in this solution.') return done_checking(solution.exercise.id, solution.id) files = solutions.get_files_tree(solution.files) file_id = file_id or files[0]['id'] file_to_show = next((f for f in solution_files if f.id == file_id), None) if file_to_show is None: return fail(404, 'File does not exist.') view_params = { 'solution': model_to_dict(solution), 'files': files, 'comments': solution.comments_per_file, 'current_file': file_to_show, 'is_manager': is_manager, 'role': current_user.role.name.lower(), 'versions': versions, 'test_results': test_results, 'shared_url': shared_url, } if is_manager: view_params = { **view_params, 'exercise_common_comments': _common_comments(exercise_id=solution.exercise), 'all_common_comments': _common_comments(), 'user_comments': _common_comments(user_id=current_user.id), 'left': Solution.left_in_exercise(solution.exercise), } if viewer_is_solver: notifications.read_related(solution_id, current_user.id) return render_template('view.html', **view_params)
def comment(): act = request.args.get('act') or request.json.get('act') if request.method == 'POST': solution_id = int(request.json.get('solutionId', 0)) else: # it's a GET solution_id = int(request.args.get('solutionId', 0)) solution = Solution.get_or_none(Solution.id == solution_id) if solution is None: return fail(404, f'No such solution {solution_id}') solver_id = solution.solver.id if solver_id != current_user.id and not current_user.role.is_manager: return fail(401, "You aren't allowed to watch this page.") if act == 'fetch': return jsonify(Comment.get_solutions(solution_id)) if act == 'delete': comment_id = int(request.args.get('commentId')) comment_ = Comment.get_or_none(Comment.id == comment_id) if comment_ is not None: comment_.delete_instance() return jsonify({'success': 'true'}) if act == 'create': kind = request.json.get('kind', '') comment_id, comment_text = None, None try: line_number = int(request.json.get('line', 0)) except ValueError: line_number = 0 if kind.lower() == 'id': comment_id = int(request.json.get('comment', 0)) if kind.lower() == 'text': comment_text = request.json.get('comment', '') return _create_comment( current_user.id, solution, kind, line_number, comment_text, comment_id, ) return fail(400, f'Unknown or unset act value "{act}"')
def download(solution_id: int, file_id: Optional[int] = None): solution = Solution.get_or_none(solution_id) if solution is None: return fail(404, 'Solution does not exist.') viewer_is_solver = solution.solver.id == current_user.id has_viewer_access = current_user.role.is_viewer if not viewer_is_solver and not has_viewer_access: return fail(403, 'This user has no permissions to view this page.') response = make_response( solutions.create_zip_from_solution(solution.files), ) response.headers.set('Content Type', 'zip') response.headers.set( 'Content-Disposition', 'attachment', filename=f'{solution.exercise.subject}.zip', ) return response
def get(solution_id: int) -> SharedSolution: if not webapp.config.get('SHAREABLE_SOLUTIONS', False): raise LmsError('Shareable solutions are not allowed.', 403) solution = Solution.get_or_none(solution_id) if solution is None: raise LmsError(f'No such solution {solution_id}', 404) solver_id = solution.solver.id if solver_id != current_user.id and not current_user.role.is_manager: raise LmsError("You aren't allowed to access this page.", 403) shared_solution = SharedSolution.get_or_none( SharedSolution.solution == solution, ) if shared_solution is None: shared_solution = SharedSolution.create_new(solution=solution) return shared_solution
def get_download_data( download_id: str, ) -> Tuple[Iterator[SolutionFile], str]: solution = Solution.get_or_none(Solution.id == download_id) shared_solution = SharedSolution.get_or_none( SharedSolution.shared_url == download_id, ) if solution is None and shared_solution is None: raise ResourceNotFound('Solution does not exist.', 404) if shared_solution is None: viewer_is_solver = solution.solver.id == current_user.id has_viewer_access = current_user.role.is_viewer if not viewer_is_solver and not has_viewer_access: raise ForbiddenPermission( 'This user has no permissions to view this page.', 403, ) files = solution.files filename = solution.exercise.subject else: files = shared_solution.solution.files filename = shared_solution.solution.exercise.subject return files, filename