AjayCharit commited on
Commit
cd57ee5
Β·
verified Β·
1 Parent(s): a5444b8

Delete app.py

Browse files
Files changed (1) hide show
  1. app.py +0 -447
app.py DELETED
@@ -1,447 +0,0 @@
1
- import gradio as gr
2
- import os
3
- from datetime import datetime
4
- from supabase import create_client, Client
5
-
6
- # ============ SUPABASE CONFIGURATION ============
7
- SUPABASE_URL = os.getenv("SUPABASE_URL")
8
- SUPABASE_KEY = os.getenv("SUPABASE_KEY")
9
-
10
- if not SUPABASE_URL or not SUPABASE_KEY:
11
- raise ValueError("❌ SUPABASE_URL or SUPABASE_KEY not set in Space Secrets!")
12
-
13
- supabase: Client = create_client(SUPABASE_URL, SUPABASE_KEY)
14
-
15
- # ============ SUPABASE HELPER FUNCTIONS ============
16
- def fetch_books():
17
- """Fetch all books from Supabase"""
18
- try:
19
- res = supabase.table("books").select("*").execute()
20
- return res.data or []
21
- except Exception as e:
22
- print(f"Error fetching books: {e}")
23
- return []
24
-
25
- def fetch_borrows():
26
- """Fetch all active borrow records from Supabase"""
27
- try:
28
- res = supabase.table("borrows").select("*").execute()
29
- return res.data or []
30
- except Exception as e:
31
- print(f"Error fetching borrows: {e}")
32
- return []
33
-
34
- def fetch_history():
35
- """Fetch last 30 transactions from Supabase"""
36
- try:
37
- res = supabase.table("transactions").select("entry").order("created_at", desc=True).limit(30).execute()
38
- entries = [row["entry"] for row in (res.data or [])]
39
- return entries # Return in descending order (newest first)
40
- except Exception as e:
41
- print(f"Error fetching history: {e}")
42
- return []
43
-
44
- def book_titles():
45
- """Get list of book titles for dropdowns - ALWAYS FRESH FROM DB"""
46
- books = fetch_books()
47
- return [b["title"] for b in books]
48
-
49
- # ============ DASHBOARD FUNCTIONS ============
50
- def get_dashboard_stats():
51
- books = fetch_books()
52
- total_books = len(books)
53
- total_copies = sum(b["total"] for b in books)
54
- available_copies = sum(b["copies"] for b in books)
55
- borrowed_copies = total_copies - available_copies
56
-
57
- return f"""
58
- πŸ“Š **Library Dashboard**
59
-
60
- πŸ“– Total Books: **{total_books}**
61
- βœ… Available Copies: **{available_copies}**
62
- πŸ“€ Borrowed Copies: **{borrowed_copies}**
63
- πŸ“¦ Total Copies: **{total_copies}**
64
- """
65
-
66
- def get_library_table():
67
- rows = []
68
- for b in fetch_books():
69
- status = "βœ… Available" if b["copies"] > 0 else "❌ Out of Stock"
70
- rows.append([b["title"], b["author"], b["copies"], b["total"], status])
71
- return rows
72
-
73
- # ============ BROWSE FUNCTIONS ============
74
- def browse_books(search_query="", sort_by="Title"):
75
- books_list = []
76
- for b in fetch_books():
77
- if search_query.lower() in b["title"].lower() or search_query.lower() in b["author"].lower():
78
- books_list.append({
79
- "Title": b["title"],
80
- "Author": b["author"],
81
- "Available": b["copies"],
82
- "Total": b["total"],
83
- "Status": "βœ… Available" if b["copies"] > 0 else "❌ Out of Stock"
84
- })
85
-
86
- if sort_by == "Title":
87
- books_list.sort(key=lambda x: x["Title"])
88
- elif sort_by == "Author":
89
- books_list.sort(key=lambda x: x["Author"])
90
- elif sort_by == "Availability":
91
- books_list.sort(key=lambda x: x["Available"], reverse=True)
92
-
93
- return books_list
94
-
95
- # ============ BORROW FUNCTION ============
96
- def borrow_book(selected_book, num_copies, name, phone, address):
97
- if not selected_book or selected_book == "":
98
- return "❌ Please select a book first"
99
-
100
- if not name or not phone or not address:
101
- return "❌ Please fill in all personal details (Name, Phone, Address)"
102
-
103
- try:
104
- num_copies = int(num_copies) if num_copies else 1
105
- if num_copies < 1:
106
- return "❌ Number of copies must be at least 1"
107
- except Exception as e:
108
- return f"❌ Invalid number of copies: {e}"
109
-
110
- try:
111
- # Get book from database
112
- res = supabase.table("books").select("*").eq("title", selected_book).execute()
113
- books = res.data
114
- if not books:
115
- return "❌ Book not found in library"
116
-
117
- book = books[0]
118
- available = book["copies"]
119
-
120
- if available < num_copies:
121
- return f"πŸ˜” Sorry, only {available} copies available. You requested {num_copies}"
122
-
123
- # Update copies in database
124
- supabase.table("books").update(
125
- {"copies": available - num_copies}
126
- ).eq("id", book["id"]).execute()
127
-
128
- # Record borrow
129
- now = datetime.now().strftime('%Y-%m-%d %H:%M')
130
- supabase.table("borrows").insert({
131
- "book_title": selected_book,
132
- "name": name,
133
- "phone": phone,
134
- "address": address,
135
- "copies": num_copies,
136
- "date": now
137
- }).execute()
138
-
139
- # Add to transaction history
140
- entry = f"[{now}] BORROWED - Book: {selected_book} | Copies: {num_copies} | Borrower: {name} | Phone: {phone} | Address: {address}"
141
- supabase.table("transactions").insert({"entry": entry}).execute()
142
-
143
- return f"βœ… {name} successfully borrowed {num_copies} copy/copies of '{selected_book}'! Enjoy reading! πŸ“–"
144
-
145
- except Exception as e:
146
- return f"❌ Error processing borrow: {e}"
147
-
148
- # ============ RETURN FUNCTION ============
149
- def return_book(selected_book, returner_name):
150
- if not selected_book or selected_book == "":
151
- return "❌ Please select a book first"
152
-
153
- if not returner_name:
154
- return "❌ Please enter your name"
155
-
156
- try:
157
- # Find borrow record
158
- res = supabase.table("borrows").select("*") \
159
- .eq("book_title", selected_book) \
160
- .eq("name", returner_name).execute()
161
- records = res.data or []
162
-
163
- if not records:
164
- return f"❌ No record found for {returner_name} borrowing '{selected_book}'"
165
-
166
- record = records[0]
167
- copies = record["copies"]
168
-
169
- # Get book
170
- res = supabase.table("books").select("*").eq("title", selected_book).execute()
171
- books = res.data
172
- if not books:
173
- return "πŸ˜‘ This book doesn't belong to our library"
174
-
175
- book = books[0]
176
-
177
- # Update book copies
178
- supabase.table("books").update(
179
- {"copies": book["copies"] + copies}
180
- ).eq("id", book["id"]).execute()
181
-
182
- # Delete borrow record
183
- supabase.table("borrows").delete().eq("id", record["id"]).execute()
184
-
185
- # Add to transaction history
186
- now = datetime.now().strftime('%Y-%m-%d %H:%M')
187
- entry = f"[{now}] RETURNED - Book: {selected_book} | Copies: {copies} | Returner: {returner_name} | Phone: {record['phone']} | Address: {record['address']}"
188
- supabase.table("transactions").insert({"entry": entry}).execute()
189
-
190
- return f"βœ… Thank you {returner_name} for returning {copies} copy/copies of '{selected_book}'! 😊"
191
-
192
- except Exception as e:
193
- return f"❌ Error processing return: {e}"
194
-
195
- # ============ ADD BOOK FUNCTION ============
196
- def add_book(title, author, copies):
197
- if not title or not author or not copies:
198
- return "❌ Please fill all fields correctly"
199
-
200
- try:
201
- copies = int(copies)
202
- if copies < 1:
203
- return "❌ Number of copies must be at least 1"
204
-
205
- # Check if book exists
206
- res = supabase.table("books").select("id").eq("title", title).execute()
207
- if res.data:
208
- return f"❌ Book '{title}' already exists in the library"
209
-
210
- # Insert new book
211
- supabase.table("books").insert({
212
- "title": title,
213
- "author": author,
214
- "copies": copies,
215
- "total": copies
216
- }).execute()
217
-
218
- # Add to transaction history
219
- entry = f"[{datetime.now().strftime('%Y-%m-%d %H:%M')}] ADDED - Book: {title} by {author} ({copies} copies)"
220
- supabase.table("transactions").insert({"entry": entry}).execute()
221
-
222
- return f"βœ… '{title}' successfully added to library! πŸ“š"
223
-
224
- except Exception as e:
225
- return f"❌ Error adding book: {e}"
226
-
227
- # ============ HISTORY FUNCTION ============
228
- def get_history():
229
- rows = fetch_history()
230
- if not rows:
231
- return "No transactions yet."
232
- return "\n".join(rows)
233
-
234
- # ============ GET BORROWER DETAILS FUNCTION ============
235
- def get_borrower_details():
236
- records = fetch_borrows()
237
- if not records:
238
- return "No active borrowing records."
239
-
240
- details = "πŸ“‹ **Active Borrowing Records**\n\n"
241
- by_book = {}
242
- for r in records:
243
- by_book.setdefault(r["book_title"], []).append(r)
244
-
245
- for title, recs in by_book.items():
246
- details += f"**πŸ“– {title}**\n"
247
- for r in recs:
248
- details += f" β€’ Name: {r['name']}\n"
249
- details += f" β€’ Phone: {r['phone']}\n"
250
- details += f" β€’ Address: {r['address']}\n"
251
- details += f" β€’ Copies: {r['copies']}\n"
252
- details += f" β€’ Borrowed on: {r['date']}\n\n"
253
-
254
- return details
255
-
256
- # ============ GRADIO INTERFACE ============
257
- demo = gr.Blocks(title="πŸ“š Library Management System")
258
-
259
- with demo:
260
- gr.Markdown("# πŸ“š Library Management System")
261
- gr.Markdown("*Your Smart Library Management Solution (Powered by Supabase)*")
262
-
263
- # ===== TAB 1: DASHBOARD =====
264
- with gr.Tab("πŸ“Š Dashboard"):
265
- dashboard_output = gr.Markdown(get_dashboard_stats())
266
- gr.Markdown("### πŸ“– Book Collection")
267
-
268
- def update_dashboard():
269
- return get_dashboard_stats()
270
-
271
- def refresh_dashboard_table():
272
- return get_library_table()
273
-
274
- demo.load(update_dashboard, outputs=dashboard_output)
275
-
276
- library_table = gr.Dataframe(
277
- value=get_library_table(),
278
- headers=["Title", "Author", "Available", "Total", "Status"],
279
- interactive=False,
280
- label="πŸ“š Books in Library"
281
- )
282
-
283
- refresh_dashboard_btn = gr.Button("πŸ”„ Refresh Dashboard")
284
- refresh_dashboard_btn.click(update_dashboard, outputs=dashboard_output)
285
- refresh_dashboard_btn.click(refresh_dashboard_table, outputs=library_table)
286
-
287
- # ===== TAB 2: BROWSE BOOKS =====
288
- with gr.Tab("πŸ” Browse Books"):
289
- search_input = gr.Textbox(label="Search by title or author", placeholder="e.g., 'Atomic' or 'James Clear'")
290
- sort_dropdown = gr.Dropdown(
291
- choices=["Title", "Author", "Availability"],
292
- value="Title",
293
- label="Sort by"
294
- )
295
-
296
- browse_output = gr.Dataframe(
297
- headers=["Title", "Author", "Available", "Total", "Status"],
298
- interactive=False,
299
- label="πŸ”Ž Search Results"
300
- )
301
-
302
- def update_browse(search, sort):
303
- results = browse_books(search, sort)
304
- if results:
305
- return [[r["Title"], r["Author"], r["Available"], r["Total"], r["Status"]] for r in results]
306
- return []
307
-
308
- search_input.change(update_browse, inputs=[search_input, sort_dropdown], outputs=browse_output)
309
- sort_dropdown.change(update_browse, inputs=[search_input, sort_dropdown], outputs=browse_output)
310
-
311
- # ===== TAB 3: BORROW BOOK =====
312
- with gr.Tab("πŸ“€ Borrow Book"):
313
- gr.Markdown("### Borrow a book from the library")
314
-
315
- books_list = book_titles()
316
-
317
- with gr.Row():
318
- with gr.Column(scale=1):
319
- borrow_select = gr.Dropdown(
320
- choices=books_list if books_list else ["No books available"],
321
- value=books_list[0] if books_list else None,
322
- label="Select Book *",
323
- interactive=True
324
- )
325
-
326
- borrow_copies = gr.Slider(
327
- label="Number of Copies to Borrow *",
328
- minimum=1,
329
- maximum=10,
330
- step=1,
331
- value=1
332
- )
333
-
334
- with gr.Column(scale=1):
335
- borrower_name = gr.Textbox(
336
- label="Your Name *",
337
- placeholder="e.g., 'John Doe'"
338
- )
339
-
340
- borrower_phone = gr.Textbox(
341
- label="Your Phone Number *",
342
- placeholder="e.g., '9876543210'"
343
- )
344
-
345
- borrower_address = gr.Textbox(
346
- label="Your Address *",
347
- placeholder="e.g., '123 Main St, City'"
348
- )
349
-
350
- borrow_output = gr.Textbox(label="Result", interactive=False)
351
- borrow_btn = gr.Button("πŸ“– Borrow Books")
352
- refresh_borrow_btn = gr.Button("πŸ”„ Refresh Book List")
353
-
354
- borrow_btn.click(
355
- borrow_book,
356
- inputs=[borrow_select, borrow_copies, borrower_name, borrower_phone, borrower_address],
357
- outputs=borrow_output
358
- )
359
-
360
- def refresh_borrow_list():
361
- titles = book_titles()
362
- return gr.Dropdown.update(
363
- choices=titles if titles else ["No books available"],
364
- value=titles[0] if titles else None
365
- )
366
-
367
- refresh_borrow_btn.click(refresh_borrow_list, outputs=borrow_select)
368
-
369
- # ===== TAB 4: RETURN BOOK =====
370
- with gr.Tab("↩️ Return Book"):
371
- gr.Markdown("### Return a borrowed book")
372
-
373
- books_list = book_titles()
374
-
375
- with gr.Row():
376
- return_select = gr.Dropdown(
377
- choices=books_list if books_list else ["No books available"],
378
- value=books_list[0] if books_list else None,
379
- label="Select Book to Return *",
380
- interactive=True,
381
- scale=1
382
- )
383
-
384
- returner_name = gr.Textbox(
385
- label="Your Name (as per borrow record) *",
386
- placeholder="e.g., 'John Doe'",
387
- scale=1
388
- )
389
-
390
- return_output = gr.Textbox(label="Result", interactive=False)
391
- return_btn = gr.Button("↩️ Return This Book")
392
- refresh_return_btn = gr.Button("πŸ”„ Refresh Book List")
393
-
394
- return_btn.click(
395
- return_book,
396
- inputs=[return_select, returner_name],
397
- outputs=return_output
398
- )
399
-
400
- def refresh_return_list():
401
- titles = book_titles()
402
- return gr.Dropdown.update(
403
- choices=titles if titles else ["No books available"],
404
- value=titles[0] if titles else None
405
- )
406
-
407
- refresh_return_btn.click(refresh_return_list, outputs=return_select)
408
-
409
- # ===== TAB 5: ADD BOOK =====
410
- with gr.Tab("βž• Add Book"):
411
- gr.Markdown("### Add a new book to the library")
412
-
413
- with gr.Row():
414
- title_input = gr.Textbox(label="Book Title *", placeholder="e.g., 'The Alchemist'", scale=1)
415
- author_input = gr.Textbox(label="Author Name *", placeholder="e.g., 'Paulo Coelho'", scale=1)
416
-
417
- copies_input = gr.Slider(label="Number of Copies *", minimum=1, maximum=100, step=1, value=1)
418
-
419
- add_output = gr.Textbox(label="Result", interactive=False)
420
- add_btn = gr.Button("βž• Add Book to Library")
421
-
422
- add_btn.click(add_book, inputs=[title_input, author_input, copies_input], outputs=add_output)
423
-
424
- # ===== TAB 6: BORROWER DETAILS =====
425
- with gr.Tab("πŸ‘₯ Active Borrowers"):
426
- gr.Markdown("### Currently active borrowing records")
427
- borrower_details = gr.Markdown(get_borrower_details())
428
-
429
- refresh_borrowers_btn = gr.Button("πŸ”„ Refresh Records")
430
- refresh_borrowers_btn.click(get_borrower_details, outputs=borrower_details)
431
-
432
- # ===== TAB 7: HISTORY =====
433
- with gr.Tab("πŸ“œ Transaction History"):
434
- gr.Markdown("### All transactions (Borrow, Return, Add)")
435
- history_output = gr.Textbox(
436
- label="History",
437
- value=get_history(),
438
- interactive=False,
439
- lines=20
440
- )
441
-
442
- refresh_btn = gr.Button("πŸ”„ Refresh History")
443
- refresh_btn.click(get_history, outputs=history_output)
444
-
445
- # Launch the app
446
- if __name__ == "__main__":
447
- demo.launch()