import gradio as gr import os import threading from datetime import datetime, timedelta from huggingface_hub import InferenceClient ROWS = [chr(i) for i in range(ord("A"), ord("Z") + 1)] SEATS_PER_ROW = 26 SECTION_RANGES = { "left": range(1, 9), "middle": range(9, 19), "right": range(19, 27), } lock = threading.Lock() seat_state = {row: {seat: "available" for seat in range(1, 27)} for row in ROWS} holds = {} bookings = {} lock_owner = None lock_expires_at = None client = InferenceClient( base_url="https://router.huggingface.co/v1", token=os.getenv("HF_TOKEN") ) def seat_label(row, seat): return f"{row}{seat}" def section_for_seat(seat): if 1 <= seat <= 8: return "left" if 9 <= seat <= 18: return "middle" return "right" def render_map(): html = """
""" for row in ROWS: html += f'
{row}' for seat in range(1, 27): status = seat_state[row][seat] cls = "available" if status == "available" else "booked" if status == "booked" else "held" html += f'{seat}' if seat in (8, 18): html += '' html += "
" html += "
" return html def available_seats(): out = [] for row in ROWS: for seat in range(1, 27): if seat_state[row][seat] == "available": out.append(seat_label(row, seat)) return out def find_best_block(n): for row in ROWS: for section_name, seats in SECTION_RANGES.items(): seats = list(seats) run = [] for s in seats: if seat_state[row][s] == "available": run.append(s) if len(run) >= n: return [seat_label(row, x) for x in run[:n]] else: run = [] return None def acquire_lock(user_id): global lock_owner, lock_expires_at now = datetime.utcnow() if lock_owner and lock_expires_at and now < lock_expires_at and lock_owner != user_id: return False, f"Locked by {lock_owner}" lock_owner = user_id lock_expires_at = now + timedelta(minutes=10) return True, f"Lock granted to {user_id}" def release_lock(user_id): global lock_owner, lock_expires_at with lock: if lock_owner != user_id: return f"You do not own the lock." lock_owner = None lock_expires_at = None return "Lock released." def hold_seats(user_id, count): with lock: ok, msg = acquire_lock(user_id) if not ok: return render_map(), msg, "", "" seats = find_best_block(count) if not seats: return render_map(), "Not enough adjacent seats available.", "", "" hold_id = f"H{len(holds)+1}" for seat in seats: row = seat[0] num = int(seat[1:]) seat_state[row][num] = "held" holds[hold_id] = { "user_id": user_id, "seats": seats, "expires_at": datetime.utcnow() + timedelta(minutes=5), } return render_map(), f"Hold created: {hold_id}", hold_id, ", ".join(seats) def confirm_hold(user_id, hold_id): global lock_owner, lock_expires_at with lock: h = holds.get(hold_id) if not h: return render_map(), "Hold not found.", "" if h["user_id"] != user_id: return render_map(), "You do not own this hold.", "" for seat in h["seats"]: row = seat[0] num = int(seat[1:]) seat_state[row][num] = "booked" booking_id = f"B{len(bookings)+1}" bookings[booking_id] = h del holds[hold_id] lock_owner = None lock_expires_at = None return render_map(), f"Confirmed. Booking ID: {booking_id}. Seats: {', '.join(h['seats'])}", ", ".join(h["seats"]) def ai_chat(message, history): messages = [{"role": "system", "content": "You are a ticketing assistant for a venue seat booking app."}] for user_msg, bot_msg in history: messages.append({"role": "user", "content": user_msg}) messages.append({"role": "assistant", "content": bot_msg}) messages.append({"role": "user", "content": message}) if os.getenv("HF_TOKEN"): resp = client.chat.completions.create( model="meta-llama/Llama-3.1-8B-Instruct", messages=messages, max_tokens=200, temperature=0.2, ) return resp.choices[0].message.content return "HF_TOKEN is not configured." def hold_action(user_id, group_size): return hold_seats(user_id, int(group_size)) def confirm_action(user_id, hold_id): return confirm_hold(user_id, hold_id) def release_action(user_id): msg = release_lock(user_id) return render_map(), msg with gr.Blocks() as demo: gr.Markdown("# Venue Ticketing System") with gr.Row(): user_id = gr.Textbox(label="User ID", value="user1") group_size = gr.Number(label="Seats needed", value=2, precision=0) with gr.Row(): btn_hold = gr.Button("Hold Seats") btn_confirm = gr.Button("Confirm Booking") btn_release = gr.Button("Release Lock") with gr.Row(): hold_id = gr.Textbox(label="Hold ID") seats_text = gr.Textbox(label="Seats", interactive=False) status = gr.Textbox(label="Status", interactive=False) seat_map = gr.HTML(label="Seat Map") ai = gr.ChatInterface(fn=ai_chat, title="AI Assistant") btn_hold.click( hold_action, inputs=[user_id, group_size], outputs=[seat_map, status, hold_id, seats_text], ) btn_confirm.click( confirm_action, inputs=[user_id, hold_id], outputs=[seat_map, status, seats_text], ) btn_release.click( release_action, inputs=[user_id], outputs=[seat_map, status], ) demo.load(render_map, outputs=seat_map) demo.queue(default_concurrency_limit=1) demo.launch()