code_review/routes.py

go back
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 |