bookManagement/libraryManager.py
knight f4f227b24d Implement Google Books API integration for book updates and enhance library management features
- Added a new endpoint in `index.js` to update book data using the Google Books API, allowing for real-time updates based on ISBN.
- Introduced a `rebuild_book_entries` function in `libraryManager.py` to facilitate user-driven updates of book entries from the Google Books API.
- Enhanced error handling and user prompts for better interaction during book updates.
- Updated `public/index.html` and `public/script.js` to improve the user interface and support new functionalities.
- Modified styles in `public/styles.css` to enhance the layout and usability of the checkout button and location prompt.
2024-12-12 10:32:20 -05:00

245 lines
11 KiB
Python

import requests
from rich.console import Console
from rich.prompt import Prompt
from rich.table import Table
from fuzzywuzzy import process
from requests.auth import HTTPBasicAuth
API_BASE_URL = "https://localhost:3000" # Replace with your actual API base URL
console = Console()
# Use environment variables or a secure method to store credentials
USERNAME = 'admin'
PASSWORD = 'library@123' # Replace with your actual password
def list_books():
response = requests.get(f"{API_BASE_URL}/api/books-with-images", verify=False)
if response.status_code == 200:
books = response.json()
table = Table(title="Books")
table.add_column("ISBN", justify="right", style="cyan", no_wrap=True)
table.add_column("Title", style="magenta")
table.add_column("Authors", style="green")
for book in books:
table.add_row(book['isbn'], book['title'], book['authors'])
console.print(table)
else:
console.print("Failed to fetch books.", style="bold red")
def add_book():
isbn = Prompt.ask("Enter ISBN")
title = Prompt.ask("Enter Title")
authors = Prompt.ask("Enter Authors")
data = {
"isbn": isbn,
"title": title,
"authors": authors
}
response = requests.post(
f"{API_BASE_URL}/store-book",
json=data,
verify=False,
auth=HTTPBasicAuth(USERNAME, PASSWORD)
)
if response.status_code == 200:
console.print("Book added successfully.", style="bold green")
else:
console.print("Failed to add book.", style="bold red")
def remove_book():
isbn = Prompt.ask("Enter ISBN of the book to remove")
response = requests.delete(
f"{API_BASE_URL}/book/{isbn}",
verify=False,
auth=HTTPBasicAuth(USERNAME, PASSWORD)
)
if response.status_code == 200:
console.print("Book removed successfully.", style="bold green")
else:
console.print("Failed to remove book.", style="bold red")
def change_book_status():
isbn = Prompt.ask("Enter ISBN of the book to change status")
status = Prompt.ask("Enter new status (e.g., Available, Checked Out)")
data = {"status": status}
response = requests.put(
f"{API_BASE_URL}/book/{isbn}",
json=data,
verify=False,
auth=HTTPBasicAuth(USERNAME, PASSWORD)
)
if response.status_code == 200:
console.print("Book status updated successfully.", style="bold green")
else:
console.print("Failed to update book status.", style="bold red")
def search_books():
query = Prompt.ask("Enter search query")
response = requests.get(f"{API_BASE_URL}/api/books-with-images", verify=False)
if response.status_code == 200:
books = response.json()
book_titles = [book['title'] for book in books]
matches = process.extract(query, book_titles, limit=5)
if matches:
table = Table(title="Search Results")
table.add_column("ISBN", justify="right", style="cyan", no_wrap=True)
table.add_column("Title", style="magenta")
table.add_column("Authors", style="green")
table.add_column("Score", justify="right", style="yellow")
for match in matches:
title, score = match
book = next(book for book in books if book['title'] == title)
table.add_row(book['isbn'], book['title'], book['authors'], str(score))
console.print(table)
else:
console.print("No matches found.", style="bold red")
else:
console.print("Failed to fetch books.", style="bold red")
def list_books_on_loan():
response = requests.get(f"{API_BASE_URL}/api/books-on-loan", verify=False)
if response.status_code == 200:
loans = response.json()
table = Table(title="Books on Loan")
table.add_column("ISBN", justify="right", style="cyan", no_wrap=True)
table.add_column("Title", style="magenta")
table.add_column("User Name", style="blue")
table.add_column("Checkout Date", style="green")
table.add_column("Return Date", style="yellow")
for loan in loans:
table.add_row(loan['isbn'], loan['title'], loan['name'], loan['checkout_date'], loan['return_date'])
console.print(table)
else:
console.print("Failed to fetch books on loan.", style="bold red")
def rebuild_book_entries():
isbn = Prompt.ask("Enter ISBN of the book to rebuild")
response = requests.get(f"{API_BASE_URL}/book/confirm/{isbn}", verify=False)
if response.status_code == 200:
book_data = response.json()
console.print("Current Book Data from Local Database:", style="bold blue")
console.print(f"Title: {book_data['data']['title']}")
console.print(f"Authors: {book_data['data']['authors']}")
console.print(f"Published Date: {book_data['data'].get('publishedDate', 'N/A')}")
console.print(f"Description: {book_data['data'].get('description', 'N/A')}")
# Allow the user to select fields to search with
console.print("\nSelect fields to search the Google Books API with:")
use_title = Prompt.ask("Use Title? (yes/no)", choices=["yes", "no"], default="yes") == "yes"
use_authors = Prompt.ask("Use Authors? (yes/no)", choices=["yes", "no"], default="yes") == "yes"
use_isbn = Prompt.ask("Use ISBN? (yes/no)", choices=["yes", "no"], default="yes") == "yes"
# Build search query based on selected fields
query_components = []
if use_title:
query_components.append(f'intitle:{book_data["data"]["title"]}')
if use_authors:
query_components.append(f'inauthor:{book_data["data"]["authors"]}')
if use_isbn:
query_components.append(f'isbn:{book_data["data"]["isbn"]}')
query = '+'.join(query_components)
# Query the Google Books API directly
google_response = requests.get(f"https://www.googleapis.com/books/v1/volumes?q={query}")
if google_response.status_code == 200:
google_data = google_response.json()
if google_data["totalItems"] > 0:
# Take the first result
volumes = google_data["items"]
console.print("\nMultiple volumes found. Please select one:")
for i, item in enumerate(volumes):
volume_info = item["volumeInfo"]
title = volume_info.get('title', 'N/A')
authors = ', '.join(volume_info.get('authors', []))
published_date = volume_info.get('publishedDate', 'N/A')
# Limit the length of the title and authors to 32 characters
if len(title) > 32:
title = title[:29] + '...'
if len(authors) > 32:
authors = authors[:29] + '...'
console.print(f"{i + 1}. Title: {title}, Authors: {authors}, Published Date: {published_date}")
selected_index = int(Prompt.ask("Enter the number of the volume you want to select")) - 1
volume_info = volumes[selected_index]["volumeInfo"]
console.print("\nBook Data Found from Google Books API:", style="bold green")
console.print(f"Title: {volume_info.get('title', 'N/A')}")
console.print(f"Authors: {', '.join(volume_info.get('authors', []))}")
console.print(f"Published Date: {volume_info.get('publishedDate', 'N/A')}")
console.print(f"Description: {volume_info.get('description', 'N/A')}")
# isbn (use 13, then 10 if 13 is not present) ISBN: [{'type': 'ISBN_10', 'identifier': '0521274559'}, {'type': 'ISBN_13', 'identifier': '9780521274555'}]
isbn = volume_info.get('industryIdentifiers', [])
isbn = next((identifier['identifier'] for identifier in isbn if identifier['type'] == 'ISBN_13'), None)
if not isbn:
isbn = next((identifier['identifier'] for identifier in isbn if identifier['type'] == 'ISBN_10'), None)
console.print(f"ISBN: {isbn}")
# Ask the user if they want to update the entry
update = Prompt.ask("Do you want to update this book entry? (yes/no)", choices=["yes", "no"], default="no")
if update == "yes":
data = {
"title": volume_info.get('title'),
"authors": ', '.join(volume_info.get('authors', [])),
"publishedDate": volume_info.get('publishedDate'),
"description": volume_info.get('description'),
"isbn": isbn
}
update_response = requests.put(
f"{API_BASE_URL}/book/{book_data['data']['isbn']}",
json=data,
verify=False,
auth=HTTPBasicAuth(USERNAME, PASSWORD)
)
if update_response.status_code == 200:
console.print("Book entry updated successfully.", style="bold green")
else:
console.print("Failed to update book entry.", style="bold red")
print(update_response.json())
print(update_response.status_code)
else:
console.print("No data found on Google Books API.", style="bold red")
else:
console.print("Failed to fetch data from Google Books API.", style="bold red")
else:
console.print("Book not found in local database.", style="bold red")
def main():
while True:
console.print("\n[bold]Admin Console[/bold]")
console.print("1. List Books")
console.print("2. Add Book")
console.print("3. Remove Book")
console.print("4. Change Book Status")
console.print("5. Search Books")
console.print("6. List Books on Loan")
console.print("7. Rebuild Book Entries")
console.print("8. Exit")
choice = Prompt.ask("Choose an option", choices=["1", "2", "3", "4", "5", "6", "7", "8"], default="8")
if choice == "1":
list_books()
elif choice == "2":
add_book()
elif choice == "3":
remove_book()
elif choice == "4":
change_book_status()
elif choice == "5":
search_books()
elif choice == "6":
list_books_on_loan()
elif choice == "7":
rebuild_book_entries()
elif choice == "8":
console.print("Exiting...", style="bold yellow")
break
if __name__ == "__main__":
main()