Spaces:
Sleeping
Sleeping
ParthivM1 commited on
Commit ·
7dedd16
1
Parent(s): 2891bd6
Final for report section
Browse files
app.py
CHANGED
|
@@ -32,8 +32,6 @@ if not SUPABASE_URL or not SUPABASE_KEY:
|
|
| 32 |
raise ValueError("Supabase credentials not found.")
|
| 33 |
supabase: Client = create_client(SUPABASE_URL, SUPABASE_KEY)
|
| 34 |
|
| 35 |
-
# --- Helper functions (convert_to_decimal, get_gps_location, etc.) remain the same ---
|
| 36 |
-
|
| 37 |
def convert_to_decimal(coord):
|
| 38 |
if coord and len(coord.values) >= 3:
|
| 39 |
deg = float(coord.values[0])
|
|
@@ -97,31 +95,24 @@ async def root():
|
|
| 97 |
@app.get("/latest_reports")
|
| 98 |
async def get_latest_reports():
|
| 99 |
try:
|
| 100 |
-
# Fetch latest 30 videos
|
| 101 |
videos_response = supabase.table("videos").select("guid, video_name, created_at, status").order("created_at", desc=True).limit(30).execute()
|
| 102 |
videos = videos_response.data
|
| 103 |
for video in videos:
|
| 104 |
video['type'] = 'video'
|
| 105 |
-
# Fetch a thumbnail for each video
|
| 106 |
first_frame_response = supabase.table("detected_frames").select("frame_image_url").eq("video_guid", video["guid"]).order("frame_number").limit(1).execute()
|
| 107 |
video["thumbnail_url"] = first_frame_response.data[0]["frame_image_url"] if first_frame_response.data else None
|
| 108 |
|
| 109 |
-
# Fetch latest 30 images (from 'potholes' table)
|
| 110 |
images_response = supabase.table("potholes").select("guid, image_name, image_url, created_at, status").order("created_at", desc=True).limit(30).execute()
|
| 111 |
images = images_response.data
|
| 112 |
for image in images:
|
| 113 |
image['type'] = 'image'
|
| 114 |
image['thumbnail_url'] = image.get('image_url')
|
| 115 |
|
| 116 |
-
# Combine, sort, and slice the results
|
| 117 |
combined_reports = sorted(videos + images, key=lambda x: datetime.fromisoformat(x['created_at']), reverse=True)
|
| 118 |
-
|
| 119 |
return combined_reports[:30]
|
| 120 |
except Exception as e:
|
| 121 |
raise HTTPException(status_code=500, detail=f"Database Error: {str(e)}")
|
| 122 |
|
| 123 |
-
# --- Other endpoints remain the same ---
|
| 124 |
-
|
| 125 |
@app.patch("/report/{guid}/status")
|
| 126 |
async def update_report_status(guid: str, payload: dict = Body(...)):
|
| 127 |
new_status = payload.get("status")
|
|
@@ -163,28 +154,18 @@ async def upload_video(background_tasks: BackgroundTasks, file: UploadFile = Fil
|
|
| 163 |
async def get_video_report(guid: str):
|
| 164 |
try:
|
| 165 |
video_response = supabase.table("videos").select("*").eq("guid", guid).single().execute()
|
| 166 |
-
if not video_response.data:
|
| 167 |
-
raise HTTPException(status_code=404, detail="Video report not found")
|
| 168 |
-
|
| 169 |
frames_response = supabase.table("detected_frames").select("*").eq("video_guid", guid).order("frame_number", desc=True).limit(15).execute()
|
| 170 |
-
|
| 171 |
-
|
| 172 |
-
"video_info": video_response.data,
|
| 173 |
-
"detected_frames": frames_response.data
|
| 174 |
-
}
|
| 175 |
-
except Exception as e:
|
| 176 |
-
raise HTTPException(status_code=500, detail=f"Database Error: {str(e)}")
|
| 177 |
-
|
| 178 |
|
| 179 |
@app.get("/frame/{frame_id}")
|
| 180 |
async def get_frame(frame_id: int):
|
| 181 |
try:
|
| 182 |
response = supabase.table("detected_frames").select("*, videos(*), status").eq("id", frame_id).single().execute()
|
| 183 |
-
if not response.data:
|
| 184 |
-
raise HTTPException(status_code=404, detail="Frame not found")
|
| 185 |
return response.data
|
| 186 |
-
except Exception as e:
|
| 187 |
-
raise HTTPException(status_code=500, detail=f"Database Error: {str(e)}")
|
| 188 |
|
| 189 |
@app.get("/videos")
|
| 190 |
async def get_videos():
|
|
@@ -195,27 +176,22 @@ async def get_videos():
|
|
| 195 |
first_frame_response = supabase.table("detected_frames").select("frame_image_url").eq("video_guid", video["guid"]).order("frame_number").limit(1).execute()
|
| 196 |
video["thumbnail_url"] = first_frame_response.data[0]["frame_image_url"] if first_frame_response.data else None
|
| 197 |
return videos
|
| 198 |
-
except Exception as e:
|
| 199 |
-
raise HTTPException(status_code=500, detail=f"Database Error: {str(e)}")
|
| 200 |
|
| 201 |
@app.get("/reports")
|
| 202 |
async def get_reports():
|
| 203 |
try:
|
| 204 |
response = supabase.table("potholes").select("id, guid, image_name, image_url, created_at, status").order("created_at", desc=True).limit(30).execute()
|
| 205 |
return response.data
|
| 206 |
-
except Exception as e:
|
| 207 |
-
raise HTTPException(status_code=500, detail=f"Database Error: {str(e)}")
|
| 208 |
|
| 209 |
@app.get("/report/{guid}")
|
| 210 |
async def get_report(guid: str):
|
| 211 |
try:
|
| 212 |
response = supabase.table("potholes").select("guid, image_name, image_url, location, created_at, location_text, status").eq("guid", guid).single().execute()
|
| 213 |
-
if response.data:
|
| 214 |
-
|
| 215 |
-
|
| 216 |
-
raise HTTPException(status_code=404, detail=f"Report with guid {guid} not found.")
|
| 217 |
-
except Exception as e:
|
| 218 |
-
raise HTTPException(status_code=500, detail=f"Database Error: {str(e)}")
|
| 219 |
|
| 220 |
@app.post("/upload")
|
| 221 |
async def upload_image(file: UploadFile = File(...), location: str = Form(None)):
|
|
@@ -227,16 +203,14 @@ async def upload_image(file: UploadFile = File(...), location: str = Form(None))
|
|
| 227 |
annotated_image_array = results[0].plot()
|
| 228 |
os.remove(temp_path)
|
| 229 |
is_success, buffer = cv2.imencode(".jpg", annotated_image_array)
|
| 230 |
-
if not is_success:
|
| 231 |
-
raise HTTPException(status_code=500, detail="Failed to encode annotated image.")
|
| 232 |
annotated_image_bytes = buffer.tobytes()
|
| 233 |
bucket_name = 'pothole-images'
|
| 234 |
uuid_path = f"annotated_{uuid.uuid4()}.jpg"
|
| 235 |
try:
|
| 236 |
supabase.storage.from_(bucket_name).upload(path=uuid_path, file=annotated_image_bytes, file_options={"content-type": "image/jpeg"})
|
| 237 |
url = supabase.storage.from_(bucket_name).get_public_url(uuid_path)
|
| 238 |
-
except Exception as e:
|
| 239 |
-
raise HTTPException(status_code=500, detail=f"Storage Error: {str(e)}")
|
| 240 |
await file.seek(0)
|
| 241 |
lat, lon = get_gps_location(file.file)
|
| 242 |
location_point = f"Point({lon:.6f} {lat:.6f})" if lat and lon else None
|
|
@@ -244,8 +218,7 @@ async def upload_image(file: UploadFile = File(...), location: str = Form(None))
|
|
| 244 |
try:
|
| 245 |
insert_data = {"guid": guid, "image_name": file.filename, "image_url": url, "location": location_point, "location_text": location if not location_point and location else None, "status": "In Progress"}
|
| 246 |
response = supabase.table("potholes").insert(insert_data).execute()
|
| 247 |
-
except Exception as e:
|
| 248 |
-
raise HTTPException(status_code=500, detail=f"Database Error: {str(e)}")
|
| 249 |
return {"message": "Upload successful", "guid": guid, "image_url": url, "db_response": response.data}
|
| 250 |
|
| 251 |
if __name__ == "__main__":
|
|
|
|
| 32 |
raise ValueError("Supabase credentials not found.")
|
| 33 |
supabase: Client = create_client(SUPABASE_URL, SUPABASE_KEY)
|
| 34 |
|
|
|
|
|
|
|
| 35 |
def convert_to_decimal(coord):
|
| 36 |
if coord and len(coord.values) >= 3:
|
| 37 |
deg = float(coord.values[0])
|
|
|
|
| 95 |
@app.get("/latest_reports")
|
| 96 |
async def get_latest_reports():
|
| 97 |
try:
|
|
|
|
| 98 |
videos_response = supabase.table("videos").select("guid, video_name, created_at, status").order("created_at", desc=True).limit(30).execute()
|
| 99 |
videos = videos_response.data
|
| 100 |
for video in videos:
|
| 101 |
video['type'] = 'video'
|
|
|
|
| 102 |
first_frame_response = supabase.table("detected_frames").select("frame_image_url").eq("video_guid", video["guid"]).order("frame_number").limit(1).execute()
|
| 103 |
video["thumbnail_url"] = first_frame_response.data[0]["frame_image_url"] if first_frame_response.data else None
|
| 104 |
|
|
|
|
| 105 |
images_response = supabase.table("potholes").select("guid, image_name, image_url, created_at, status").order("created_at", desc=True).limit(30).execute()
|
| 106 |
images = images_response.data
|
| 107 |
for image in images:
|
| 108 |
image['type'] = 'image'
|
| 109 |
image['thumbnail_url'] = image.get('image_url')
|
| 110 |
|
|
|
|
| 111 |
combined_reports = sorted(videos + images, key=lambda x: datetime.fromisoformat(x['created_at']), reverse=True)
|
|
|
|
| 112 |
return combined_reports[:30]
|
| 113 |
except Exception as e:
|
| 114 |
raise HTTPException(status_code=500, detail=f"Database Error: {str(e)}")
|
| 115 |
|
|
|
|
|
|
|
| 116 |
@app.patch("/report/{guid}/status")
|
| 117 |
async def update_report_status(guid: str, payload: dict = Body(...)):
|
| 118 |
new_status = payload.get("status")
|
|
|
|
| 154 |
async def get_video_report(guid: str):
|
| 155 |
try:
|
| 156 |
video_response = supabase.table("videos").select("*").eq("guid", guid).single().execute()
|
| 157 |
+
if not video_response.data: raise HTTPException(status_code=404, detail="Video report not found")
|
|
|
|
|
|
|
| 158 |
frames_response = supabase.table("detected_frames").select("*").eq("video_guid", guid).order("frame_number", desc=True).limit(15).execute()
|
| 159 |
+
return { "video_info": video_response.data, "detected_frames": frames_response.data }
|
| 160 |
+
except Exception as e: raise HTTPException(status_code=500, detail=f"Database Error: {str(e)}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 161 |
|
| 162 |
@app.get("/frame/{frame_id}")
|
| 163 |
async def get_frame(frame_id: int):
|
| 164 |
try:
|
| 165 |
response = supabase.table("detected_frames").select("*, videos(*), status").eq("id", frame_id).single().execute()
|
| 166 |
+
if not response.data: raise HTTPException(status_code=404, detail="Frame not found")
|
|
|
|
| 167 |
return response.data
|
| 168 |
+
except Exception as e: raise HTTPException(status_code=500, detail=f"Database Error: {str(e)}")
|
|
|
|
| 169 |
|
| 170 |
@app.get("/videos")
|
| 171 |
async def get_videos():
|
|
|
|
| 176 |
first_frame_response = supabase.table("detected_frames").select("frame_image_url").eq("video_guid", video["guid"]).order("frame_number").limit(1).execute()
|
| 177 |
video["thumbnail_url"] = first_frame_response.data[0]["frame_image_url"] if first_frame_response.data else None
|
| 178 |
return videos
|
| 179 |
+
except Exception as e: raise HTTPException(status_code=500, detail=f"Database Error: {str(e)}")
|
|
|
|
| 180 |
|
| 181 |
@app.get("/reports")
|
| 182 |
async def get_reports():
|
| 183 |
try:
|
| 184 |
response = supabase.table("potholes").select("id, guid, image_name, image_url, created_at, status").order("created_at", desc=True).limit(30).execute()
|
| 185 |
return response.data
|
| 186 |
+
except Exception as e: raise HTTPException(status_code=500, detail=f"Database Error: {str(e)}")
|
|
|
|
| 187 |
|
| 188 |
@app.get("/report/{guid}")
|
| 189 |
async def get_report(guid: str):
|
| 190 |
try:
|
| 191 |
response = supabase.table("potholes").select("guid, image_name, image_url, location, created_at, location_text, status").eq("guid", guid).single().execute()
|
| 192 |
+
if not response.data: raise HTTPException(status_code=404, detail=f"Report with guid {guid} not found.")
|
| 193 |
+
return response.data
|
| 194 |
+
except Exception as e: raise HTTPException(status_code=500, detail=f"Database Error: {str(e)}")
|
|
|
|
|
|
|
|
|
|
| 195 |
|
| 196 |
@app.post("/upload")
|
| 197 |
async def upload_image(file: UploadFile = File(...), location: str = Form(None)):
|
|
|
|
| 203 |
annotated_image_array = results[0].plot()
|
| 204 |
os.remove(temp_path)
|
| 205 |
is_success, buffer = cv2.imencode(".jpg", annotated_image_array)
|
| 206 |
+
if not is_success: raise HTTPException(status_code=500, detail="Failed to encode annotated image.")
|
|
|
|
| 207 |
annotated_image_bytes = buffer.tobytes()
|
| 208 |
bucket_name = 'pothole-images'
|
| 209 |
uuid_path = f"annotated_{uuid.uuid4()}.jpg"
|
| 210 |
try:
|
| 211 |
supabase.storage.from_(bucket_name).upload(path=uuid_path, file=annotated_image_bytes, file_options={"content-type": "image/jpeg"})
|
| 212 |
url = supabase.storage.from_(bucket_name).get_public_url(uuid_path)
|
| 213 |
+
except Exception as e: raise HTTPException(status_code=500, detail=f"Storage Error: {str(e)}")
|
|
|
|
| 214 |
await file.seek(0)
|
| 215 |
lat, lon = get_gps_location(file.file)
|
| 216 |
location_point = f"Point({lon:.6f} {lat:.6f})" if lat and lon else None
|
|
|
|
| 218 |
try:
|
| 219 |
insert_data = {"guid": guid, "image_name": file.filename, "image_url": url, "location": location_point, "location_text": location if not location_point and location else None, "status": "In Progress"}
|
| 220 |
response = supabase.table("potholes").insert(insert_data).execute()
|
| 221 |
+
except Exception as e: raise HTTPException(status_code=500, detail=f"Database Error: {str(e)}")
|
|
|
|
| 222 |
return {"message": "Upload successful", "guid": guid, "image_url": url, "db_response": response.data}
|
| 223 |
|
| 224 |
if __name__ == "__main__":
|