Spaces:
Sleeping
Sleeping
File size: 11,949 Bytes
ba9d42c e55c1dd 10f63f4 fff8c20 ba9d42c e55c1dd 10f63f4 d2c308e 10f63f4 e55c1dd 9a09158 10f63f4 a8d585d 10f63f4 9a09158 fff8c20 c80b5e5 d2c308e 10f63f4 b24fec9 d2c308e 10f63f4 d2c308e 10f63f4 9a09158 10f63f4 d2c308e 10f63f4 d2c308e b24fec9 c404ea1 10f63f4 b24fec9 10f63f4 b24fec9 fff8c20 d2c308e b24fec9 10f63f4 d2c308e 10f63f4 d2c308e 10f63f4 d2c308e 10f63f4 d2c308e 9a09158 d2c308e 2807f04 f591015 b4f2206 c03c75e f591015 c03c75e b4f2206 9a09158 c03c75e f591015 c03c75e f591015 b24fec9 a8d585d 10f63f4 b24fec9 a8d585d 10f63f4 a8d585d b24fec9 a8d585d 9a09158 2ce8aec 10f63f4 2ce8aec 9a09158 2ce8aec 9a09158 4078b37 10f63f4 9a09158 4078b37 10f63f4 9a09158 d2c308e 10f63f4 9a09158 10f63f4 2807f04 10f63f4 d2c308e 10f63f4 d2c308e 10f63f4 a8d585d 10f63f4 a8d585d 10f63f4 fff8c20 10f63f4 9a09158 fff8c20 a8d585d | 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 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 | import gradio as gr
import sqlite3
import os
import datetime
DB_FILE = "cases.db"
# -----------------------------
# Database setup
# -----------------------------
def init_db():
conn = sqlite3.connect(DB_FILE)
c = conn.cursor()
# Cases table
c.execute('''CREATE TABLE IF NOT EXISTS summons_cases (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT,
address TEXT,
ticket_number TEXT UNIQUE,
vehicle_number TEXT,
road_name TEXT,
town_city TEXT,
state TEXT,
offence_en TEXT,
offence_bm TEXT,
offence_cn TEXT,
base_fine REAL,
status TEXT,
created_at TEXT,
updated_at TEXT
)''')
# Appeals table
c.execute('''CREATE TABLE IF NOT EXISTS appeals (
appeal_id INTEGER PRIMARY KEY AUTOINCREMENT,
ticket_number TEXT,
appeal_text TEXT,
appeal_to TEXT,
decision TEXT,
final_fine REAL,
created_at TEXT,
updated_at TEXT
)''')
conn.commit()
conn.close()
def seed_mock_data():
"""Seed Ali, Ah Kow, Muthu if DB empty"""
conn = sqlite3.connect(DB_FILE)
c = conn.cursor()
c.execute("SELECT COUNT(*) FROM summons_cases")
if c.fetchone()[0] == 0:
now = datetime.datetime.now().isoformat()
cases = [
("Ali", "12, Jalan Kenanga 3, Taman Seri, 75450 Melaka", "K250901234", "VDK8821",
"Jalan Lembongan", "Melaka", "Melaka Tengah",
"Not obeying correct lane usage",
"Tidak mematuhi lorong yang betul",
"未按规定车道行驶",
300.00, "ISSUED", now, now),
("Ah Kow", "88, Jalan Merdeka, 75000 Melaka", "K250901235", "MCX8899",
"Jalan Merdeka", "Melaka", "Melaka Tengah",
"Speeding over 120km/h in city zone",
"Memandu melebihi 120km/j di kawasan bandar",
"在市区超速驾驶超过120公里/小时",
250.00, "ISSUED", now, now),
("Muthu", "5, Jalan Bunga Raya, 11000 Pulau Pinang", "K250901236", "PGX5521",
"Jalan Bunga Raya", "George Town", "Pulau Pinang",
"Parking in a no-parking zone",
"Letak kenderaan di kawasan larangan",
"在禁止停车区停车",
100.00, "ISSUED", now, now)
]
c.executemany('''INSERT INTO summons_cases
(name, address, ticket_number, vehicle_number, road_name, town_city, state,
offence_en, offence_bm, offence_cn, base_fine, status, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)''', cases)
conn.commit()
conn.close()
# -----------------------------
# DB Helper
# -----------------------------
def find_case(ticket_number, name, vehicle_number):
conn = sqlite3.connect(DB_FILE)
c = conn.cursor()
c.execute("""SELECT * FROM summons_cases
WHERE ticket_number=? OR name=? OR vehicle_number=?""",
(ticket_number, name, vehicle_number))
row = c.fetchone()
conn.close()
return row
# -----------------------------
# Citizen Portal
# -----------------------------
def create_case(name, address, ticket_number, vehicle_number, road_name, town_city, state,
offence_en, offence_bm, offence_cn, base_fine):
now = datetime.datetime.now().isoformat()
conn = sqlite3.connect(DB_FILE)
c = conn.cursor()
try:
c.execute('''INSERT INTO summons_cases
(name, address, ticket_number, vehicle_number, road_name, town_city, state,
offence_en, offence_bm, offence_cn, base_fine, status, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)''',
(name, address, ticket_number, vehicle_number, road_name, town_city, state,
offence_en, offence_bm, offence_cn, base_fine, "ISSUED", now, now))
conn.commit()
return "✅ Case created successfully / Kes berjaya dicipta / 案件创建成功"
except sqlite3.IntegrityError:
return "❌ Case already exists / Kes sudah wujud / 案件已存在"
finally:
conn.close()
def view_case(ticket_number, name, vehicle_number):
row = find_case(ticket_number, name, vehicle_number)
if not row:
return "❌ Case not found / Kes tidak dijumpai / 未找到案件"
return (
f"Case / Kes / 案件 — Ticket: {row[3]}\n"
f"Name / Nama / 姓名: {row[1]}\n"
f"Address / Alamat / 地址: {row[2]}\n\n"
f"Vehicle No. / No. Kenderaan / 车牌号码: {row[4]}\n"
f"Road / Jalan / 道路: {row[5]}\n"
f"Town/City / Bandar / 城市: {row[6]}\n"
f"State / Negeri / 州: {row[7]}\n\n"
f"Offence (EN): {row[8]}\n"
f"Kesalahan (BM): {row[9]}\n"
f"违法 (中文): {row[10]}\n\n"
f"Base Fine / Denda Asal / 原始罚款: RM {row[11]:.2f}\n"
f"Status / Status / 状态: {row[12]}\n\n"
f"Created / Dicipta / 创建: {row[13]}\n"
f"Updated / Dikemaskini / 更新: {row[14]}"
)
def appeal_to_pdrm(ticket_number, appeal_text):
now = datetime.datetime.now().isoformat()
conn = sqlite3.connect(DB_FILE)
c = conn.cursor()
c.execute('''INSERT INTO appeals (ticket_number, appeal_text, appeal_to, decision, final_fine, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, ?)''',
(ticket_number, appeal_text, "PDRM", None, None, now, now))
conn.commit()
conn.close()
return "📨 Appeal submitted to PDRM / Rayuan dihantar ke PDRM / 上诉已提交给皇家警察"
def appeal_to_magistrate(ticket_number, appeal_text):
now = datetime.datetime.now().isoformat()
conn = sqlite3.connect(DB_FILE)
c = conn.cursor()
c.execute('''INSERT INTO appeals (ticket_number, appeal_text, appeal_to, decision, final_fine, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, ?)''',
(ticket_number, appeal_text, "MAGISTRATE", None, None, now, now))
conn.commit()
conn.close()
return "📨 Appeal submitted to Magistrate / Rayuan dihantar ke Majistret / 上诉已提交给地方法官"
def view_appeal_status(ticket_number):
conn = sqlite3.connect(DB_FILE)
c = conn.cursor()
c.execute("SELECT decision, final_fine FROM appeals WHERE ticket_number=? ORDER BY appeal_id DESC LIMIT 1", (ticket_number,))
row = c.fetchone()
decision, final_fine = None, None
# Predefined outcomes
if ticket_number == "K250901234": # Ali
decision, final_fine = "APPROVED_REDUCED", 150.00
elif ticket_number == "K250901235": # Ah Kow
decision, final_fine = "REJECTED", 250.00
elif ticket_number == "K250901236": # Muthu
decision, final_fine = "MAINTAINED", 100.00
if not row or not row[0]:
c.execute("UPDATE appeals SET decision=?, final_fine=? WHERE ticket_number=?",
(decision, final_fine, ticket_number))
conn.commit()
else:
decision, final_fine = row
conn.close()
decision_map = {
"APPROVED_REDUCED": "APPROVED_REDUCED / DILULUSKAN & DIKURANGKAN / 批准并减免",
"REJECTED": "REJECTED / DITOLAK / 驳回",
"MAINTAINED": "MAINTAINED / DIKEKALKAN / 维持原判"
}
decision_str = decision_map.get(decision, decision)
fine_str = "Pending / Menunggu / 待定" if final_fine is None else f"RM {final_fine:.2f}"
return (
f"Appeal Status / Status Rayuan / 上诉状态 — Ticket: {ticket_number}\n"
f"Decision / Keputusan / 决定: {decision_str}\n"
f"Final Fine / Denda Akhir / 最终罚款: {fine_str}"
)
def pay_fine(ticket_number):
return f"💳 Payment successful / Bayaran berjaya / 支付成功 — Ticket: {ticket_number}. Receipt issued / Resit dikeluarkan / 收据已发出."
# -----------------------------
# Gradio UI
# -----------------------------
def citizen_portal():
with gr.Tab("Citizen Portal / Portal Warganegara / 公民门户"):
with gr.Tab("Create Case / Cipta Kes / 创建案件"):
name = gr.Textbox(label="Name / Nama / 姓名")
address = gr.Textbox(label="Address / Alamat / 地址")
ticket_number = gr.Textbox(label="Ticket Number / Nombor Saman / 传票号码")
vehicle_number = gr.Textbox(label="Vehicle No. / No. Kenderaan / 车牌号码")
road_name = gr.Textbox(label="Road / Jalan / 道路")
town_city = gr.Textbox(label="Town/City / Bandar / 城市")
state = gr.Textbox(label="State / Negeri / 州")
offence_en = gr.Textbox(label="Offence (EN)")
offence_bm = gr.Textbox(label="Kesalahan (BM)")
offence_cn = gr.Textbox(label="违法 (中文)")
base_fine = gr.Number(label="Base Fine / Denda Asal / 原始罚款", value=300.00)
create_btn = gr.Button("Create / Cipta / 创建")
create_output = gr.Textbox(label="Result / Keputusan / 结果")
create_btn.click(create_case, [name, address, ticket_number, vehicle_number,
road_name, town_city, state,
offence_en, offence_bm, offence_cn, base_fine],
create_output)
with gr.Tab("View Case / Lihat Kes / 查看案件"):
vc_ticket = gr.Textbox(label="Ticket Number / Nombor Saman / 传票号码")
vc_name = gr.Textbox(label="Name / Nama / 姓名")
vc_vehicle = gr.Textbox(label="Vehicle No. / No. Kenderaan / 车牌号码")
view_btn = gr.Button("View / Lihat / 查看")
view_output = gr.Textbox(label="Case Details / Butiran Kes / 案件详情", lines=15)
view_btn.click(view_case, [vc_ticket, vc_name, vc_vehicle], view_output)
with gr.Tab("Submit Appeal / Hantar Rayuan / 提交上诉"):
sa_ticket = gr.Textbox(label="Ticket Number / Nombor Saman / 传票号码")
sa_text = gr.Textbox(label="Appeal Text / Teks Rayuan / 上诉内容")
sa_pdrm_btn = gr.Button("Appeal to PDRM / Rayuan ke PDRM / 向皇家警察上诉")
sa_mag_btn = gr.Button("Appeal to Magistrate / Rayuan ke Majistret / 向地方法官上诉")
sa_output = gr.Textbox(label="Result / Keputusan / 结果")
sa_pdrm_btn.click(appeal_to_pdrm, [sa_ticket, sa_text], sa_output)
sa_mag_btn.click(appeal_to_magistrate, [sa_ticket, sa_text], sa_output)
with gr.Tab("View Appeal Status / Lihat Status Rayuan / 查看上诉状态"):
vas_ticket = gr.Textbox(label="Ticket Number / Nombor Saman / 传票号码")
vas_btn = gr.Button("Check / Semak / 检查")
vas_output = gr.Textbox(label="Appeal Status / Status Rayuan / 上诉状态", lines=5)
vas_btn.click(view_appeal_status, [vas_ticket], vas_output)
with gr.Tab("Pay Fine / Bayar Denda / 缴纳罚款"):
pf_ticket = gr.Textbox(label="Ticket Number / Nombor Saman / 传票号码")
pf_btn = gr.Button("Pay / Bayar / 支付")
pf_output = gr.Textbox(label="Result / Keputusan / 结果")
pf_btn.click(pay_fine, [pf_ticket], pf_output)
# -----------------------------
# Launch
# -----------------------------
init_db()
seed_mock_data()
with gr.Blocks() as demo:
gr.Markdown("## 🚦 SwiftCase.ai — Smart Traffic Justice Platform")
citizen_portal()
if __name__ == "__main__":
demo.launch()
|