|
|
|
|
@ -26,14 +26,50 @@ django.setup()
|
|
|
|
|
|
|
|
|
|
# Helper function to make safe filenames
|
|
|
|
|
def get_safe_filename(name):
|
|
|
|
|
"""
|
|
|
|
|
Generate a safe filename by replacing unsafe characters with underscores.
|
|
|
|
|
|
|
|
|
|
This function takes a string `name` and replaces any character that is not
|
|
|
|
|
a letter (a-z, A-Z), digit (0-9), underscore (_), or hyphen (-) with an
|
|
|
|
|
underscore (_). It also strips any leading or trailing whitespace from the
|
|
|
|
|
resulting string.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
name (str): The original filename string.
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
str: A safe filename string with unsafe characters replaced by underscores.
|
|
|
|
|
"""
|
|
|
|
|
return re.sub(r'[^a-zA-Z0-9_-]', '_', name).strip()
|
|
|
|
|
|
|
|
|
|
# Vista para renderizar la página principal
|
|
|
|
|
def create_tabs_flow(request):
|
|
|
|
|
"""
|
|
|
|
|
Handles the creation of tabs flow view.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
request (HttpRequest): The HTTP request object.
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
HttpResponse: The rendered 'flow.html' template.
|
|
|
|
|
"""
|
|
|
|
|
return render(request, 'flow.html')
|
|
|
|
|
|
|
|
|
|
# Vista para listar todas las pestañas existentes
|
|
|
|
|
def list_tabs(request):
|
|
|
|
|
"""
|
|
|
|
|
List all tabs by reading JSON files from the data directory.
|
|
|
|
|
|
|
|
|
|
This function searches for files in the 'flow/data' directory that match the pattern 'tab_<id>_<name>.json'.
|
|
|
|
|
It extracts the tab ID and tab name from the filename and reads the 'tabName' from the JSON content.
|
|
|
|
|
If 'tabName' is not present in the JSON content, it defaults to 'Pestaña <id>'.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
request: The HTTP request object.
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
JsonResponse: A JSON response containing a list of tabs with their names and IDs.
|
|
|
|
|
"""
|
|
|
|
|
data_dir = os.path.join(settings.BASE_DIR, 'flow', 'data')
|
|
|
|
|
tabs = []
|
|
|
|
|
|
|
|
|
|
@ -58,6 +94,24 @@ def list_tabs(request):
|
|
|
|
|
# Función para crear y guardar archivos de texto desde el contenido del node3
|
|
|
|
|
@csrf_exempt
|
|
|
|
|
def save_tts(request):
|
|
|
|
|
"""
|
|
|
|
|
Handles the saving of Text-to-Speech (TTS) data from a POST request and generates a Python AGI script for Asterisk.
|
|
|
|
|
Args:
|
|
|
|
|
request (HttpRequest): The HTTP request object containing the TTS data in JSON format.
|
|
|
|
|
Returns:
|
|
|
|
|
JsonResponse: A JSON response indicating the success or failure of the operation.
|
|
|
|
|
The function performs the following steps:
|
|
|
|
|
1. Checks if the request method is POST. If not, returns an error response.
|
|
|
|
|
2. Parses the JSON data from the request body.
|
|
|
|
|
3. Extracts necessary fields such as tabId, tabName, nodeId, nodeType, title, content, and audioFile.
|
|
|
|
|
4. Formats the audio file name based on nodeId and title.
|
|
|
|
|
5. Constructs the file path for the Python AGI script.
|
|
|
|
|
6. Generates the content of the AGI script, including functions for handling calls, recording audio, detecting audio, and consulting Claude.
|
|
|
|
|
7. Writes the generated script to the specified file path.
|
|
|
|
|
8. Sets the appropriate file permissions and ownership.
|
|
|
|
|
9. Returns a success response with the file path if the operation is successful.
|
|
|
|
|
10. Returns an error response if any exceptions occur during the process.
|
|
|
|
|
"""
|
|
|
|
|
if request.method != 'POST':
|
|
|
|
|
return JsonResponse({'status': 'error', 'message': 'Solo se permiten solicitudes POST'}, status=405)
|
|
|
|
|
|
|
|
|
|
@ -293,6 +347,28 @@ if __name__ == "__main__":
|
|
|
|
|
# Vista para guardar datos de la pestaña
|
|
|
|
|
@csrf_exempt
|
|
|
|
|
def save_tab_data(request):
|
|
|
|
|
"""
|
|
|
|
|
Guarda los datos de una pestaña en un archivo JSON y extrae condiciones específicas para guardarlas en otro archivo JSON.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
request (HttpRequest): La solicitud HTTP que contiene los datos de la pestaña.
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
JsonResponse: Una respuesta JSON indicando el éxito o el error de la operación.
|
|
|
|
|
|
|
|
|
|
Raises:
|
|
|
|
|
JsonResponse: Si ocurre un error durante el procesamiento de los datos.
|
|
|
|
|
|
|
|
|
|
El cuerpo de la solicitud debe contener un JSON con los siguientes campos:
|
|
|
|
|
- tabId (str): El ID de la pestaña.
|
|
|
|
|
- tabName (str): El nombre de la pestaña.
|
|
|
|
|
- nodes (list): Una lista de nodos que pertenecen a la pestaña.
|
|
|
|
|
- connections (list): Una lista de conexiones entre los nodos.
|
|
|
|
|
|
|
|
|
|
El archivo JSON se guarda en la ruta: <settings.BASE_DIR>/flow/data/tab_<tabId>_<safe_tab_name>.json
|
|
|
|
|
|
|
|
|
|
Además, se extraen las condiciones de los nodos de tipo 'node3' y se guardan en otro archivo JSON en la ruta: /home/Flow_IA/IVR/tab_<tabId>_conditions.json
|
|
|
|
|
"""
|
|
|
|
|
if request.method != 'POST':
|
|
|
|
|
return JsonResponse({'error': 'Solo se permiten solicitudes POST'}, status=405)
|
|
|
|
|
|
|
|
|
|
@ -449,6 +525,31 @@ def save_tab_data(request):
|
|
|
|
|
|
|
|
|
|
# Vista para cargar los datos de una pestaña específica
|
|
|
|
|
def load_tab_data(request, tab_id):
|
|
|
|
|
"""
|
|
|
|
|
Load data for a specific tab from a JSON file.
|
|
|
|
|
|
|
|
|
|
This function searches for a JSON file corresponding to the given tab_id
|
|
|
|
|
in the 'flow/data' directory. If found, it loads the data from the file,
|
|
|
|
|
ensures that nodes of type 'node1', 'node3', and 'node4' do not have an
|
|
|
|
|
'audioFile' attribute, and returns the data as a JSON response. If no
|
|
|
|
|
matching file is found, it returns a default response with an empty list
|
|
|
|
|
of nodes and connections, and a tab name based on the tab_id.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
request (HttpRequest): The HTTP request object.
|
|
|
|
|
tab_id (int): The ID of the tab to load data for.
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
JsonResponse: A JSON response containing the tab data or an error message.
|
|
|
|
|
|
|
|
|
|
Raises:
|
|
|
|
|
Exception: If an error occurs while loading the data.
|
|
|
|
|
|
|
|
|
|
Notes:
|
|
|
|
|
- For nodes of type 'node4', there is no 'receivedString' attribute,
|
|
|
|
|
but there is an 'extensionNumber' attribute that should be handled
|
|
|
|
|
correctly.
|
|
|
|
|
"""
|
|
|
|
|
try:
|
|
|
|
|
data_dir = os.path.join(settings.BASE_DIR, 'flow', 'data')
|
|
|
|
|
# Buscar el archivo JSON correspondiente a la tab_id
|
|
|
|
|
@ -477,6 +578,27 @@ def load_tab_data(request, tab_id):
|
|
|
|
|
# Nueva Vista para eliminar archivos de Node3 cuando se actualiza
|
|
|
|
|
@csrf_exempt
|
|
|
|
|
def delete_files(request):
|
|
|
|
|
"""
|
|
|
|
|
Handle the deletion of text files associated with a specific node in a tab.
|
|
|
|
|
|
|
|
|
|
This view function processes POST requests to delete text files based on the provided
|
|
|
|
|
tab ID, node ID, node type, and old title. It only processes nodes of type "node3".
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
request (HttpRequest): The HTTP request object containing the request data.
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
JsonResponse: A JSON response indicating the success or failure of the file deletion
|
|
|
|
|
operation. Possible status codes are:
|
|
|
|
|
- 200: Node type does not have files to delete.
|
|
|
|
|
- 400: Incomplete data provided.
|
|
|
|
|
- 405: Request method is not POST.
|
|
|
|
|
- 500: An internal server error occurred.
|
|
|
|
|
|
|
|
|
|
Raises:
|
|
|
|
|
Exception: If any error occurs during the file deletion process, it is caught and
|
|
|
|
|
returned in the JSON response.
|
|
|
|
|
"""
|
|
|
|
|
if request.method != 'POST':
|
|
|
|
|
return JsonResponse({'status': 'error', 'message': 'Solo se permiten solicitudes POST'}, status=405)
|
|
|
|
|
|
|
|
|
|
@ -516,6 +638,29 @@ def delete_files(request):
|
|
|
|
|
# Vista para subir audio para Node2
|
|
|
|
|
@csrf_exempt
|
|
|
|
|
def upload_audio(request):
|
|
|
|
|
"""
|
|
|
|
|
Handles the upload of an audio file via a POST request.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
request (HttpRequest): The HTTP request object containing POST data and files.
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
JsonResponse: A JSON response indicating the success or failure of the upload process.
|
|
|
|
|
|
|
|
|
|
The function performs the following steps:
|
|
|
|
|
1. Checks if the request method is POST. If not, returns a 405 error.
|
|
|
|
|
2. Extracts 'tabId', 'nodeId', 'nodeType', 'title', and 'audioFile' from the POST data.
|
|
|
|
|
3. Validates that all required data is present. If not, returns a 400 error.
|
|
|
|
|
4. Ensures the 'nodeType' is 'node2'. If not, returns a 400 error.
|
|
|
|
|
5. Creates necessary directories for storing the audio file.
|
|
|
|
|
6. Generates a unique filename for the audio file using 'title', 'nodeType', and 'nodeId'.
|
|
|
|
|
7. Saves the uploaded audio file to the specified directory.
|
|
|
|
|
8. Copies the saved audio file to the Asterisk recordings directory.
|
|
|
|
|
9. Generates a URL for the saved audio file.
|
|
|
|
|
10. Returns a JSON response with the URL of the saved audio file and the path in the Asterisk directory.
|
|
|
|
|
|
|
|
|
|
If any exception occurs during the process, returns a 500 error with the exception message.
|
|
|
|
|
"""
|
|
|
|
|
if request.method != 'POST':
|
|
|
|
|
return JsonResponse({'status': 'error', 'message': 'Solo se permiten solicitudes POST'}, status=405)
|
|
|
|
|
|
|
|
|
|
@ -571,6 +716,31 @@ def upload_audio(request):
|
|
|
|
|
# Vista para eliminar audio de Node2 y Node6
|
|
|
|
|
@csrf_exempt
|
|
|
|
|
def delete_audio(request):
|
|
|
|
|
"""
|
|
|
|
|
Handle the deletion of an audio file based on the provided request.
|
|
|
|
|
|
|
|
|
|
This view function processes POST requests to delete an audio file associated with a specific node type.
|
|
|
|
|
It only processes requests for nodes of type "node2" or "node6".
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
request (HttpRequest): The HTTP request object containing the request data.
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
JsonResponse: A JSON response indicating the success or failure of the operation.
|
|
|
|
|
|
|
|
|
|
The request body should contain the following JSON fields:
|
|
|
|
|
- tabId (str): The ID of the tab.
|
|
|
|
|
- nodeId (str): The ID of the node.
|
|
|
|
|
- nodeType (str): The type of the node (must be "node2" or "node6").
|
|
|
|
|
- oldAudioFile (str): The path to the old audio file to be deleted.
|
|
|
|
|
|
|
|
|
|
Possible JSON responses:
|
|
|
|
|
- {'status': 'error', 'message': 'Solo se permiten solicitudes POST'} (HTTP 405)
|
|
|
|
|
- {'status': 'error', 'message': 'Datos incompletos'} (HTTP 400)
|
|
|
|
|
- {'status': 'error', 'message': 'Este endpoint solo es para node2 o node6'} (HTTP 400)
|
|
|
|
|
- {'status': 'success', 'message': 'Archivo de audio eliminado correctamente'} (HTTP 200)
|
|
|
|
|
- {'status': 'error', 'message': str(e)} (HTTP 500)
|
|
|
|
|
"""
|
|
|
|
|
if request.method != 'POST':
|
|
|
|
|
return JsonResponse({'status': 'error', 'message': 'Solo se permiten solicitudes POST'}, status=405)
|
|
|
|
|
|
|
|
|
|
@ -602,6 +772,35 @@ def delete_audio(request):
|
|
|
|
|
# Vista para renombrar audio de Node2 y Node6
|
|
|
|
|
@csrf_exempt
|
|
|
|
|
def rename_audio(request):
|
|
|
|
|
"""
|
|
|
|
|
Renames the audio file associated with node2 or node6.
|
|
|
|
|
|
|
|
|
|
This view handles POST requests to rename an audio file based on the provided data.
|
|
|
|
|
It processes the request only if the node type is either "node2" or "node6".
|
|
|
|
|
The renamed file is also copied to the Asterisk directory.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
request (HttpRequest): The HTTP request object containing the POST data.
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
JsonResponse: A JSON response indicating the success or failure of the operation.
|
|
|
|
|
|
|
|
|
|
POST Data:
|
|
|
|
|
- tabId (str): The ID of the tab.
|
|
|
|
|
- nodeId (str): The ID of the node.
|
|
|
|
|
- nodeType (str): The type of the node (must be "node2" or "node6").
|
|
|
|
|
- oldTitle (str): The old title of the audio file.
|
|
|
|
|
- newTitle (str): The new title of the audio file.
|
|
|
|
|
- currentAudioFile (str): The current audio file name.
|
|
|
|
|
|
|
|
|
|
JSON Response:
|
|
|
|
|
- status (str): The status of the operation ("success" or "error").
|
|
|
|
|
- message (str, optional): The error message if the operation failed.
|
|
|
|
|
- newAudioFile (str, optional): The URL of the new audio file if the operation succeeded.
|
|
|
|
|
|
|
|
|
|
Raises:
|
|
|
|
|
Exception: If any error occurs during the process, a JSON response with status 500 is returned.
|
|
|
|
|
"""
|
|
|
|
|
"""
|
|
|
|
|
Renombra el archivo de audio asociado a node2 o node6.
|
|
|
|
|
"""
|
|
|
|
|
@ -663,6 +862,22 @@ def rename_audio(request):
|
|
|
|
|
# Vista para renombrar una pestaña
|
|
|
|
|
@csrf_exempt
|
|
|
|
|
def rename_tab(request):
|
|
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
Args:
|
|
|
|
|
request (HttpRequest): La solicitud HTTP que debe ser de tipo POST y contener un cuerpo JSON con 'tabId' y 'newTabName'.
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
JsonResponse: Una respuesta JSON con el estado de la operación. Puede ser:
|
|
|
|
|
- {'status': 'success', 'message': 'Pestaña renombrada exitosamente'} en caso de éxito.
|
|
|
|
|
- {'status': 'error', 'message': 'Solo se permiten solicitudes POST'} si el método de la solicitud no es POST.
|
|
|
|
|
- {'status': 'error', 'message': 'Datos incompletos'} si faltan 'tabId' o 'newTabName' en el cuerpo de la solicitud.
|
|
|
|
|
- {'status': 'error', 'message': 'Archivo de pestaña no encontrado'} si no se encuentra un archivo correspondiente a 'tabId'.
|
|
|
|
|
- {'status': 'error', 'message': str(e)} si ocurre cualquier otra excepción durante el proceso.
|
|
|
|
|
|
|
|
|
|
Raises:
|
|
|
|
|
Exception: Cualquier excepción que ocurra durante el proceso será capturada y su mensaje será incluido en la respuesta JSON.
|
|
|
|
|
"""
|
|
|
|
|
"""
|
|
|
|
|
Renombra una pestaña específica.
|
|
|
|
|
"""
|
|
|
|
|
@ -713,6 +928,30 @@ def rename_tab(request):
|
|
|
|
|
# Vista para actualizar Node1 (título y extensión)
|
|
|
|
|
@csrf_exempt
|
|
|
|
|
def update_node1(request):
|
|
|
|
|
"""
|
|
|
|
|
Updates the title and extension number of a specific node1.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
request (HttpRequest): The HTTP request object containing the data to update the node.
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
JsonResponse: A JSON response indicating the success or failure of the update operation.
|
|
|
|
|
|
|
|
|
|
Raises:
|
|
|
|
|
Exception: If any error occurs during the update process.
|
|
|
|
|
|
|
|
|
|
The function performs the following steps:
|
|
|
|
|
1. Checks if the request method is POST. If not, returns a 405 error.
|
|
|
|
|
2. Parses the request body to extract the necessary data.
|
|
|
|
|
3. Validates the presence of required data fields.
|
|
|
|
|
4. Creates a backup of the Asterisk configuration file and appends new extension configuration.
|
|
|
|
|
5. Searches for the corresponding JSON file for the tab and updates the node's title and extension number.
|
|
|
|
|
6. Saves the updated JSON file.
|
|
|
|
|
7. Returns a success response if the update is successful, or an error response if any step fails.
|
|
|
|
|
|
|
|
|
|
Note:
|
|
|
|
|
This endpoint is specifically for updating nodes of type "node1".
|
|
|
|
|
"""
|
|
|
|
|
"""
|
|
|
|
|
Actualiza el título y número de extensión de un node1 específico.
|
|
|
|
|
"""
|
|
|
|
|
@ -786,6 +1025,34 @@ exten => {new_extension},n,Hangup()
|
|
|
|
|
# Vista para eliminar un nodo
|
|
|
|
|
@csrf_exempt
|
|
|
|
|
def delete_node(request):
|
|
|
|
|
"""
|
|
|
|
|
Handle the deletion of a node and its connections from a tab.
|
|
|
|
|
|
|
|
|
|
This view function processes a POST request to delete a node identified by its ID from a specified tab.
|
|
|
|
|
It also handles the deletion of associated files if the node type requires it.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
request (HttpRequest): The HTTP request object containing the POST data.
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
JsonResponse: A JSON response indicating the success or failure of the operation.
|
|
|
|
|
|
|
|
|
|
The expected JSON payload in the request body should contain:
|
|
|
|
|
- tabId (str): The ID of the tab.
|
|
|
|
|
- nodeId (str): The ID of the node to be deleted.
|
|
|
|
|
- nodeType (str): The type of the node.
|
|
|
|
|
|
|
|
|
|
Possible responses:
|
|
|
|
|
- 200 OK: Node and its connections were successfully deleted.
|
|
|
|
|
- 400 Bad Request: Missing or incomplete data in the request.
|
|
|
|
|
- 404 Not Found: Tab file or node not found.
|
|
|
|
|
- 405 Method Not Allowed: Request method is not POST.
|
|
|
|
|
- 500 Internal Server Error: An unexpected error occurred during processing.
|
|
|
|
|
|
|
|
|
|
Node type-specific behavior:
|
|
|
|
|
- node3: Deletes associated text files.
|
|
|
|
|
- node2, node6: Deletes associated audio files.
|
|
|
|
|
"""
|
|
|
|
|
if request.method != 'POST':
|
|
|
|
|
return JsonResponse({'status': 'error', 'message': 'Solo se permiten solicitudes POST'}, status=405)
|
|
|
|
|
|
|
|
|
|
@ -852,6 +1119,25 @@ def delete_node(request):
|
|
|
|
|
# Vista para eliminar una pestaña
|
|
|
|
|
@csrf_exempt
|
|
|
|
|
def delete_tab(request):
|
|
|
|
|
"""
|
|
|
|
|
Handle the deletion of a tab.
|
|
|
|
|
|
|
|
|
|
This view function processes a POST request to delete a tab by its ID and name.
|
|
|
|
|
It performs the following actions:
|
|
|
|
|
- Validates that the request method is POST.
|
|
|
|
|
- Parses the request body to extract the tab ID and name.
|
|
|
|
|
- Deletes the corresponding tab data file.
|
|
|
|
|
- Deletes associated media files (audio and text files).
|
|
|
|
|
- Deletes the conditions JSON file related to the tab.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
request (HttpRequest): The HTTP request object.
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
JsonResponse: A JSON response indicating the result of the operation.
|
|
|
|
|
- On success: {'status': 'success', 'message': 'Pestaña eliminada exitosamente'}
|
|
|
|
|
- On error: {'status': 'error', 'message': 'Error message'} with appropriate HTTP status code.
|
|
|
|
|
"""
|
|
|
|
|
if request.method != 'POST':
|
|
|
|
|
return JsonResponse({'status': 'error', 'message': 'Solo se permiten solicitudes POST'}, status=405)
|
|
|
|
|
|
|
|
|
|
@ -893,6 +1179,29 @@ def delete_tab(request):
|
|
|
|
|
# Vista para actualizar Node4
|
|
|
|
|
@csrf_exempt
|
|
|
|
|
def update_node4(request):
|
|
|
|
|
"""
|
|
|
|
|
Handle POST requests to update the extension number of a node4 in a tab's JSON file.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
request (HttpRequest): The HTTP request object containing the POST data.
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
JsonResponse: A JSON response indicating the success or failure of the operation.
|
|
|
|
|
|
|
|
|
|
The request body should contain a JSON object with the following keys:
|
|
|
|
|
- tabId (str): The ID of the tab.
|
|
|
|
|
- tabName (str): The name of the tab.
|
|
|
|
|
- nodeId (str): The ID of the node to be updated.
|
|
|
|
|
- nodeType (str): The type of the node (should be "node4").
|
|
|
|
|
- extensionNumber (int): The new extension number for the node.
|
|
|
|
|
|
|
|
|
|
Possible responses:
|
|
|
|
|
- 200 OK: If the node4 is successfully updated.
|
|
|
|
|
- 400 Bad Request: If the request data is incomplete or the node type is not "node4".
|
|
|
|
|
- 404 Not Found: If the tab file or the node4 is not found.
|
|
|
|
|
- 405 Method Not Allowed: If the request method is not POST.
|
|
|
|
|
- 500 Internal Server Error: If an unexpected error occurs during processing.
|
|
|
|
|
"""
|
|
|
|
|
if request.method != 'POST':
|
|
|
|
|
return JsonResponse({'status': 'error', 'message': 'Solo se permiten solicitudes POST'}, status=405)
|
|
|
|
|
|
|
|
|
|
@ -945,6 +1254,29 @@ def update_node4(request):
|
|
|
|
|
# Vista para generar audios por medio del TTS
|
|
|
|
|
@csrf_exempt
|
|
|
|
|
def tts_module(request, language="es"):
|
|
|
|
|
"""
|
|
|
|
|
Generates an audio file from text using TTS and saves it in the corresponding directory.
|
|
|
|
|
Args:
|
|
|
|
|
request (HttpRequest): The HTTP request object containing the POST data.
|
|
|
|
|
language (str, optional): The language code for TTS. Defaults to "es".
|
|
|
|
|
Returns:
|
|
|
|
|
JsonResponse: A JSON response indicating the success or failure of the operation.
|
|
|
|
|
The function performs the following steps:
|
|
|
|
|
1. Checks if the request method is POST.
|
|
|
|
|
2. Parses the JSON data from the request body.
|
|
|
|
|
3. Validates the presence of required data fields: tabId, title, text, nodeId, and nodeType.
|
|
|
|
|
4. Creates the necessary directories for storing the audio file.
|
|
|
|
|
5. Generates a unique filename for the audio file using the nodeId and title.
|
|
|
|
|
6. Converts the text to speech using the specified language.
|
|
|
|
|
7. Adjusts the speed of the audio.
|
|
|
|
|
8. Converts the audio to WAV format at 8000 kHz.
|
|
|
|
|
9. Saves the audio file in the specified directory.
|
|
|
|
|
10. Copies the audio file to the Asterisk sounds directory.
|
|
|
|
|
11. Generates the URL for the saved audio file.
|
|
|
|
|
12. Returns a JSON response with the status and URL of the saved audio file.
|
|
|
|
|
Raises:
|
|
|
|
|
Exception: If any error occurs during the process, a JSON response with the error message is returned.
|
|
|
|
|
"""
|
|
|
|
|
"""
|
|
|
|
|
Genera un archivo de audio a partir de un texto utilizando TTS y lo guarda en el directorio correspondiente.
|
|
|
|
|
"""
|
|
|
|
|
|