HirCoir's picture
Update app.py
4ff87f9 verified
raw
history blame
4.52 kB
import logging
from flask import Flask, render_template, request, jsonify, after_this_request
from functools import wraps
from io import BytesIO
import base64
import subprocess
import os
import random
import string
import re
import sys
# Configuración del registro
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
app = Flask(__name__)
# Define el directorio donde se guardan los archivos
file_folder = getattr(sys, '_MEIPASS', os.path.abspath(os.path.dirname(__file__)))
temp_audio_folder = "/home/app/temp_audio/"
model_folder = "/home/app/"
piper_binary_path = "/home/app/piper"
# Define los nombres asignados a modelos específicos
model_names = {
"Español México | Claude": "es_MX-claude-14947-epoch-high.onnx",
"Español México | Cortana v1": "es_MX-cortana-19669-epoch-high.onnx",
"Español México | TheGevy": "es_MX-gevy-10196-epoch-high.onnx",
"English United States Example": "en_US-ljspeech-high.onnx"
}
def filter_text(text):
filtered_text = re.sub(r'[^\w\s,.\(\):\u00C0-\u00FF]', '', text) # Filtra caracteres no deseados
filtered_text = filtered_text.replace('\n', ' ') # Reemplaza saltos de línea con espacios
return filtered_text
def convert_text_to_speech(text, model):
filtered_text = filter_text(text)
random_name = ''.join(random.choices(string.ascii_letters + string.digits, k=8)) + '.wav'
output_file = os.path.join(temp_audio_folder, random_name)
if os.path.isfile(piper_binary_path) and model in model_names:
model_path = os.path.join(model_folder, model_names[model])
if os.path.isfile(model_path):
# Construye el comando para ejecutar Piper
command = f'echo "{filtered_text}" | "{piper_binary_path}" -m {model_path} -f {output_file}'
try:
subprocess.run(command, shell=True, check=True)
return output_file
except subprocess.CalledProcessError as e:
logging.error(f"Error al ejecutar el comando: {e}")
else:
logging.error(f"Modelo '{model}' no encontrado en la ubicación especificada.")
else:
logging.error(f"No se encontró el binario de Piper en la ubicación especificada o modelo no asignado.")
return None
# Define una función decoradora para restringir el acceso a la ruta /convert
def restrict_access(func):
@wraps(func)
def wrapper(*args, **kwargs):
# Verifica si la solicitud se hizo desde la página index.html
referer = request.headers.get("Referer")
if referer and referer.endswith("/"):
# Permite el acceso a la función si la solicitud proviene de la página index.html
return func(*args, **kwargs)
else:
# Devuelve un mensaje de error o redirecciona a otra página
return "Acceso no autorizado", 403 # Código de respuesta HTTP 403 - Forbidden
return wrapper
@app.route('/')
def index():
model_options = list(model_names.keys())
# Registra el contenido de la carpeta actual
logging.info("Contents of current folder: %s", os.listdir(file_folder))
return render_template('index.html', model_options=model_options)
@app.route('/convert', methods=['POST'])
@restrict_access
def convert_text():
try:
text = request.form['text']
model = request.form['model']
output_file = convert_text_to_speech(text, model)
@after_this_request
def remove_file(response):
try:
if output_file and os.path.exists(output_file):
os.remove(output_file)
logging.info("Audio file deleted: %s", output_file)
except Exception as error:
logging.error("Error deleting file: %s", error)
return response
if output_file:
with open(output_file, 'rb') as audio_file:
audio_content = audio_file.read()
audio_base64 = base64.b64encode(audio_content).decode('utf-8')
return jsonify({'audio_base64': audio_base64})
else:
return jsonify({'error': 'Error al convertir texto a voz'}), 500 # Internal Server Error
except Exception as e:
logging.error("Error processing request: %s", e)
return jsonify({'error': 'Error interno del servidor'}), 500 # Internal Server Error
if __name__ == '__main__':
logging.info("Se está iniciando la aplicación.")
app.run(host='0.0.0.0', port=7860, debug=False)