| 1 |
| import os |
| 2 |
| from pathlib import Path |
| 3 |
| from itertools import takewhile |
| 4 |
| |
| 5 |
| from flask import ( |
| 6 |
| Blueprint, |
| 7 |
| render_template, |
| 8 |
| request |
| 9 |
| ) |
| 10 |
| |
| 11 |
| from file import File |
| 12 |
| |
| 13 |
| |
| 14 |
| BASE_PATH = Path("/", "srv") |
| 15 |
| PROJECTS_PATH = BASE_PATH / "projects" |
| 16 |
| STATIC_PATH = BASE_PATH / "code_review" / "css" |
| 17 |
| |
| 18 |
| bp = Blueprint('routes', __name__, static_folder=STATIC_PATH) |
| 19 |
| |
| 20 |
| def register_routes(app: "Flask"): |
| 21 |
| app.register_blueprint(bp) |
| 22 |
| |
| 23 |
| |
| 24 |
| @bp.get('/') |
| 25 |
| def home(): |
| 26 |
| projects = os.listdir(path=PROJECTS_PATH.resolve()) |
| 27 |
| return render_template( |
| 28 |
| 'home.html', |
| 29 |
| projects=projects |
| 30 |
| ) |
| 31 |
| |
| 32 |
| |
| 33 |
| @bp.get('/file') |
| 34 |
| def display_file(): |
| 35 |
| path = request.args.get('file') |
| 36 |
| if not path: |
| 37 |
| raise ValueError('file not specified') |
| 38 |
| if ".." in path.split("/"): |
| 39 |
| raise ValueError('invalid path') |
| 40 |
| if path[0] == '/': |
| 41 |
| raise ValueError('invalid path') |
| 42 |
| |
| 43 |
| full_path = PROJECTS_PATH / path |
| 44 |
| path_segments = path.split("/") |
| 45 |
| if len(path_segments) < 2: |
| 46 |
| return_url = "/" |
| 47 |
| else: |
| 48 |
| return_path = "/".join(path_segments[:-1]) |
| 49 |
| return_url = f"/file?file={return_path}" |
| 50 |
| |
| 51 |
| if full_path.is_dir(): |
| 52 |
| return render_dir(path, return_url) |
| 53 |
| else: |
| 54 |
| return render_file(full_path, path, return_url) |
| 55 |
| |
| 56 |
| |
| 57 |
| def render_dir(dir: str, return_url: str): |
| 58 |
| path = PROJECTS_PATH / dir |
| 59 |
| files = [ |
| 60 |
| File(dir, file) for file in |
| 61 |
| os.listdir(path=path.resolve()) |
| 62 |
| ] |
| 63 |
| return render_template( |
| 64 |
| 'directory.html', |
| 65 |
| dir=dir, |
| 66 |
| files=files, |
| 67 |
| return_url=return_url |
| 68 |
| ) |
| 69 |
| |
| 70 |
| |
| 71 |
| def render_file(full_path: Path, local_path: str, return_url: str): |
| 72 |
| with open(full_path, 'r') as f: |
| 73 |
| g = ( |
| 74 |
| replace_tabs(line.rstrip()) |
| 75 |
| for line in f.readlines() |
| 76 |
| ) |
| 77 |
| |
| 78 |
| document = [ |
| 79 |
| (lineno + 1, f"| {line}") |
| 80 |
| for lineno, line in enumerate(g) |
| 81 |
| ] |
| 82 |
| |
| 83 |
| return render_template( |
| 84 |
| 'file.html', |
| 85 |
| document=document, |
| 86 |
| path=local_path, |
| 87 |
| return_url=return_url |
| 88 |
| ) |
| 89 |
| |
| 90 |
| |
| 91 |
| def replace_tabs(line: str): |
| 92 |
| count = len(list(takewhile(lambda x: x == '\t', line))) |
| 93 |
| return line.replace('\t', ' ', count) |
| 94 |
| |