Spaces:
Running
Running
import os | |
from pathlib import Path | |
from typing import List | |
import gradio as gr | |
from dotenv import load_dotenv | |
from langchain_community.document_loaders import PyPDFLoader | |
load_dotenv() | |
from src.builder import AudiobookBuilder | |
from src.config import logger, FILE_SIZE_MAX | |
def get_auth_params() -> List[tuple[str, str]]: | |
users = os.environ["AUTH_USERS"].split(",") | |
passwords = os.environ["AUTH_PASS"].split(",") | |
auth_list = [(u, passwords[0] if len(passwords) == 1 else p) for u, p in zip(users, passwords)] | |
return auth_list | |
def parse_pdf(file_path): | |
"""Parse the PDF file and return the text content.""" | |
loader = PyPDFLoader(file_path) | |
documents = loader.load() | |
return "\n".join([doc.page_content for doc in documents]) | |
def load_text_from_file(uploaded_file): | |
# Save the uploaded file temporarily to check its size | |
temp_file_path = uploaded_file.name | |
if os.path.getsize(temp_file_path) > FILE_SIZE_MAX * 1024 * 1024: | |
raise ValueError( | |
f"The uploaded file exceeds the size limit of {FILE_SIZE_MAX} MB." | |
) | |
if uploaded_file.name.endswith(".txt"): | |
with open(temp_file_path, "r", encoding="utf-8") as file: | |
text = file.read() | |
elif uploaded_file.name.endswith(".pdf"): | |
text = parse_pdf(temp_file_path) | |
else: | |
raise ValueError("Unsupported file type. Please upload a .txt or .pdf file.") | |
return text | |
async def respond(text: str, uploaded_file) -> tuple[Path | None, str]: | |
if uploaded_file is not None: | |
try: | |
text = load_text_from_file(uploaded_file=uploaded_file) | |
except Exception as e: | |
logger.exception(e) | |
return (None, str(e)) | |
builder = AudiobookBuilder() | |
audio_fp = await builder.run(text=text) | |
return audio_fp, "" | |
def refresh(): | |
return None, None, None # Reset audio output, error message, and uploaded file | |
with gr.Blocks(title="Audiobooks Generation") as ui: | |
gr.Markdown("# Audiobooks Generation") | |
with gr.Row(variant="panel"): | |
text_input = gr.Textbox(label="Enter the book text", lines=20) | |
# Add a file upload field for .txt and .pdf files | |
file_input = gr.File( | |
label="Upload a text file or PDF", file_types=[".txt", ".pdf"] | |
) | |
with gr.Row(variant="panel"): | |
audio_output = gr.Audio(label="Generated audio", type="filepath") | |
error_output = gr.Textbox( | |
label="Error Messages", interactive=False, visible=False | |
) # Initially hidden | |
submit_button = gr.Button("Submit") | |
submit_button.click( | |
fn=respond, | |
inputs=[text_input, file_input], # Include the uploaded file as an input | |
outputs=[ | |
audio_output, | |
error_output, | |
], # Include the audio output and error message output | |
) | |
refresh_button = gr.Button("Refresh") | |
refresh_button.click( | |
fn=refresh, | |
inputs=[], | |
outputs=[ | |
audio_output, | |
error_output, | |
file_input, | |
], # Reset audio output, error message, and uploaded file | |
) | |
# Hide error message dynamically when input is received | |
text_input.change( | |
fn=lambda _: gr.update(visible=False), # Hide the error field | |
inputs=[text_input], | |
outputs=error_output, | |
) | |
file_input.change( | |
fn=lambda _: gr.update(visible=False), # Hide the error field | |
inputs=[file_input], | |
outputs=error_output, | |
) | |
# To clear error field when refreshing | |
refresh_button.click( | |
fn=lambda _: gr.update(visible=False), # Hide the error field | |
inputs=[], | |
outputs=error_output, | |
) | |
ui.launch(auth=get_auth_params()) | |