drewThomasson commited on
Commit
cfd61ed
1 Parent(s): 1d55c25

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +104 -65
app.py CHANGED
@@ -2,25 +2,23 @@ import gradio as gr
2
  import os
3
  import shutil
4
  import subprocess
5
- import pexpect
6
  import threading
 
7
 
8
- # Declare the global variable
9
- gradio_input_file = None
10
- process = None
 
11
 
12
- def process_ebook(ebook_file):
13
  # Pre-download the xtts TOS agreed file
14
  import download_tos_agreed_file
15
-
16
  import nltk
17
  nltk.download('averaged_perceptron_tagger_eng')
18
  nltk.download('punkt_tab')
19
 
20
  # Download the en_core_web_sm spacy model
21
  subprocess.run(["python", "-m", "spacy", "download", "en_core_web_sm"])
22
-
23
- global gradio_input_file # Use the global variable to store the ebook file path
24
 
25
  # Create input_files directory if it doesn't exist
26
  input_dir = "input_files"
@@ -31,45 +29,77 @@ def process_ebook(ebook_file):
31
  input_file_path = os.path.join(input_dir, os.path.basename(ebook_file))
32
  shutil.copy(ebook_file, input_file_path)
33
 
34
- # Set the file path to the global variable
35
- gradio_input_file = input_file_path
36
-
37
  # Print the name of the uploaded file
38
  ebook_file_name = os.path.basename(ebook_file)
39
- print(f"Uploaded file: {ebook_file_name}")
40
-
41
- # Initialize pexpect to run the subprocess and capture output
42
- return run_subprocess()
43
-
44
- def run_subprocess():
45
- global process
46
- output = []
47
-
48
- # Use pexpect to spawn the process and interact with it
49
- process = pexpect.spawn(f"python3 Auto_VoxNovel.py {gradio_input_file}", encoding='utf-8', timeout=None)
50
-
51
- def read_output():
52
- while True:
53
- try:
54
- line = process.readline().strip() # Read output from the subprocess
55
- if line: # If there's output, append it to the list
56
- output.append(line)
57
- yield "\n".join(output) # Yield current output to display
58
- except pexpect.EOF:
59
- break # End of file means the process has finished
60
-
61
- return read_output() # Call read_output() to return the actual generator
62
-
63
-
64
-
65
- def send_input(user_input):
66
- global process
67
- if process and process.isalive():
68
- process.sendline(user_input)
69
- return "Input sent!"
70
- else:
71
- return "Process is not running or already finished."
72
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  def list_output_files():
74
  # List all files in the output directory for downloading
75
  output_dir = "output_audiobooks"
@@ -93,21 +123,17 @@ with gr.Blocks() as gui:
93
  type='filepath' # Specify that we want the file path
94
  )
95
  process_button = gr.Button("Start Processing")
96
- status_output = gr.Textbox(label="Status")
97
-
98
- # Function to update status with subprocess output
99
- def update_status(ebook_input):
100
- output_generator = process_ebook(ebook_input) # Pass the file to process_ebook
101
-
102
- # Iterate through the generator and update status
103
- for output in output_generator:
104
- status_output.value = output
105
-
106
-
107
 
 
 
108
 
109
  # Start processing and update status in real-time
110
- process_button.click(update_status, inputs=ebook_input, outputs=status_output)
 
 
 
 
111
 
112
  with gr.Column():
113
  gr.Markdown("### Subprocess Input")
@@ -115,21 +141,34 @@ with gr.Blocks() as gui:
115
  # Textbox to allow user to send input to subprocess
116
  user_input_box = gr.Textbox(label="Send Input to Subprocess")
117
  submit_input_button = gr.Button("Submit Input")
118
- submit_input_button.click(send_input, inputs=user_input_box, outputs=status_output)
 
 
 
 
119
 
120
  with gr.Column():
121
  gr.Markdown("### Download Generated Audiobook Files")
122
  download_button = gr.Button("Reload Files")
123
- file_output = gr.Files(
124
  label="Generated Audiobook Files",
125
- type='filepath' # Use 'filepath' type for gr.Files component
 
126
  )
127
 
128
  # Update the file_output component with the list of output files
129
- def update_output_files():
130
- files = list_output_files()
131
- return files
132
-
133
- download_button.click(fn=update_output_files, inputs=[], outputs=file_output)
 
 
 
 
 
 
 
 
134
 
135
  gui.launch()
 
2
  import os
3
  import shutil
4
  import subprocess
 
5
  import threading
6
+ import time
7
 
8
+ # Function to process the ebook and start the subprocess
9
+ def process_ebook(ebook_file, state):
10
+ if not ebook_file:
11
+ return "No file uploaded.", state
12
 
 
13
  # Pre-download the xtts TOS agreed file
14
  import download_tos_agreed_file
15
+
16
  import nltk
17
  nltk.download('averaged_perceptron_tagger_eng')
18
  nltk.download('punkt_tab')
19
 
20
  # Download the en_core_web_sm spacy model
21
  subprocess.run(["python", "-m", "spacy", "download", "en_core_web_sm"])
 
 
22
 
23
  # Create input_files directory if it doesn't exist
24
  input_dir = "input_files"
 
29
  input_file_path = os.path.join(input_dir, os.path.basename(ebook_file))
30
  shutil.copy(ebook_file, input_file_path)
31
 
 
 
 
32
  # Print the name of the uploaded file
33
  ebook_file_name = os.path.basename(ebook_file)
34
+ initial_output = f"Uploaded file: {ebook_file_name}\n"
35
+
36
+ # Initialize state with subprocess info
37
+ state = {
38
+ "process": None,
39
+ "output": initial_output,
40
+ "lock": threading.Lock()
41
+ }
42
+
43
+ # Start the subprocess in a separate thread
44
+ thread = threading.Thread(target=run_subprocess, args=(input_file_path, state), daemon=True)
45
+ thread.start()
46
+
47
+ return initial_output, state
48
+
49
+ # Function to run the subprocess and capture its output
50
+ def run_subprocess(input_file_path, state):
51
+ try:
52
+ # Start the subprocess
53
+ process = subprocess.Popen(
54
+ ["python3", "Auto_VoxNovel.py", input_file_path],
55
+ stdin=subprocess.PIPE,
56
+ stdout=subprocess.PIPE,
57
+ stderr=subprocess.STDOUT,
58
+ text=True,
59
+ bufsize=1 # Line-buffered
60
+ )
61
+
62
+ with state["lock"]:
63
+ state["process"] = process
64
+
65
+ # Continuously read the subprocess output
66
+ for line in iter(process.stdout.readline, ''):
67
+ with state["lock"]:
68
+ state["output"] += line
69
+ process.stdout.close()
70
+ process.wait()
71
+ with state["lock"]:
72
+ state["output"] += "\nProcess finished."
73
+ except Exception as e:
74
+ with state["lock"]:
75
+ state["output"] += f"\nError: {str(e)}"
76
+
77
+ # Function to send user input to the subprocess
78
+ def send_input(user_input, state):
79
+ if not state or "process" not in state or state["process"] is None:
80
+ return "Process is not running."
81
+
82
+ process = state["process"]
83
+ if process.poll() is not None:
84
+ return "Process has already finished."
85
+
86
+ try:
87
+ # Send the input followed by a newline
88
+ process.stdin.write(user_input + "\n")
89
+ process.stdin.flush()
90
+ return "Input sent successfully."
91
+ except Exception as e:
92
+ return f"Failed to send input: {str(e)}"
93
+
94
+ # Function to update the output display
95
+ def get_output(state):
96
+ if not state:
97
+ return "No process started."
98
+
99
+ with state["lock"]:
100
+ return state["output"]
101
+
102
+ # Function to list output files for downloading
103
  def list_output_files():
104
  # List all files in the output directory for downloading
105
  output_dir = "output_audiobooks"
 
123
  type='filepath' # Specify that we want the file path
124
  )
125
  process_button = gr.Button("Start Processing")
126
+ status_output = gr.Textbox(label="Status", lines=20)
 
 
 
 
 
 
 
 
 
 
127
 
128
+ # Initialize state
129
+ state = gr.State()
130
 
131
  # Start processing and update status in real-time
132
+ process_button.click(
133
+ process_ebook,
134
+ inputs=[ebook_input, state],
135
+ outputs=[status_output, state]
136
+ )
137
 
138
  with gr.Column():
139
  gr.Markdown("### Subprocess Input")
 
141
  # Textbox to allow user to send input to subprocess
142
  user_input_box = gr.Textbox(label="Send Input to Subprocess")
143
  submit_input_button = gr.Button("Submit Input")
144
+ submit_input_button.click(
145
+ send_input,
146
+ inputs=[user_input_box, state],
147
+ outputs="status_output" # Optionally, you can have a separate output
148
+ )
149
 
150
  with gr.Column():
151
  gr.Markdown("### Download Generated Audiobook Files")
152
  download_button = gr.Button("Reload Files")
153
+ file_output = gr.File(
154
  label="Generated Audiobook Files",
155
+ file_count="multiple",
156
+ type='file' # Use 'file' type for gr.File component
157
  )
158
 
159
  # Update the file_output component with the list of output files
160
+ download_button.click(fn=list_output_files, inputs=[], outputs=file_output)
161
+
162
+ # Periodically update the status_output textbox
163
+ def periodic_update(state):
164
+ return get_output(state)
165
+
166
+ # Use Gradio's `every` method to update every second
167
+ gui.load(
168
+ periodic_update,
169
+ inputs=state,
170
+ outputs=status_output,
171
+ every=1 # Update every second
172
+ )
173
 
174
  gui.launch()