import gradio as gr from data_layer import WardIndex, resolve from model_client import classify_image, draft_complaint from theme import SariMadiTheme, CUSTOM_CSS ward_index = WardIndex() GET_LOCATION_JS = """ () => { const box = document.getElementById("loc-status-box"); const setMsg = (cls, text) => { if (box) { box.className = "loc-status " + cls; box.textContent = text; } }; setMsg("loc-pending", "Locating you..."); return new Promise((resolve) => { if (!navigator.geolocation) { setMsg("loc-err", "Geolocation not supported. Enter coordinates below."); resolve([null, null]); return; } navigator.geolocation.getCurrentPosition( (pos) => { const lat = Math.round(pos.coords.latitude * 1e6) / 1e6; const lng = Math.round(pos.coords.longitude * 1e6) / 1e6; setMsg("loc-ok", "Location set \u00b7 " + lat.toFixed(4) + ", " + lng.toFixed(4)); resolve([lat, lng]); }, (err) => { setMsg("loc-err", "Location blocked. Enter coordinates below."); resolve([null, null]); }, { enableHighAccuracy: true, timeout: 10000, maximumAge: 60000 } ); }); } """ SEVERITY_COLORS = {"low": "#16a34a", "medium": "#ea580c", "high": "#dc2626"} def build_result(image, lat, lng, language): if image is None: return _error("Please add a photo of the issue first.") if lat is None or lng is None: return _error("Please share your location or enter coordinates.") try: lat = float(lat) lng = float(lng) except (TypeError, ValueError): return _error("Those coordinates don't look right.") vision = classify_image(image) civic = vision.get("is_civic_issue", False) category = vision.get("category", "other") if not civic or category == "other": return _error( "This doesn't look like a clear civic issue BBMP handles. Point the " "camera directly at a pothole, damaged or blocked road, broken footpath, " "dead streetlight, garbage, an open or overflowing drain, waterlogging, " "or a stray or dead animal." ) info = resolve(ward_index, lat, lng, vision["category"]) if info is None: return _error( "This location is outside Bengaluru's BBMP wards. Sari Madi can only " "route complaints within Bengaluru city limits. Please use a location " "inside Bengaluru." ) officer = info["officer"] if officer is None: return _error("No officer contact found for this ward.") context = { "category_label": info["category_label"], "severity": vision["severity"], "description": vision["description"], "ward_name": info["ward_name"], "ward_no": info["ward_no"], "zone": info["zone"], "officer_role": officer["role"], "officer_name": officer["name"], } complaint = draft_complaint(context, language=language) sev = vision["severity"] sev_color = SEVERITY_COLORS.get(sev, "#ea580c") seen = vision.get("visible_text", "") seen_html = ( f'
Spotted in photo: "{seen}"
' if seen else "" ) card = f"""{vision['description']}
{seen_html}Bengaluru civic reporting
' 'Snap a civic problem. Get it routed to the right BBMP officer ' 'with a ready-to-file complaint in English or Kannada.
Your complaint will appear here
' 'Add a photo, mark the spot, and tap generate.
' '