Fred808 commited on
Commit
5a777f1
·
verified ·
1 Parent(s): f6358f8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +107 -33
app.py CHANGED
@@ -2,6 +2,7 @@ from fastapi import FastAPI, UploadFile, File, HTTPException, BackgroundTasks, Q
2
  from fastapi.responses import FileResponse, JSONResponse
3
  from fastapi.middleware.cors import CORSMiddleware
4
  import os
 
5
  import uuid
6
  import time
7
  from typing import Dict, List, Optional
@@ -30,9 +31,12 @@ app.add_middleware(
30
  allow_headers=["*"], # Allows all headers
31
  )
32
 
 
 
 
33
  processing_thread = None
34
 
35
- # ==== API ENDPOINTS ====
36
 
37
  def save_file(uploaded_file: UploadFile, save_path: str):
38
  os.makedirs(os.path.dirname(save_path), exist_ok=True)
@@ -42,8 +46,22 @@ def save_file(uploaded_file: UploadFile, save_path: str):
42
  # === ROUTES ===
43
 
44
  @app.get("/")
45
- def root():
46
- return {"message": "FastAPI Florence-2 backend"}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
 
48
  @app.post("/upload/")
49
  async def upload_file(file: UploadFile = File(...)):
@@ -62,30 +80,59 @@ async def list_uploaded_files():
62
  files.append(file)
63
  return JSONResponse(content=files)
64
 
65
-
66
  @app.get("/download/{mp4_path:path}")
67
  async def download_file(mp4_path: str):
68
  """
69
  Download any MP4 under processed_mp4s, including nested course folders.
70
  e.g. GET /download/MDS_CGAdventure_DownloadPirate.com/1.mp4
71
  """
 
 
72
  # Compose the full file path
73
  full_path = os.path.join(MP4_OUTPUT_FOLDER, mp4_path)
 
74
 
75
  # Security: Prevent escaping outside of MP4_OUTPUT_FOLDER
76
  full_path = os.path.normpath(full_path)
77
  if not full_path.startswith(os.path.abspath(MP4_OUTPUT_FOLDER)):
 
78
  raise HTTPException(status_code=400, detail="Invalid path")
79
 
80
- if not os.path.exists(full_path) or not full_path.lower().endswith(".mp4"):
81
- raise HTTPException(status_code=404, detail="File not found")
82
-
83
- return FileResponse(path=full_path, filename=os.path.basename(full_path), media_type="video/mp4")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
 
85
  @app.get("/courses")
86
  async def list_courses():
87
  """List all unique course folder names based on extracted MP4 paths."""
88
  course_folders = set()
 
 
89
 
90
  if os.path.exists(MP4_OUTPUT_FOLDER):
91
  for root, dirs, files in os.walk(MP4_OUTPUT_FOLDER):
@@ -93,41 +140,70 @@ async def list_courses():
93
  if file.lower().endswith(".mp4"):
94
  rel_path = os.path.relpath(os.path.join(root, file), MP4_OUTPUT_FOLDER)
95
  course_folder = os.path.dirname(rel_path)
96
- if course_folder:
97
  course_folders.add(course_folder)
 
98
 
99
- return JSONResponse(content={"courses": sorted(course_folders), "total": len(course_folders)})
 
 
100
 
101
  @app.get("/images/{course_folder:path}")
102
  async def list_mp4s_in_course(course_folder: str):
103
  """List MP4s available for a specific course folder"""
 
 
104
  course_path = os.path.join(MP4_OUTPUT_FOLDER, course_folder)
 
 
 
105
  if not os.path.exists(course_path):
106
- raise HTTPException(status_code=404, detail="Course folder not found")
 
 
 
 
 
 
 
 
107
 
108
  mp4s = []
109
- for file in os.listdir(course_path):
110
- if file.lower().endswith(".mp4"):
111
- mp4s.append(file)
 
 
 
 
 
112
 
 
113
  return JSONResponse(content=mp4s)
114
 
115
- @app.get("/")
116
- async def root():
117
- """API root endpoint"""
118
- return {
119
- "message": "MP4 Processing API",
120
- "version": "1.0.0",
121
- "endpoints": {
122
- "upload": "POST /upload - Upload MP4 file",
123
- "download": "GET /download/{mp4_id} - Download MP4 file",
124
- "delete": "DELETE /delete/{mp4_id} - Delete MP4 file",
125
- "list": "GET /mp4s - List all MP4 files",
126
- "start_processing": "POST /process/start - Start HF processing",
127
- "processing_status": "GET /process/status - Get processing status",
128
- "stop_processing": "POST /process/stop - Stop processing"
129
- }
130
- }
 
 
 
 
 
 
 
131
 
132
  @app.on_event("startup")
133
  async def startup_event():
@@ -141,6 +217,4 @@ async def startup_event():
141
 
142
  if __name__ == "__main__":
143
  import uvicorn
144
- uvicorn.run(app, host="0.0.0.0", port=8000)
145
-
146
-
 
2
  from fastapi.responses import FileResponse, JSONResponse
3
  from fastapi.middleware.cors import CORSMiddleware
4
  import os
5
+ import shutil # Add missing import
6
  import uuid
7
  import time
8
  from typing import Dict, List, Optional
 
31
  allow_headers=["*"], # Allows all headers
32
  )
33
 
34
+ # Define MP4_UPLOAD_FOLDER if not imported from processing_logic
35
+ MP4_UPLOAD_FOLDER = os.path.join(UPLOAD_DIRECTORY, "uploads")
36
+
37
  processing_thread = None
38
 
39
+ # ==== HELPER FUNCTIONS ====
40
 
41
  def save_file(uploaded_file: UploadFile, save_path: str):
42
  os.makedirs(os.path.dirname(save_path), exist_ok=True)
 
46
  # === ROUTES ===
47
 
48
  @app.get("/")
49
+ async def root():
50
+ """API root endpoint"""
51
+ return {
52
+ "message": "MP4 Processing API",
53
+ "version": "1.0.0",
54
+ "endpoints": {
55
+ "upload": "POST /upload - Upload MP4 file",
56
+ "download": "GET /download/{mp4_path:path} - Download MP4 file",
57
+ "list": "GET /list - List uploaded files",
58
+ "courses": "GET /courses - List all course folders",
59
+ "images": "GET /images/{course_folder:path} - List MP4s in course",
60
+ "start_processing": "POST /process/start - Start HF processing",
61
+ "processing_status": "GET /process/status - Get processing status",
62
+ "stop_processing": "POST /process/stop - Stop processing"
63
+ }
64
+ }
65
 
66
  @app.post("/upload/")
67
  async def upload_file(file: UploadFile = File(...)):
 
80
  files.append(file)
81
  return JSONResponse(content=files)
82
 
 
83
  @app.get("/download/{mp4_path:path}")
84
  async def download_file(mp4_path: str):
85
  """
86
  Download any MP4 under processed_mp4s, including nested course folders.
87
  e.g. GET /download/MDS_CGAdventure_DownloadPirate.com/1.mp4
88
  """
89
+ print(f"[DEBUG] Download request for: {mp4_path}")
90
+
91
  # Compose the full file path
92
  full_path = os.path.join(MP4_OUTPUT_FOLDER, mp4_path)
93
+ print(f"[DEBUG] Full path: {full_path}")
94
 
95
  # Security: Prevent escaping outside of MP4_OUTPUT_FOLDER
96
  full_path = os.path.normpath(full_path)
97
  if not full_path.startswith(os.path.abspath(MP4_OUTPUT_FOLDER)):
98
+ print(f"[ERROR] Security violation - path outside output folder")
99
  raise HTTPException(status_code=400, detail="Invalid path")
100
 
101
+ print(f"[DEBUG] Normalized path: {full_path}")
102
+ print(f"[DEBUG] File exists: {os.path.exists(full_path)}")
103
+ print(f"[DEBUG] Is MP4: {full_path.lower().endswith('.mp4')}")
104
+
105
+ if not os.path.exists(full_path):
106
+ # Try to find the file in subdirectories
107
+ print(f"[DEBUG] File not found at expected path, searching...")
108
+
109
+ # List what's actually in the MP4_OUTPUT_FOLDER
110
+ if os.path.exists(MP4_OUTPUT_FOLDER):
111
+ print(f"[DEBUG] Contents of {MP4_OUTPUT_FOLDER}:")
112
+ for root, dirs, files in os.walk(MP4_OUTPUT_FOLDER):
113
+ for file in files:
114
+ if file.lower().endswith('.mp4'):
115
+ rel_path = os.path.relpath(os.path.join(root, file), MP4_OUTPUT_FOLDER)
116
+ print(f"[DEBUG] Found MP4: {rel_path}")
117
+
118
+ raise HTTPException(status_code=404, detail=f"File not found: {mp4_path}")
119
+
120
+ if not full_path.lower().endswith(".mp4"):
121
+ raise HTTPException(status_code=400, detail="File is not an MP4")
122
+
123
+ print(f"[DEBUG] Serving file: {full_path}")
124
+ return FileResponse(
125
+ path=full_path,
126
+ filename=os.path.basename(full_path),
127
+ media_type="video/mp4"
128
+ )
129
 
130
  @app.get("/courses")
131
  async def list_courses():
132
  """List all unique course folder names based on extracted MP4 paths."""
133
  course_folders = set()
134
+
135
+ print(f"[DEBUG] Scanning {MP4_OUTPUT_FOLDER} for courses")
136
 
137
  if os.path.exists(MP4_OUTPUT_FOLDER):
138
  for root, dirs, files in os.walk(MP4_OUTPUT_FOLDER):
 
140
  if file.lower().endswith(".mp4"):
141
  rel_path = os.path.relpath(os.path.join(root, file), MP4_OUTPUT_FOLDER)
142
  course_folder = os.path.dirname(rel_path)
143
+ if course_folder and course_folder != ".":
144
  course_folders.add(course_folder)
145
+ print(f"[DEBUG] Found course: {course_folder} (from file: {rel_path})")
146
 
147
+ courses_list = sorted(course_folders)
148
+ print(f"[DEBUG] Returning courses: {courses_list}")
149
+ return JSONResponse(content={"courses": courses_list, "total": len(courses_list)})
150
 
151
  @app.get("/images/{course_folder:path}")
152
  async def list_mp4s_in_course(course_folder: str):
153
  """List MP4s available for a specific course folder"""
154
+ print(f"[DEBUG] Listing MP4s for course: {course_folder}")
155
+
156
  course_path = os.path.join(MP4_OUTPUT_FOLDER, course_folder)
157
+ print(f"[DEBUG] Course path: {course_path}")
158
+ print(f"[DEBUG] Path exists: {os.path.exists(course_path)}")
159
+
160
  if not os.path.exists(course_path):
161
+ # List what's actually available
162
+ print(f"[DEBUG] Course folder not found. Available folders:")
163
+ if os.path.exists(MP4_OUTPUT_FOLDER):
164
+ for item in os.listdir(MP4_OUTPUT_FOLDER):
165
+ item_path = os.path.join(MP4_OUTPUT_FOLDER, item)
166
+ if os.path.isdir(item_path):
167
+ print(f"[DEBUG] {item}")
168
+
169
+ raise HTTPException(status_code=404, detail=f"Course folder not found: {course_folder}")
170
 
171
  mp4s = []
172
+ try:
173
+ for file in os.listdir(course_path):
174
+ if file.lower().endswith(".mp4"):
175
+ mp4s.append(file)
176
+ print(f"[DEBUG] Found MP4: {file}")
177
+ except Exception as e:
178
+ print(f"[ERROR] Failed to list files in {course_path}: {e}")
179
+ raise HTTPException(status_code=500, detail="Failed to list files")
180
 
181
+ print(f"[DEBUG] Returning MP4s: {mp4s}")
182
  return JSONResponse(content=mp4s)
183
 
184
+ # Add debug endpoint to help troubleshoot
185
+ @app.get("/debug/structure")
186
+ async def debug_file_structure():
187
+ """Debug endpoint to show the actual file structure"""
188
+ structure = {}
189
+
190
+ if os.path.exists(MP4_OUTPUT_FOLDER):
191
+ for root, dirs, files in os.walk(MP4_OUTPUT_FOLDER):
192
+ rel_root = os.path.relpath(root, MP4_OUTPUT_FOLDER)
193
+ if rel_root == ".":
194
+ rel_root = "/"
195
+
196
+ structure[rel_root] = {
197
+ "directories": dirs,
198
+ "mp4_files": [f for f in files if f.lower().endswith('.mp4')],
199
+ "other_files": [f for f in files if not f.lower().endswith('.mp4')]
200
+ }
201
+
202
+ return JSONResponse(content={
203
+ "mp4_output_folder": MP4_OUTPUT_FOLDER,
204
+ "folder_exists": os.path.exists(MP4_OUTPUT_FOLDER),
205
+ "structure": structure
206
+ })
207
 
208
  @app.on_event("startup")
209
  async def startup_event():
 
217
 
218
  if __name__ == "__main__":
219
  import uvicorn
220
+ uvicorn.run(app, host="0.0.0.0", port=8000)