HirCoir commited on
Commit
24fe88b
·
verified ·
1 Parent(s): b165328

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +44 -47
app.py CHANGED
@@ -11,6 +11,7 @@ import markdown
11
  import threading
12
  from queue import Queue
13
  import time
 
14
 
15
  app = Flask(__name__)
16
 
@@ -54,52 +55,48 @@ def get_ollama_models(base_host=DEFAULT_BASE_HOST):
54
  except:
55
  return []
56
 
57
- def load_chat_history(chat_file):
58
  try:
59
- with open(os.path.join(chats_folder, chat_file), 'r', encoding='utf-8') as f:
60
  return json.load(f).get('messages', [])
61
  except:
62
  return []
63
 
64
- def save_chat(messages, chat_file=None):
65
  if not messages:
66
  return None
67
-
68
- if not chat_file:
69
- timestamp = datetime.now().strftime('%Y%m%d-%H%M%S')
70
- chat_file = f'chat-{timestamp}.json'
71
-
72
- filepath = os.path.join(chats_folder, chat_file)
73
  with open(filepath, 'w', encoding='utf-8') as f:
74
  json.dump({
75
  'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
76
  'messages': messages
77
  }, f, ensure_ascii=False, indent=2)
78
-
79
- return chat_file
80
 
81
  def remove_markdown(text):
82
  html_content = markdown.markdown(text)
83
  soup = BeautifulSoup(html_content, 'html.parser')
84
  return soup.get_text().strip()
85
-
86
  def convert_to_speech(text, model_name, remove_md=False):
87
  if model_name not in get_available_models():
88
  return None
89
-
90
  if remove_md:
91
  text = remove_markdown(text)
92
-
93
  random_name = ''.join(random.choices(string.ascii_letters + string.digits, k=8)) + '.wav'
94
  output_file = os.path.join(temp_audio_folder, random_name)
95
-
96
  # Clean old audio files
97
  for file in os.listdir(temp_audio_folder):
98
  if file.endswith('.wav'):
99
  os.remove(os.path.join(temp_audio_folder, file))
100
-
101
  model_path = os.path.join(model_folder, model_name + '.onnx')
102
-
103
  try:
104
  # Use the text directly in the command
105
  command = (
@@ -108,69 +105,69 @@ def convert_to_speech(text, model_name, remove_md=False):
108
  f'--length_scale {SETTINGS["length_scale"]} --noise_w {SETTINGS["noise_w"]} '
109
  f'--sentence_silence {SETTINGS["sentence_silence"]}'
110
  )
111
-
112
  # Pass the text as input to the command
113
  result = subprocess.run(command, input=text.encode('utf-8'), shell=True, check=True)
114
-
115
  if os.path.exists(output_file):
116
  return output_file
117
  except Exception as e:
118
  print(f"Error during text-to-speech conversion: {e}")
119
-
120
  return None
121
 
122
  def set_default_models():
123
  tts_models = get_available_models()
124
  ollama_models = get_ollama_models()
125
-
126
  default_tts_model = "RecomendacionesConMiau" if "RecomendacionesConMiau" in tts_models else None
127
  default_ollama_model = "llama3.2:1b" if "llama3.2:1b" in ollama_models else None
128
-
129
  return default_tts_model, default_ollama_model
130
 
131
  @app.route('/')
132
  def index():
133
  tts_models = get_available_models()
134
- chat_files = sorted([f for f in os.listdir(chats_folder) if f.endswith('.json')], reverse=True)
135
  default_tts_model, default_ollama_model = set_default_models()
136
- return render_template('index.html', tts_models=tts_models, chat_files=chat_files, default_tts_model=default_tts_model, default_ollama_model=default_ollama_model)
137
 
138
  @app.route('/api/list_ollama_models')
139
  def list_ollama_models():
140
  base_host = request.args.get('base_host', DEFAULT_BASE_HOST)
141
  return jsonify(models=get_ollama_models(base_host))
142
 
143
- @app.route('/api/load_chat/<chat_file>')
144
- def load_chat(chat_file):
145
- messages = load_chat_history(chat_file)
146
  return jsonify(messages=messages)
147
 
148
  @app.route('/api/update_message', methods=['POST'])
149
  def update_message():
150
  data = request.json
151
- chat_file = data.get('chat_file')
152
  message_index = data.get('message_index')
153
  new_content = data.get('content')
154
  is_user = data.get('is_user', False)
155
-
156
- if not chat_file or message_index is None or not new_content:
157
  return jsonify(error="Missing required parameters"), 400
158
-
159
- messages = load_chat_history(chat_file)
160
  if message_index >= len(messages):
161
  return jsonify(error="Invalid message index"), 400
162
-
163
  # Update the message content
164
  messages[message_index]['content'] = new_content
165
-
166
  # If it's a user message, regenerate all subsequent responses
167
  if is_user:
168
  # Keep messages up to and including the edited message
169
  messages = messages[:message_index + 1]
170
-
171
  # Save the updated chat
172
- save_chat(messages, chat_file)
173
-
174
  return jsonify(success=True, messages=messages)
175
 
176
  @app.route('/api/chat', methods=['POST'])
@@ -179,8 +176,8 @@ def chat():
179
  base_host = data.get('base_host', DEFAULT_BASE_HOST)
180
  model = data.get('model')
181
  messages = data.get('messages', [])
182
- chat_file = data.get('chat_file')
183
-
184
  def generate():
185
  queue = Queue()
186
  thread = threading.Thread(
@@ -188,7 +185,7 @@ def chat():
188
  args=(base_host, model, messages, queue)
189
  )
190
  thread.start()
191
-
192
  complete_response = ""
193
  while True:
194
  msg_type, content = queue.get()
@@ -201,10 +198,10 @@ def chat():
201
  elif msg_type == "done":
202
  # Save chat history
203
  messages.append({"role": "assistant", "content": complete_response})
204
- save_chat(messages, chat_file)
205
  yield f"data: {json.dumps({'done': complete_response})}\n\n"
206
  break
207
-
208
  return Response(stream_with_context(generate()), mimetype='text/event-stream')
209
 
210
  def stream_ollama_response(base_host, model, messages, queue):
@@ -214,7 +211,7 @@ def stream_ollama_response(base_host, model, messages, queue):
214
  "messages": messages,
215
  "stream": True
216
  }
217
-
218
  try:
219
  with requests.post(url, json=data, stream=True) as response:
220
  if response.status_code == 200:
@@ -241,14 +238,14 @@ def text_to_speech():
241
  text = data.get('text', '')
242
  model = data.get('model')
243
  remove_md = data.get('remove_markdown', False)
244
-
245
  if not text or not model:
246
  return jsonify(error="Missing text or model"), 400
247
-
248
  audio_file = convert_to_speech(text, model, remove_md)
249
  if not audio_file:
250
  return jsonify(error="Failed to convert text to speech"), 500
251
-
252
  return jsonify(audio_file=os.path.basename(audio_file))
253
 
254
  @app.route('/audio/<filename>')
@@ -256,4 +253,4 @@ def serve_audio(filename):
256
  return send_file(os.path.join(temp_audio_folder, filename))
257
 
258
  if __name__ == '__main__':
259
- app.run(debug=True, port=7860, host='0.0.0.0')
 
11
  import threading
12
  from queue import Queue
13
  import time
14
+ import uuid
15
 
16
  app = Flask(__name__)
17
 
 
55
  except:
56
  return []
57
 
58
+ def load_chat_history(session_id):
59
  try:
60
+ with open(os.path.join(chats_folder, f'{session_id}.json'), 'r', encoding='utf-8') as f:
61
  return json.load(f).get('messages', [])
62
  except:
63
  return []
64
 
65
+ def save_chat(session_id, messages):
66
  if not messages:
67
  return None
68
+
69
+ filepath = os.path.join(chats_folder, f'{session_id}.json')
 
 
 
 
70
  with open(filepath, 'w', encoding='utf-8') as f:
71
  json.dump({
72
  'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
73
  'messages': messages
74
  }, f, ensure_ascii=False, indent=2)
75
+
76
+ return session_id
77
 
78
  def remove_markdown(text):
79
  html_content = markdown.markdown(text)
80
  soup = BeautifulSoup(html_content, 'html.parser')
81
  return soup.get_text().strip()
82
+
83
  def convert_to_speech(text, model_name, remove_md=False):
84
  if model_name not in get_available_models():
85
  return None
86
+
87
  if remove_md:
88
  text = remove_markdown(text)
89
+
90
  random_name = ''.join(random.choices(string.ascii_letters + string.digits, k=8)) + '.wav'
91
  output_file = os.path.join(temp_audio_folder, random_name)
92
+
93
  # Clean old audio files
94
  for file in os.listdir(temp_audio_folder):
95
  if file.endswith('.wav'):
96
  os.remove(os.path.join(temp_audio_folder, file))
97
+
98
  model_path = os.path.join(model_folder, model_name + '.onnx')
99
+
100
  try:
101
  # Use the text directly in the command
102
  command = (
 
105
  f'--length_scale {SETTINGS["length_scale"]} --noise_w {SETTINGS["noise_w"]} '
106
  f'--sentence_silence {SETTINGS["sentence_silence"]}'
107
  )
108
+
109
  # Pass the text as input to the command
110
  result = subprocess.run(command, input=text.encode('utf-8'), shell=True, check=True)
111
+
112
  if os.path.exists(output_file):
113
  return output_file
114
  except Exception as e:
115
  print(f"Error during text-to-speech conversion: {e}")
116
+
117
  return None
118
 
119
  def set_default_models():
120
  tts_models = get_available_models()
121
  ollama_models = get_ollama_models()
122
+
123
  default_tts_model = "RecomendacionesConMiau" if "RecomendacionesConMiau" in tts_models else None
124
  default_ollama_model = "llama3.2:1b" if "llama3.2:1b" in ollama_models else None
125
+
126
  return default_tts_model, default_ollama_model
127
 
128
  @app.route('/')
129
  def index():
130
  tts_models = get_available_models()
131
+ session_id = str(uuid.uuid4())
132
  default_tts_model, default_ollama_model = set_default_models()
133
+ return render_template('index.html', tts_models=tts_models, session_id=session_id, default_tts_model=default_tts_model, default_ollama_model=default_ollama_model)
134
 
135
  @app.route('/api/list_ollama_models')
136
  def list_ollama_models():
137
  base_host = request.args.get('base_host', DEFAULT_BASE_HOST)
138
  return jsonify(models=get_ollama_models(base_host))
139
 
140
+ @app.route('/api/load_chat/<session_id>')
141
+ def load_chat(session_id):
142
+ messages = load_chat_history(session_id)
143
  return jsonify(messages=messages)
144
 
145
  @app.route('/api/update_message', methods=['POST'])
146
  def update_message():
147
  data = request.json
148
+ session_id = data.get('session_id')
149
  message_index = data.get('message_index')
150
  new_content = data.get('content')
151
  is_user = data.get('is_user', False)
152
+
153
+ if not session_id or message_index is None or not new_content:
154
  return jsonify(error="Missing required parameters"), 400
155
+
156
+ messages = load_chat_history(session_id)
157
  if message_index >= len(messages):
158
  return jsonify(error="Invalid message index"), 400
159
+
160
  # Update the message content
161
  messages[message_index]['content'] = new_content
162
+
163
  # If it's a user message, regenerate all subsequent responses
164
  if is_user:
165
  # Keep messages up to and including the edited message
166
  messages = messages[:message_index + 1]
167
+
168
  # Save the updated chat
169
+ save_chat(session_id, messages)
170
+
171
  return jsonify(success=True, messages=messages)
172
 
173
  @app.route('/api/chat', methods=['POST'])
 
176
  base_host = data.get('base_host', DEFAULT_BASE_HOST)
177
  model = data.get('model')
178
  messages = data.get('messages', [])
179
+ session_id = data.get('session_id')
180
+
181
  def generate():
182
  queue = Queue()
183
  thread = threading.Thread(
 
185
  args=(base_host, model, messages, queue)
186
  )
187
  thread.start()
188
+
189
  complete_response = ""
190
  while True:
191
  msg_type, content = queue.get()
 
198
  elif msg_type == "done":
199
  # Save chat history
200
  messages.append({"role": "assistant", "content": complete_response})
201
+ save_chat(session_id, messages)
202
  yield f"data: {json.dumps({'done': complete_response})}\n\n"
203
  break
204
+
205
  return Response(stream_with_context(generate()), mimetype='text/event-stream')
206
 
207
  def stream_ollama_response(base_host, model, messages, queue):
 
211
  "messages": messages,
212
  "stream": True
213
  }
214
+
215
  try:
216
  with requests.post(url, json=data, stream=True) as response:
217
  if response.status_code == 200:
 
238
  text = data.get('text', '')
239
  model = data.get('model')
240
  remove_md = data.get('remove_markdown', False)
241
+
242
  if not text or not model:
243
  return jsonify(error="Missing text or model"), 400
244
+
245
  audio_file = convert_to_speech(text, model, remove_md)
246
  if not audio_file:
247
  return jsonify(error="Failed to convert text to speech"), 500
248
+
249
  return jsonify(audio_file=os.path.basename(audio_file))
250
 
251
  @app.route('/audio/<filename>')
 
253
  return send_file(os.path.join(temp_audio_folder, filename))
254
 
255
  if __name__ == '__main__':
256
+ app.run(debug=True, port=7860, host='0.0.0.0')