ashutoshzade commited on
Commit
d98748e
·
verified ·
1 Parent(s): 1a5183f

Initial version

Browse files
Files changed (1) hide show
  1. app.py +183 -0
app.py ADDED
@@ -0,0 +1,183 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import os
3
+ import threading
4
+ from datetime import datetime, timedelta
5
+ from huggingface_hub import InferenceClient
6
+
7
+ ROWS = [chr(i) for i in range(ord("A"), ord("Z") + 1)]
8
+ SEATS_PER_ROW = 26
9
+ SECTIONS = {
10
+ "left": range(1, 9),
11
+ "middle": range(9, 19),
12
+ "right": range(19, 27),
13
+ }
14
+
15
+ lock = threading.Lock()
16
+
17
+ seat_state = {
18
+ row: {seat: "available" for seat in range(1, 27)}
19
+ for row in ROWS
20
+ }
21
+
22
+ holds = {}
23
+ bookings = {}
24
+ lock_owner = None
25
+ lock_expires_at = None
26
+
27
+ client = InferenceClient(
28
+ base_url="https://router.huggingface.co/v1",
29
+ token=os.getenv("HF_TOKEN")
30
+ )
31
+
32
+ def seat_label(row, seat):
33
+ return f"{row}{seat}"
34
+
35
+ def section_for_seat(seat):
36
+ if 1 <= seat <= 8:
37
+ return "left"
38
+ if 9 <= seat <= 18:
39
+ return "middle"
40
+ return "right"
41
+
42
+ def available_seats():
43
+ out = []
44
+ for row in ROWS:
45
+ for seat in range(1, 27):
46
+ if seat_state[row][seat] == "available":
47
+ out.append(seat_label(row, seat))
48
+ return out
49
+
50
+ def find_best_block(n):
51
+ for row in ROWS:
52
+ for section_name, seats in SECTIONS.items():
53
+ seats = list(seats)
54
+ free_runs = []
55
+ current = []
56
+ for s in seats:
57
+ if seat_state[row][s] == "available":
58
+ current.append(s)
59
+ else:
60
+ if current:
61
+ free_runs.append(current)
62
+ current = []
63
+ if current:
64
+ free_runs.append(current)
65
+
66
+ for run in free_runs:
67
+ if len(run) >= n:
68
+ return [seat_label(row, s) for s in run[:n]]
69
+ return None
70
+
71
+ def acquire_lock(user_id):
72
+ global lock_owner, lock_expires_at
73
+ now = datetime.utcnow()
74
+ if lock_owner and lock_expires_at and now < lock_expires_at and lock_owner != user_id:
75
+ return False, f"Locked by {lock_owner}"
76
+ lock_owner = user_id
77
+ lock_expires_at = now + timedelta(minutes=10)
78
+ return True, f"Lock granted to {user_id}"
79
+
80
+ def release_lock(user_id):
81
+ global lock_owner, lock_expires_at
82
+ if lock_owner == user_id:
83
+ lock_owner = None
84
+ lock_expires_at = None
85
+ return True
86
+ return False
87
+
88
+ def hold_seats(user_id, count):
89
+ with lock:
90
+ ok, msg = acquire_lock(user_id)
91
+ if not ok:
92
+ return msg, ""
93
+ seats = find_best_block(count)
94
+ if not seats:
95
+ return "Not enough adjacent seats available.", ""
96
+ hold_id = f"H{len(holds)+1}"
97
+ for seat in seats:
98
+ row = seat[0]
99
+ num = int(seat[1:])
100
+ seat_state[row][num] = "held"
101
+ holds[hold_id] = {
102
+ "user_id": user_id,
103
+ "seats": seats,
104
+ "expires_at": datetime.utcnow() + timedelta(minutes=5),
105
+ }
106
+ return f"Hold created: {hold_id}", ", ".join(seats)
107
+
108
+ def confirm_hold(user_id, hold_id):
109
+ with lock:
110
+ h = holds.get(hold_id)
111
+ if not h:
112
+ return "Hold not found."
113
+ if h["user_id"] != user_id:
114
+ return "You do not own this hold."
115
+ for seat in h["seats"]:
116
+ row = seat[0]
117
+ num = int(seat[1:])
118
+ seat_state[row][num] = "booked"
119
+ booking_id = f"B{len(bookings)+1}"
120
+ bookings[booking_id] = h
121
+ del holds[hold_id]
122
+ release_lock(user_id)
123
+ return f"Booked successfully: {booking_id}"
124
+
125
+ def chat_with_ai(message, history):
126
+ messages = [{"role": "system", "content": "You are a ticketing assistant that helps users book venue seats."}]
127
+ for item in history:
128
+ messages.append({"role": "user", "content": item[0]})
129
+ messages.append({"role": "assistant", "content": item[1]})
130
+ messages.append({"role": "user", "content": message})
131
+
132
+ if os.getenv("HF_TOKEN"):
133
+ resp = client.chat.completions.create(
134
+ model="meta-llama/Llama-3.1-8B-Instruct",
135
+ messages=messages,
136
+ max_tokens=200,
137
+ temperature=0.2,
138
+ )
139
+ return resp.choices[0].message.content
140
+
141
+ return "HF_TOKEN is not configured."
142
+
143
+ def render_map():
144
+ rows = []
145
+ for row in ROWS:
146
+ vals = []
147
+ for seat in range(1, 27):
148
+ status = seat_state[row][seat]
149
+ vals.append(f"{seat_label(row, seat)}:{status[0]}")
150
+ rows.append(" | ".join(vals))
151
+ return "\n".join(rows)
152
+
153
+ def ui_action(user_id, group_size):
154
+ hold_msg, seats = hold_seats(user_id, int(group_size))
155
+ return render_map(), hold_msg, seats
156
+
157
+ def confirm_action(user_id, hold_id):
158
+ return render_map(), confirm_hold(user_id, hold_id)
159
+
160
+ with gr.Blocks() as demo:
161
+ gr.Markdown("# Venue Ticketing System")
162
+
163
+ with gr.Row():
164
+ user_id = gr.Textbox(label="User ID", value="user1")
165
+ group_size = gr.Number(label="Seats needed", value=2, precision=0)
166
+
167
+ with gr.Row():
168
+ btn_hold = gr.Button("Hold Best Seats")
169
+ hold_id = gr.Textbox(label="Hold ID")
170
+ btn_confirm = gr.Button("Confirm Hold")
171
+
172
+ seat_map = gr.Textbox(label="Seat map", lines=18)
173
+ hold_result = gr.Textbox(label="Hold result")
174
+ booked_result = gr.Textbox(label="Booking result")
175
+ ai_chat = gr.ChatInterface(fn=chat_with_ai, type="messages", title="AI Assistant")
176
+
177
+ btn_hold.click(ui_action, inputs=[user_id, group_size], outputs=[seat_map, hold_result, hold_id])
178
+ btn_confirm.click(confirm_action, inputs=[user_id, hold_id], outputs=[seat_map, booked_result])
179
+
180
+ demo.load(render_map, outputs=seat_map)
181
+ demo.queue(default_concurrency_limit=1)
182
+
183
+ demo.launch()