-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.py
More file actions
179 lines (141 loc) · 6.9 KB
/
app.py
File metadata and controls
179 lines (141 loc) · 6.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
import os
import Tools
from flask import jsonify, Flask, request # type: ignore
from flask_cors import CORS # type: ignore
from werkzeug.utils import secure_filename # type: ignore
from Tools import *
app = Flask(__name__)
CORS(app)
BASE_DIR = os.path.abspath("./content")
UPLOAD_FOLDER = './content/' # Define the folder where uploaded files will go
ALLOWED_EXTENSIONS = {'docx', 'doc', 'xls', 'xlsx', 'pdf', 'md'} # Allowed file types
# Ensure the upload folder exists
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
# Function to check allowed file types
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
@app.route("/upload/<gradeLetter>/<gradeNumber>", methods=["POST"])
def handleUploadFile(gradeLetter: str, gradeNumber: str):
"""
Handles file upload, converts it to Markdown, and moves the file
to the appropriate grade-specific folder.
"""
# Define grade path (e.g., "9/B")
grade = f"{gradeLetter}/{gradeNumber}"
# Check if the request contains a file part
if 'file' not in request.files:
return jsonify({"error": "No file part in the request"}), 400
file = request.files['file']
# Check if a file was selected
if file.filename == '':
return jsonify({"error": "No file selected"}), 400
# Validate the file type
if file and allowed_file(file.filename):
# Sanitize filename
filename = secure_filename(file.filename)
# Define the temporary folder and file path
temp_folder = os.path.join(UPLOAD_FOLDER, 'temp')
temp_path = os.path.join(temp_folder, filename)
# Ensure the temp folder exists
os.makedirs(temp_folder, exist_ok=True)
try:
# Save the uploaded file to the temp folder
file.save(temp_path)
log(
message=f"Uploaded file {filename} saved to temporary folder.",
app_route=f"/upload/{gradeLetter}/{gradeNumber}",
ip=request.remote_addr
)
# Attempt to convert the file to Markdown
try:
converted_temp_path = convert_to_markdown(temp_path)
# Validate that the converted file exists
if not converted_temp_path or not os.path.exists(converted_temp_path):
raise FileNotFoundError(f"Converted file does not exist: {converted_temp_path}")
# Define the grade folder and ensure it exists
grade_folder = os.path.join(UPLOAD_FOLDER, grade)
os.makedirs(grade_folder, exist_ok=True)
# Move the converted Markdown file to the grade folder
converted_filename = os.path.basename(converted_temp_path)
converted_path = os.path.join(grade_folder, converted_filename)
os.rename(converted_temp_path, converted_path)
log(
message=f"File {filename} successfully converted to Markdown and moved to {converted_path}.",
app_route=f"/upload/{gradeLetter}/{gradeNumber}",
ip=request.remote_addr
)
os.remove(f"./content/temp/{filename}")
return jsonify({
"success": f"File {filename} uploaded, converted to Markdown, and saved to {converted_path}"
}), 200
except Exception as e:
log(
message=f"Error converting file {filename} to Markdown: {str(e)}",
app_route=f"/upload/{gradeLetter}/{gradeNumber}",
ip=request.remote_addr
)
return jsonify({"error": f"Failed to convert the file to Markdown: {str(e)}"}), 500
except Exception as e:
log(
message=f"Failed to upload file {filename}: {str(e)}",
app_route=request.path,
ip=request.remote_addr
)
return jsonify({"error": f"Failed to save the file: {str(e)}"}), 500
# If the file type is invalid
return jsonify({"error": "Invalid file type"}), 400
# Route for handling posterboard files
@app.route("/posterboard/<gradeNum>/<gradeLetter>", methods=["GET"])
def handle_file(gradeNum: str, gradeLetter: str):
if gradeNum in [".", ".."] or gradeLetter in [".", ".."]:
log(message="Recieved request, trying to access parent folder", ip=request.remote_addr, app_route=request.path)
return jsonify({"error": "Bad request"}), 400
grade = f"{gradeNum}/{gradeLetter}"
return Tools.assemble(grade=grade)
# Route for displaying the upload page
@app.route("/manage/", methods=['GET'])
def show_manage_page():
log(message="Accesed Management page", ip=request.remote_addr, app_route=request.path)
return Tools.html("./web/management/index.html", "./web/management/management.css")
# Route for fetching the directory tree
@app.route("/get/tree/", methods=["GET"])
def tree():
path = request.args.get("path", "").strip("/")
full_path = os.path.abspath(os.path.join(BASE_DIR, path))
# Validate that full_path is within BASE_DIR
if not full_path.startswith(BASE_DIR) or not os.path.isdir(full_path):
return jsonify({"error": "Invalid directory path"}), 400
try:
def build_tree(directory):
tree = {"name": os.path.basename(directory), "type": "directory", "children": []}
for entry in sorted(os.listdir(directory)):
entry_path = os.path.join(directory, entry)
if os.path.isdir(entry_path):
tree["children"].append(build_tree(entry_path))
else:
tree["children"].append({"name": entry, "type": "file"})
return tree
# Build directory tree from the BASE_DIR
tree = build_tree(full_path)
log(message="Request tree", ip=request.remote_addr, app_route=request.path)
return jsonify(tree), 200
except Exception as e:
return jsonify({"error": f"Unable to read directory: {str(e)}"}), 500
# Route for fetching the content of a file
@app.route("/get/file/", methods=["GET"])
def get_file():
path = request.args.get("path", "").strip("/")
requested_path = os.path.abspath(os.path.join(BASE_DIR, path))
print(f"Request file: {requested_path}")
# Validate that the path is within the base directory and is a file
if not os.path.isfile(requested_path) or not requested_path.startswith(BASE_DIR):
return jsonify({"error": "Invalid file path"}), 400
try:
with open(requested_path, "r", encoding="utf-8") as file:
content = file.read()
log(message="Request tree", ip=request.remote_addr, app_route=request.path)
return jsonify({"content": content}), 200
except Exception as e:
return jsonify({"error": f"Unable to read file: {str(e)}"}), 500
def main(port: int, debug: bool):
app.run(port=port, debug=debug)