File size: 5,612 Bytes
c769319
577cd8e
4a7d9b6
c769319
9c400ea
cfd61ed
577cd8e
cfd61ed
 
 
 
0789588
9c400ea
8d185df
cfd61ed
765c790
 
bfe61b1
9c400ea
 
a53b35a
4a7d9b6
 
 
 
 
 
 
 
 
 
40f31ac
b977317
cfd61ed
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b1d940d
 
cfd61ed
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c769319
 
 
 
b977317
 
 
 
 
c769319
 
 
 
 
 
 
 
 
b977317
 
 
 
c769319
cfd61ed
1febdfb
cfd61ed
 
1febdfb
9c400ea
cfd61ed
 
 
 
 
9c400ea
 
 
 
 
 
 
cfd61ed
 
 
1fa6a51
cfd61ed
c769319
 
 
 
cfd61ed
b977317
cfd61ed
bfbd9aa
b977317
 
bfbd9aa
b977317
cfd61ed
 
 
 
 
 
 
 
 
 
 
 
 
c769319
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
import gradio as gr
import os
import shutil
import subprocess
import threading
import time

# Function to process the ebook and start the subprocess
def process_ebook(ebook_file, state):
    if not ebook_file:
        return "No file uploaded.", state

    # Pre-download the xtts TOS agreed file
    import download_tos_agreed_file

    import nltk
    nltk.download('averaged_perceptron_tagger_eng')
    nltk.download('punkt_tab')

    # Download the en_core_web_sm spacy model
    subprocess.run(["python", "-m", "spacy", "download", "en_core_web_sm"])

    # Create input_files directory if it doesn't exist
    input_dir = "input_files"
    if not os.path.exists(input_dir):
        os.mkdir(input_dir)

    # Copy the uploaded file to input_files folder
    input_file_path = os.path.join(input_dir, os.path.basename(ebook_file))
    shutil.copy(ebook_file, input_file_path)

    # Print the name of the uploaded file
    ebook_file_name = os.path.basename(ebook_file)
    initial_output = f"Uploaded file: {ebook_file_name}\n"

    # Initialize state with subprocess info
    state = {
        "process": None,
        "output": initial_output,
        "lock": threading.Lock()
    }

    # Start the subprocess in a separate thread
    thread = threading.Thread(target=run_subprocess, args=(input_file_path, state), daemon=True)
    thread.start()

    return initial_output, state

# Function to run the subprocess and capture its output
def run_subprocess(input_file_path, state):
    try:
        # Start the subprocess
        process = subprocess.Popen(
            #["python3", "Auto_VoxNovel.py", input_file_path],
            ["python3", "Headless_VoxNovel.py", input_file_path],
            stdin=subprocess.PIPE,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
            text=True,
            bufsize=1  # Line-buffered
        )

        with state["lock"]:
            state["process"] = process

        # Continuously read the subprocess output
        for line in iter(process.stdout.readline, ''):
            with state["lock"]:
                state["output"] += line
        process.stdout.close()
        process.wait()
        with state["lock"]:
            state["output"] += "\nProcess finished."
    except Exception as e:
        with state["lock"]:
            state["output"] += f"\nError: {str(e)}"

# Function to send user input to the subprocess
def send_input(user_input, state):
    if not state or "process" not in state or state["process"] is None:
        return "Process is not running."

    process = state["process"]
    if process.poll() is not None:
        return "Process has already finished."

    try:
        # Send the input followed by a newline
        process.stdin.write(user_input + "\n")
        process.stdin.flush()
        return "Input sent successfully."
    except Exception as e:
        return f"Failed to send input: {str(e)}"

# Function to update the output display
def get_output(state):
    if not state:
        return "No process started."

    with state["lock"]:
        return state["output"]

# Function to list output files for downloading
def list_output_files():
    # List all files in the output directory for downloading
    output_dir = "output_audiobooks"
    if os.path.exists(output_dir):
        files = [
            os.path.join(output_dir, f)
            for f in os.listdir(output_dir)
            if os.path.isfile(os.path.join(output_dir, f))
        ]
        return files
    return []

# Gradio Interface
with gr.Blocks() as gui:
    gr.Markdown("### Ebook to Audiobook Converter")

    with gr.Row():
        with gr.Column():
            ebook_input = gr.File(
                label="Upload your ebook file (epub, pdf, etc.)",
                type='filepath'  # Specify that we want the file path
            )
            process_button = gr.Button("Start Processing")
            status_output = gr.Textbox(label="Status", lines=20)

            # Initialize state
            state = gr.State()

            # Start processing and update status in real-time
            process_button.click(
                process_ebook, 
                inputs=[ebook_input, state], 
                outputs=[status_output, state]
            )

        with gr.Column():
            gr.Markdown("### Subprocess Input")

            # Textbox to allow user to send input to subprocess
            user_input_box = gr.Textbox(label="Send Input to Subprocess")
            submit_input_button = gr.Button("Submit Input")
            submit_input_button.click(
                send_input, 
                inputs=[user_input_box, state], 
                outputs=status_output  # Corrected to pass the actual Gradio component
            )

        with gr.Column():
            gr.Markdown("### Download Generated Audiobook Files")
            download_button = gr.Button("Reload Files")
            file_output = gr.File(
                label="Generated Audiobook Files",
                file_count="multiple",
                type='filepath'  # Corrected the type to 'filepath'
            )


            # Update the file_output component with the list of output files
            download_button.click(fn=list_output_files, inputs=[], outputs=file_output)

    # Periodically update the status_output textbox
    def periodic_update(state):
        return get_output(state)

    # Use Gradio's `every` method to update every second
    gui.load(
        periodic_update, 
        inputs=state, 
        outputs=status_output, 
        every=1  # Update every second
    )

gui.launch()