From 24ea17819efdd4d3ab19271c7a1f277cc7490277 Mon Sep 17 00:00:00 2001
From: Raghuram Subramani <raghus2247@gmail.com>
Date: Mon, 07 Apr 2025 12:15:39 +0530
Subject: [PATCH] update app

---
 flake.nix                      |   3 +++
 heinous_offences/app.py        | 143 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 heinous_offences/import_csv.py |  24 ------------------------
 3 files changed, 134 insertions(+), 36 deletions(-)

diff --git a/flake.nix b/flake.nix
index d080875..55fdb95 100644
--- a/flake.nix
+++ a/flake.nix
@@ -17,6 +17,7 @@
           p.uvicorn
           p.jinja2
           p.streamlit
+          p.gradio
 
           # p.pdf2image
           # p.openai-whisper
@@ -29,6 +30,8 @@
         geckodriver
 
         tesseract
+
+        nodejs_22
       ];
     };
   };
diff --git a/heinous_offences/app.py b/heinous_offences/app.py
index d527aa8..7cec2bd 100644
--- a/heinous_offences/app.py
+++ a/heinous_offences/app.py
@@ -1,19 +1,138 @@
-import streamlit as st
+from fastapi import FastAPI, Form, UploadFile
+from fastapi.responses import HTMLResponse, RedirectResponse
+import gradio as gr
+import csv
 from tinydb import TinyDB, Query
+import shutil
 
-db = TinyDB('db.json')
+DB_FILE = "db.json"
+ADMIN_PASSWORD = "shivermetimbers"
 
-st.title('Heinous Crime Lookup')
+db = TinyDB(DB_FILE)
 
-section = st.number_input('Section', value=0)
+name_from_key = {
+    'ipc': 'Indian Penal Code',
+    'bns': 'Bhartiya Nyay Sanhita',
+    'pocso': 'POCSO, 2012',
+    'scst': 'SCST Act, 1989',
+    'ndps': 'NDPS Act, 1985',
+    'arms': 'Arms Act, 1959',
+    'motor': 'Motor Vehicle Act, 1988',
+    'it': 'IT Act, 2000'
+}
 
-if section > 0:
-    offence = db.search(Query().section == str(section))[0]
-    st.subheader(offence['severity'])
-    st.write(offence['section_text'])
+key_from_name = { value: key for key, value in name_from_key.items() }
 
-    st.subheader('Minimum Punishment')
-    st.write(offence['minimum_punishment'])
+crime_query = Query()
 
-    st.subheader('Comments')
-    st.write(offence['comment'])
+# ---------- Gradio Logic ----------
+def lookup_crime(section, act_key):
+    if section <= 0:
+        return "Please enter a valid section number.", "", "", ""
+
+    table = db.table(key_from_name[act_key])
+    results = table.search(crime_query.section == str(section))
+
+    if not results:
+        return f"No record found for section {section} under {name_from_key.get(act_key)}.", "", "", ""
+
+    offence = results[0]
+    return [
+        f"## Severity: {offence.get('severity', 'N/A')}",
+        f"{offence.get('section_text', 'N/A')}",
+        f"### Minimum Punishment: {offence.get('minimum_punishment', 'N/A')}",
+        f"Comments: {offence.get('comment', 'N/A')}"
+    ]
+
+gradio_ui = gr.Blocks()
+with gradio_ui:
+    gr.Markdown("## Heinous Crime Lookup Tool")
+
+    with gr.Row():
+        section_input = gr.Number(label="Enter Section Number", value=0)
+        act_dropdown = gr.Dropdown(choices=list(name_from_key.values()), label="Select Act")
+
+    submit_btn = gr.Button("Lookup")
+    severity = gr.Markdown()
+    section_text = gr.Markdown()
+    punishment = gr.Markdown()
+    comment = gr.Markdown()
+
+    submit_btn.click(
+        fn=lookup_crime,
+        inputs=[section_input, act_dropdown],
+        outputs=[severity, section_text, punishment, comment]
+    )
+
+# ---------- FastAPI Logic ----------
+app = FastAPI()
+
+@app.get("/admin", response_class=HTMLResponse)
+async def admin_form():
+    options_html = "".join(
+        f"<option value='{key}'>{label}</option>" for key, label in name_from_key.items()
+    )
+    return f"""
+    <html>
+        <head><title>Admin Upload</title></head>
+        <link
+          rel="stylesheet"
+          href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css"
+        >
+        <body>
+        <main class='container'>
+            <h2>Admin Panel - Upload CSV</h2>
+            <form action="/admin" method="post" enctype="multipart/form-data">
+                <label>Password:</label>
+                <input type="password" name="password" required><br><br>
+
+                <label>Select Act:</label>
+                <select name="act" required>
+                    {options_html}
+                </select><br><br>
+
+                <label>CSV File:</label>
+                <input type="file" name="file" accept=".csv" required><br><br>
+                <input type="submit" value="Upload & Replace DB">
+            </form>
+        </main>
+        </body>
+    </html>
+    """
+
+@app.post("/admin")
+async def handle_admin_upload(
+    password: str = Form(...),
+    act: str = Form(...),
+    file: UploadFile = Form(...)
+):
+    if password != ADMIN_PASSWORD:
+        return HTMLResponse("<h3>Incorrect password.</h3>", status_code=401)
+
+    if act not in name_from_key:
+        return HTMLResponse("<h3>Invalid Act selected.</h3>", status_code=400)
+
+    with open('tmp.csv', "wb") as buffer:
+        shutil.copyfileobj(file.file, buffer)
+
+    db.drop_table(act)
+    table = db.table(act)
+
+    with open('tmp.csv', "r", encoding="utf-8") as f:
+        reader = csv.reader(f)
+        next(reader)
+        for row in reader:
+            if len(row) < 5:
+                continue
+            table.insert({
+                "section": row[0],
+                "section_text": row[1],
+                "minimum_punishment": row[2],
+                "severity": row[3],
+                "comment": row[4],
+            })
+
+    return RedirectResponse("/admin", status_code=303)
+
+# Mount Gradio on "/"
+gr.mount_gradio_app(app, gradio_ui, path="/")
diff --git a/heinous_offences/import_csv.py b/heinous_offences/import_csv.py
deleted file mode 100644
index bff906f..0000000 100644
--- a/heinous_offences/import_csv.py
+++ /dev/null
@@ -1,24 +1,0 @@
-import tinydb
-import csv
-
-db = tinydb.TinyDB('db.json')
-file = open('ipc.csv', 'r')
-
-reader = csv.reader(file)
-
-header_parsed = False
-for row in reader:
-    if not header_parsed:
-        header_parsed = True
-        continue
-
-    record = {
-        'section': row[0],
-        'section_text': row[1],
-        'minimum_punishment': row[2],
-        'severity': row[3],
-        'comment': row[4]
-    }
-    db.insert(record)
-
-file.close()
--
rgit 0.1.5