| import gradio as gr |
| import pandas as pd |
| from datetime import datetime, date |
| from supabase import create_client, Client |
|
|
| class LibraryManagement: |
| def __init__(self): |
| """Initialize Supabase connection for library management""" |
| self.url = "https://bnjblzcqaumctpehgoid.supabase.co" |
| self.key = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImJuamJsemNxYXVtY3RwZWhnb2lkIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTgyOTA0OTQsImV4cCI6MjA3Mzg2NjQ5NH0.L4wPzuBj9dlSKpYxO1eDX-57KcP0mbNfN8stmTB-STM" |
| |
| try: |
| self.supabase: Client = create_client(self.url, self.key) |
| self.connection_status = "β
Connected to Library Database!" |
| except Exception as e: |
| self.supabase = None |
| self.connection_status = f"β Connection failed: {str(e)}" |
| |
| def get_all_members(self): |
| """Get all library members""" |
| try: |
| result = self.supabase.table("member").select("*").order("name").execute() |
| return pd.DataFrame(result.data) |
| except Exception as e: |
| return pd.DataFrame([{"Error": str(e)}]) |
| |
| def get_all_books(self): |
| """Get all books""" |
| try: |
| result = self.supabase.table("book").select("*").order("title").execute() |
| return pd.DataFrame(result.data) |
| except Exception as e: |
| return pd.DataFrame([{"Error": str(e)}]) |
| |
| def get_current_borrows(self): |
| """Get all current (unreturned) book borrows with member and book details""" |
| try: |
| |
| |
| |
| |
| borrows = self.supabase.table("borrow").select("*").is_("return_date", "null").execute() |
| |
| if not borrows.data: |
| return pd.DataFrame([{"Message": "No current borrows"}]) |
| |
| |
| members = self.supabase.table("member").select("*").execute() |
| books = self.supabase.table("book").select("*").execute() |
| |
| |
| member_dict = {m['id']: m for m in members.data} |
| book_dict = {b['id']: b for b in books.data} |
| |
| |
| result_data = [] |
| for borrow in borrows.data: |
| member = member_dict.get(borrow['member_id'], {}) |
| book = book_dict.get(borrow['book_id'], {}) |
| |
| result_data.append({ |
| 'borrow_id': borrow['id'], |
| 'member_name': member.get('name', 'Unknown'), |
| 'member_email': member.get('email', 'Unknown'), |
| 'book_title': book.get('title', 'Unknown'), |
| 'book_author': book.get('author', 'Unknown'), |
| 'borrow_date': borrow['borrow_date'] |
| }) |
| |
| return pd.DataFrame(result_data) |
| |
| except Exception as e: |
| return pd.DataFrame([{"Error": str(e)}]) |
| |
| def add_member(self, name: str, email: str): |
| """Add a new member""" |
| try: |
| if not name or not email: |
| return "β Name and email are required" |
| |
| data = {"name": name, "email": email} |
| result = self.supabase.table("member").insert(data).execute() |
| |
| if result.data: |
| return f"β
Successfully added member: {name}" |
| else: |
| return "β Failed to add member" |
| |
| except Exception as e: |
| if "duplicate key" in str(e): |
| return "β Email already exists" |
| return f"β Error: {str(e)}" |
| |
| def add_book(self, title: str, author: str, year: int): |
| """Add a new book""" |
| try: |
| if not title or not author: |
| return "β Title and author are required" |
| |
| if year < 0 or year > datetime.now().year + 1: |
| return "β Invalid year" |
| |
| data = {"title": title, "author": author, "year": year} |
| result = self.supabase.table("book").insert(data).execute() |
| |
| if result.data: |
| return f"β
Successfully added book: {title}" |
| else: |
| return "β Failed to add book" |
| |
| except Exception as e: |
| return f"β Error: {str(e)}" |
| |
| def borrow_book(self, member_id: int, book_id: int): |
| """Create a new borrow record""" |
| try: |
| if not member_id or not book_id: |
| return "β Please select both member and book" |
| |
| |
| existing = self.supabase.table("borrow").select("*").eq("book_id", book_id).is_("return_date", "null").execute() |
| |
| if existing.data: |
| return "β Book is already borrowed and not returned" |
| |
| data = { |
| "member_id": member_id, |
| "book_id": book_id, |
| "borrow_date": date.today().isoformat() |
| } |
| |
| result = self.supabase.table("borrow").insert(data).execute() |
| |
| if result.data: |
| return f"β
Book borrowed successfully!" |
| else: |
| return "β Failed to create borrow record" |
| |
| except Exception as e: |
| return f"β Error: {str(e)}" |
| |
| def return_book(self, borrow_id: int): |
| """Return a borrowed book""" |
| try: |
| if not borrow_id: |
| return "β Please select a borrow record" |
| |
| |
| data = {"return_date": date.today().isoformat()} |
| result = self.supabase.table("borrow").update(data).eq("id", borrow_id).execute() |
| |
| if result.data: |
| return f"β
Book returned successfully!" |
| else: |
| return "β Failed to return book" |
| |
| except Exception as e: |
| return f"β Error: {str(e)}" |
| |
| def get_member_choices(self): |
| """Get member choices for dropdown""" |
| try: |
| result = self.supabase.table("member").select("id, name").order("name").execute() |
| return [(f"{m['name']} (ID: {m['id']})", m['id']) for m in result.data] |
| except: |
| return [("No members found", 0)] |
| |
| def get_book_choices(self): |
| """Get book choices for dropdown""" |
| try: |
| result = self.supabase.table("book").select("id, title, author").order("title").execute() |
| return [(f"{b['title']} by {b['author']} (ID: {b['id']})", b['id']) for b in result.data] |
| except: |
| return [("No books found", 0)] |
| |
| def get_borrow_choices(self): |
| """Get active borrow choices for dropdown""" |
| try: |
| |
| borrows = self.supabase.table("borrow").select("*").is_("return_date", "null").execute() |
| |
| if not borrows.data: |
| return [("No active borrows", 0)] |
| |
| |
| members = self.supabase.table("member").select("*").execute() |
| books = self.supabase.table("book").select("*").execute() |
| |
| member_dict = {m['id']: m for m in members.data} |
| book_dict = {b['id']: b for b in books.data} |
| |
| choices = [] |
| for borrow in borrows.data: |
| member = member_dict.get(borrow['member_id'], {}) |
| book = book_dict.get(borrow['book_id'], {}) |
| |
| label = f"{member.get('name', 'Unknown')} - {book.get('title', 'Unknown')} (Borrow ID: {borrow['id']})" |
| choices.append((label, borrow['id'])) |
| |
| return choices |
| except: |
| return [("Error loading borrows", 0)] |
|
|
| |
| library = LibraryManagement() |
|
|
| |
| def refresh_members(): |
| return library.get_all_members() |
|
|
| def refresh_books(): |
| return library.get_all_books() |
|
|
| def refresh_borrows(): |
| return library.get_current_borrows() |
|
|
| def add_new_member(name, email): |
| status = library.add_member(name, email) |
| return status, library.get_all_members() |
|
|
| def add_new_book(title, author, year): |
| status = library.add_book(title, author, year) |
| return status, library.get_all_books() |
|
|
| def create_borrow(member_choice, book_choice): |
| member_id = member_choice if isinstance(member_choice, int) else 0 |
| book_id = book_choice if isinstance(book_choice, int) else 0 |
| status = library.borrow_book(member_id, book_id) |
| return status, library.get_current_borrows() |
|
|
| def process_return(borrow_choice): |
| borrow_id = borrow_choice if isinstance(borrow_choice, int) else 0 |
| status = library.return_book(borrow_id) |
| return status, library.get_current_borrows() |
|
|
| def refresh_member_dropdown(): |
| return gr.Dropdown(choices=library.get_member_choices()) |
|
|
| def refresh_book_dropdown(): |
| return gr.Dropdown(choices=library.get_book_choices()) |
|
|
| def refresh_borrow_dropdown(): |
| return gr.Dropdown(choices=library.get_borrow_choices()) |
|
|
| |
| with gr.Blocks(title="Library Management System", theme=gr.themes.Soft()) as app: |
| gr.Markdown("# π Library Management System") |
| gr.Markdown("Manage your library members, books, and borrowing records") |
| |
| |
| with gr.Row(): |
| gr.Markdown(f"**Status:** {library.connection_status}") |
| |
| with gr.Tabs(): |
| |
| with gr.Tab("π₯ Members"): |
| gr.Markdown("### Library Members") |
| |
| with gr.Row(): |
| refresh_members_btn = gr.Button("π Refresh Members", size="sm") |
| |
| members_table = gr.Dataframe(label="All Members", value=library.get_all_members()) |
| |
| gr.Markdown("---") |
| gr.Markdown("**Add New Member:**") |
| |
| with gr.Row(): |
| member_name = gr.Textbox(label="Name", placeholder="Enter member name") |
| member_email = gr.Textbox(label="Email", placeholder="Enter email address") |
| |
| add_member_btn = gr.Button("β Add Member", variant="primary") |
| member_status = gr.Textbox(label="Status", interactive=False) |
| |
| refresh_members_btn.click(refresh_members, outputs=members_table) |
| add_member_btn.click( |
| add_new_member, |
| inputs=[member_name, member_email], |
| outputs=[member_status, members_table] |
| ) |
| |
| |
| with gr.Tab("π Books"): |
| gr.Markdown("### Library Books") |
| |
| with gr.Row(): |
| refresh_books_btn = gr.Button("π Refresh Books", size="sm") |
| |
| books_table = gr.Dataframe(label="All Books", value=library.get_all_books()) |
| |
| gr.Markdown("---") |
| gr.Markdown("**Add New Book:**") |
| |
| with gr.Row(): |
| book_title = gr.Textbox(label="Title", placeholder="Enter book title") |
| book_author = gr.Textbox(label="Author", placeholder="Enter author name") |
| book_year = gr.Number(label="Year", value=2024, minimum=1900, maximum=2030) |
| |
| add_book_btn = gr.Button("β Add Book", variant="primary") |
| book_status = gr.Textbox(label="Status", interactive=False) |
| |
| refresh_books_btn.click(refresh_books, outputs=books_table) |
| add_book_btn.click( |
| add_new_book, |
| inputs=[book_title, book_author, book_year], |
| outputs=[book_status, books_table] |
| ) |
| |
| |
| with gr.Tab("π Borrowing"): |
| gr.Markdown("### Current Borrows") |
| |
| with gr.Row(): |
| refresh_borrows_btn = gr.Button("π Refresh Borrows", size="sm") |
| |
| borrows_table = gr.Dataframe(label="Current Borrows", value=library.get_current_borrows()) |
| |
| gr.Markdown("---") |
| gr.Markdown("**Borrow a Book:**") |
| |
| with gr.Row(): |
| member_dropdown = gr.Dropdown( |
| choices=library.get_member_choices(), |
| label="Select Member" |
| ) |
| book_dropdown = gr.Dropdown( |
| choices=library.get_book_choices(), |
| label="Select Book" |
| ) |
| refresh_dropdowns_btn = gr.Button("π", size="sm") |
| |
| borrow_btn = gr.Button("π Borrow Book", variant="primary") |
| borrow_status = gr.Textbox(label="Borrow Status", interactive=False) |
| |
| gr.Markdown("---") |
| gr.Markdown("**Return a Book:**") |
| |
| with gr.Row(): |
| borrow_dropdown = gr.Dropdown( |
| choices=library.get_borrow_choices(), |
| label="Select Borrow Record to Return" |
| ) |
| refresh_return_btn = gr.Button("π", size="sm") |
| |
| return_btn = gr.Button("β©οΈ Return Book", variant="secondary") |
| return_status = gr.Textbox(label="Return Status", interactive=False) |
| |
| |
| refresh_borrows_btn.click(refresh_borrows, outputs=borrows_table) |
| |
| refresh_dropdowns_btn.click( |
| lambda: [gr.Dropdown(choices=library.get_member_choices()), |
| gr.Dropdown(choices=library.get_book_choices())], |
| outputs=[member_dropdown, book_dropdown] |
| ) |
| |
| refresh_return_btn.click( |
| lambda: gr.Dropdown(choices=library.get_borrow_choices()), |
| outputs=borrow_dropdown |
| ) |
| |
| borrow_btn.click( |
| create_borrow, |
| inputs=[member_dropdown, book_dropdown], |
| outputs=[borrow_status, borrows_table] |
| ) |
| |
| return_btn.click( |
| process_return, |
| inputs=[borrow_dropdown], |
| outputs=[return_status, borrows_table] |
| ) |
| |
| |
| with gr.Tab("π Reports"): |
| gr.Markdown("### Library Reports") |
| |
| with gr.Row(): |
| gr.Markdown(""" |
| **Available Data:** |
| - Members: View and manage library members |
| - Books: Browse the book collection |
| - Current Borrows: See who has borrowed what |
| - Add/Return: Manage borrowing transactions |
| |
| **Database Tables:** |
| - `member`: Library members with contact info |
| - `book`: Book catalog with title, author, year |
| - `borrow`: Borrowing records with dates |
| """) |
| |
| gr.Markdown("---") |
| gr.Markdown("π‘ **Your Library Database is Ready!** Use the tabs above to manage members, books, and borrowing.") |
|
|
| |
| if __name__ == "__main__": |
| app.launch( |
| server_name="0.0.0.0", |
| server_port=7860, |
| share=False |
| ) |
|
|