1. views.py
Este archivo contiene todas la funciones para cargar vistas, desarrollo de funciones para almacenar información y crear diferentes tipos de archivos con su respectiva información.
1.1. get_safe_filename()
Esta función toma el nombre de los archivos que serán creados, como por ejemplo archivos de audio, documentos, entre otras cosas y al nombre del archivo lo transforma en un nombre sin ningún tipo de carácter especial o espacio.
1.2. create_tabs_flow()
Esta función es la encargada de renderizar la vista HTML ubicada en la carpeta "templates".
1.3. list_tabs()
1.3.1. Definición de la Función.
Parámetro request: Representa el objeto de solicitud HTTP que invoca esta vista.
1.3.2. Docstring.
La cadena de documentación proporciona una descripción clara de lo que hace la función, sus argumentos y el valor que retorna.
1.3.3. Construcción de la Ruta al Directorio de Datos.
settings.BASE_DIR: Es la ruta base del proyecto Django.
os.path.join: Combina rutas de manera segura según el sistema operativo.
tabs: Inicializa una lista vacía que almacenará la información de las pestañas.
1.3.4. Verificación de la Existencia del Directorio.
Verifica si el directorio flow/data existe para evitar errores al intentar acceder a un directorio inexistente.
1.3.5. Iteración Sobre los Archivos del Directorio.
os.listdir(data_dir): Lista todos los archivos en el directorio especificado.
Filtrado de Archivos: Solo procesa archivos que comienzan con 'tab_' y terminan con '.json', siguiendo el patrón esperado.
1.3.6. Extracción de tabId y tabName del Nombre del Archivo.
tab_: Prefijo fijo.
(\d+): Captura uno o más dígitos que representan el tabId.
_(.+): Captura uno o más caracteres que representan el tabName.
.json: Sufijo fijo para asegurar que el archivo es un JSON.
match.group(1): Extrae el tabId.
match.group(2): Extraería el tabName del nombre del archivo, aunque en este caso no se utiliza directamente.
1.3.7. Lectura del Contenido del Archivo JSON
file_path = os.path.join(data_dir, filename)
with open(file_path, 'r', encoding='utf-8') as f:
data = json.load(f)
tab_name = data.get('tabName', f'Pestaña {tab_id}')
file_path: Construye la ruta completa al archivo JSON.
Apertura del Archivo: Se abre el archivo en modo lectura con codificación UTF-8.
json.load(f): Carga el contenido JSON del archivo en un diccionario de Python.
Obtención de tabName: Intenta obtener el valor de la clave 'tabName' del JSON. Si no está presente, asigna un nombre por defecto en español 'Pestaña + id'.
1.3.8. Agregando la Pestaña a la Lista.
Crea un diccionario con las claves 'name' y 'id' y lo agrega a la lista tabs.
1.3.9. Retorno de la Respuesta JSON.
return JsonResponse({'tabs': tabs})
JsonResponse: Es una clase de Django que convierte el diccionario proporcionado en una respuesta HTTP con contenido JSON.
La respuesta contiene una clave 'tabs' que mapea a la lista de pestañas recopiladas.
1.4. save_tts.
La función save_tts es una vista de Django que procesa una solicitud POST para guardar datos relacionados con TTS y generar un script Python AGI que interactúa con el sistema Asterisk. Este script AGI se utiliza para manejar llamadas, grabar audio, detectar audio, y consultar el modelo de lenguaje Claude para generar respuestas basadas en el contenido proporcionado.
1.4.1. Decorador @csrf_exempt.
Propósito: Exime a la vista de la protección contra ataques CSRF (Cross-Site Request Forgery). Esto es útil cuando la vista espera solicitudes que no provienen de formularios de Django, como solicitudes API externas.
Consideración de Seguridad: Al eximir CSRF, se debe asegurar que otros mecanismos de seguridad (como autenticación y validación de entradas) estén correctamente implementados para evitar vulnerabilidades.
1.4.2. Verificación del Método de Solicitud.
Propósito: Asegura que solo se procesen solicitudes HTTP POST. Si la solicitud no es POST, devuelve una respuesta de error con el código de estado 405 (Método No Permitido).
1.4.3. Manejo de Excepciones Generales.
Propósito: Envuelve la lógica principal en un bloque try-except para capturar y manejar cualquier excepción que ocurra durante el procesamiento, devolviendo una respuesta JSON con el mensaje de error correspondiente.
1.4.4. Extracción y Validación de Datos del Cuerpo de la Solicitud.
Propósito:
Parsea el cuerpo de la solicitud JSON.
Extrae campos específicos necesarios para la generación del script AGI.
Asigna un valor por defecto al audio_file si no se proporciona en la solicitud.
1.4.5. Formateo del Nombre del Archivo de Audio.
Propósito:
Utiliza una función get_safe_filename (presumiblemente definida en otro lugar) para sanitizar el título y asegurar que el nombre del archivo sea seguro para el sistema de archivos.
Formatea el nombre del archivo de audio combinando el node_id y el título sanitizado, seguido de la extensión .WAV.
1.4.6. Construcción de la Ruta del Archivo Python AGI.
Propósito:
Define el nombre del archivo Python basado en el tab_name.
Construye la ruta completa donde se guardará el script AGI, en este caso dentro de /var/lib/asterisk/agi-bin/, que es el directorio estándar para scripts AGI en Asterisk.
1.4.7. Generación del Contenido del Archivo Python AGI.
Crea una cadena multilínea que contiene el contenido del script Python AGI. Este script incluye importaciones necesarias, una clase CallHandler con métodos para manejar llamadas, grabar audio, detectar audio, consultar Claude, y determinar extensiones. Al final del script, se incluye un bloque if name == "main": que inicia el AGI, reproduce un archivo de audio y comienza a grabar la llamada. Aspectos Destacables del Script AGI Generado:
Importaciones: Incluye módulos para reconocimiento de voz, manejo de expresiones regulares, TTS, subprocessos, manejo de Asterisk AGI, y comunicación con el modelo de lenguaje Claude. Clase CallHandler: Inicialización: Configura la ruta del audio y obtiene el tab_id. Métodos Principales: grabar_llamada: Inicia la grabación de la llamada y llama a detectar_audio después de la grabación. detectar_audio: Utiliza speech_recognition para convertir el audio grabado en texto, consulta a Claude para generar una respuesta, convierte el texto de la respuesta a voz, y maneja la lógica de reproducción y redirección basada en las condiciones definidas. determine_extension: Determina la extensión de marcación basada en las condiciones definidas en un archivo JSON específico. consultar_claude: Interactúa con el modelo Claude para generar respuestas basadas en el contenido proporcionado. Bloque Principal: Inicia el AGI, reproduce un archivo de audio inicial, y comienza a manejar la llamada.
1.4.8. Escritura del Archivo AGI y Configuración de Permisos.
Propósito:
Escritura del Archivo: Abre (o crea) el archivo en la ruta especificada y escribe el contenido generado.
Configuración de Permisos:
Cambia los permisos del archivo a 755, lo que permite que el propietario lea, escriba y ejecute el archivo, y que el grupo y otros usuarios lo lean y ejecuten.
Cambia la propiedad del archivo al usuario y grupo asterisk mediante un comando sudo chown.
Manejo de Excepciones: Si ocurre cualquier error durante estos pasos, se captura la excepción y se devuelve una respuesta JSON indicando el fallo.
1.4.9. Respuesta de Éxito.
Propósito: Si todo el proceso se completa exitosamente, devuelve una respuesta JSON con el estado 'success' y la ruta del archivo AGI creado.
1.5. save_tab_data.
La función save_tab_data es una vista de Django que procesa una solicitud POST para almacenar información de una pestaña. Esta información incluye nodos y conexiones que conforman la estructura de la pestaña. Además, la función extrae condiciones específicas de nodos de tipo 'node3' y las guarda en un archivo JSON separado destinado al sistema IVR (Interactive Voice Response).
1.5.1. Decorador @csrf_exempt.
Propósito: Exime a la vista de la protección contra ataques CSRF (Cross-Site Request Forgery). Esto es útil cuando la vista espera solicitudes que no provienen de formularios de Django, como solicitudes API externas.
Consideración de Seguridad: Al eximir CSRF, es crucial asegurarse de que otros mecanismos de seguridad (como autenticación y validación de entradas) estén correctamente implementados para evitar vulnerabilidades.
1.5.2. Verificación del Método de Solicitud.
Propósito: Asegura que solo se procesen solicitudes HTTP POST. Si la solicitud no es POST, devuelve una respuesta de error con el código de estado 405 (Método No Permitido).
1.5.3. Manejo de Excepciones Generales.
Propósito: Envuelve la lógica principal en un bloque try-except para capturar y manejar cualquier excepción que ocurra durante el procesamiento, devolviendo una respuesta JSON con el mensaje de error correspondiente.
1.5.4. Extracción y Validación de Datos del Cuerpo de la Solicitud.
Propósito:
Parseo del JSON: Convierte el cuerpo de la solicitud de formato JSON a un diccionario de Python.
Extracción de Campos: Obtiene los valores de 'tabId', 'tabName', 'nodes' y 'connections'.
Validación de Datos: Verifica que 'tabId', 'tabName', 'nodes' y 'connections' estén presentes. Si falta alguno, devuelve una respuesta de error indicando que los datos están incompletos.
1.5.5. Sanitización del Nombre de la Pestaña.
Propósito: Utiliza una función get_safe_filename para sanitizar el nombre de la pestaña, asegurando que no contenga caracteres inválidos que puedan causar problemas en el sistema de archivos.
1.5.6. Formateo y Construcción de la Ruta del Archivo JSON.
Propósito:
Formateo del Nombre del Archivo: Crea un nombre de archivo que incluye el ID de la pestaña y el nombre sanitizado.
Construcción de la Ruta Completa: Utiliza os.path.join para crear una ruta completa hacia el directorio flow/data dentro del directorio base del proyecto Django.
1.5.7. Filtrado y Procesamiento de Nodos
Propósito: Itera sobre cada nodo en la lista nodes y filtra la información relevante según el tipo de nodo ('node1', 'node2', 'node3', 'node4', 'node6' u otros). Para cada tipo de nodo, extrae y organiza los campos necesarios, aplicando lógica específica según las características de cada tipo.
node1: Extrae 'id', 'title', 'extensionNumber', 'position' y 'nodeType'. node2: Maneja el campo 'audioFile', asegurándose de que sea una URL relativa si está presente. Extrae 'id', 'title', 'audioFile', 'position' y 'nodeType'. node3: Extrae 'id', 'title', 'content', 'position', 'nodeType', 'textFile' y 'conditions'. Las 'conditions' se utilizan posteriormente para generar el archivo de condiciones. node4: Extrae 'id', 'title', 'position', 'nodeType' y 'extensionNumber'. node6: Maneja el campo 'audioFile', verificando si ya contiene la ruta relativa y, si no, construye la ruta correcta. Extrae 'id', 'title', 'content', 'audioFile', 'position' y 'nodeType'. Otros Tipos de Nodos: Si el tipo de nodo no coincide con ninguno de los anteriores, simplemente agrega el nodo tal cual a la lista filtered_nodes.
1.5.8. Creación de Directorios Necesarios
Propósito: Verifica que el directorio donde se almacenarán los archivos JSON (flow/data) exista. Si no existe, lo crea utilizando os.makedirs con la opción exist_ok=True para evitar errores si el directorio ya existe.
1.5.9. Guardado del Archivo JSON de la Pestaña
Propósito: Escribe los datos filtrados en un archivo JSON en la ruta previamente definida. El archivo contiene:
'tabName': Nombre de la pestaña.
'nodes': Lista de nodos filtrados.
'connections': Lista de conexiones entre nodos.
Detalles:
ensure_ascii=False: Permite que los caracteres no ASCII (como acentos y eñes) se guarden correctamente en el archivo JSON.
indent=4: Formatea el JSON con una indentación de 4 espacios para mejorar la legibilidad.
1.5.10. Extracción y Guardado de Condiciones de node3
Propósito:
Creación del Directorio IVR: Verifica que el directorio /home/Flow_IA/IVR/ exista y lo crea si no.
Preparación de la Estructura de Datos: Inicializa un diccionario conditions_data que almacenará el ID de la pestaña, el nombre de la pestaña y una lista de condiciones extraídas de nodos de tipo 'node3'.
Creación de Diccionarios de Nodos:
node_dict: Un diccionario que mapea cada ID de nodo a su respectivo nodo para acceso rápido.
node_types: Un diccionario que mapea cada ID de nodo a su tipo ('nodeType').
Iteración sobre los Nodos Filtrados: Para cada nodo de tipo 'node3':
Inicialización de node_info: Contiene el ID del nodo, el título y una lista vacía de condiciones.
Extracción de Condiciones: Para cada condición dentro del nodo:
condition_string: La cadena de condición.
target_node_id: El ID del nodo al que apunta la condición.
extension_number: Inicialmente vacío; se llena si el target_node_id corresponde a un nodo de tipo 'node4'.
Verificación del Tipo de Nodo Objetivo: Si el target_node_id corresponde a un nodo de tipo 'node4', se obtiene el número de extensión asociado.
Agregación de la Condición: Se agrega un diccionario con 'condition_string' y 'extensionNumber' a la lista de condiciones de node_info.
Agregación de node_info a conditions_data: Finalmente, se agrega node_info a la lista 'node3_conditions' en conditions_data.
Formateo y Guardado del Archivo de Condiciones:
Nombre del Archivo: Formateado como tab_<tab_id>_conditions.json.
Ruta del Archivo: Construida en el directorio IVR.
Escritura del Archivo JSON: Guarda conditions_data en el archivo JSON con una indentación de 4 espacios y sin escapar caracteres ASCII.
1.5.11. Respuesta de Éxito
Propósito: Si todo el proceso se completa exitosamente, devuelve una respuesta JSON indicando que los datos se han guardado correctamente.
1.6. load_tab_data.
La función load_tab_data es una vista de Django que maneja solicitudes para cargar datos de una pestaña específica (tab_id). Busca un archivo JSON correspondiente a la pestaña en el directorio flow/data, carga y procesa los datos del archivo, elimina ciertos atributos de nodos según su tipo y devuelve los datos procesados como una respuesta JSON. Si no se encuentra un archivo correspondiente, devuelve una respuesta por defecto con listas vacías de nodos y conexiones, y un nombre de pestaña basado en el tab_id.
1.6.1. Definición de la Función y Docstring
Propósito: Define la función load_tab_data que carga y procesa los datos de una pestaña específica.
Docstring: Proporciona una descripción detallada de lo que hace la función, los argumentos que recibe, lo que retorna y notas adicionales sobre el manejo de ciertos tipos de nodos.
1.6.2. Bloque try-except para Manejo de Excepciones
Propósito: Envolver la lógica principal en un bloque try-except para capturar y manejar cualquier excepción que ocurra durante la ejecución. Si ocurre una excepción, se registra el error y se devuelve una respuesta JSON con un mensaje de error y un código de estado 500 (Error Interno del Servidor).
1.6.3. Construcción de la Ruta al Directorio de Datos
Propósito: Construye la ruta completa al directorio flow/data dentro del directorio base del proyecto Django utilizando os.path.join para asegurar compatibilidad entre diferentes sistemas operativos.
1.6.4. Búsqueda del Archivo JSON Correspondiente al tab_id
Propósito:
Listado de Archivos: Utiliza os.listdir(data_dir) para listar todos los archivos en el directorio flow/data.
Filtrado de Archivos: Filtra los archivos que comienzan con tab_<tab_id>_ y terminan con .json, asegurando que coincidan con el patrón esperado para el archivo de la pestaña.
Verificación de Existencia: Si no se encuentran archivos coincidentes (matching_files está vacío), devuelve una respuesta JSON por defecto con listas vacías de nodes y connections, y un nombre de pestaña basado en el tab_id.
1.6.5. Carga de los Datos desde el Archivo JSON
Propósito:
Construcción de la Ruta del Archivo: Asume que el primer archivo en matching_files es el correcto y construye su ruta completa.
Apertura y Lectura del Archivo: Abre el archivo en modo lectura con codificación UTF-8 y carga su contenido utilizando json.load, convirtiéndolo en un diccionario de Python.
1.6.6. Procesamiento de los Nodos para Eliminar el Atributo audioFile
Propósito:
Iteración sobre los Nodos: Recorre cada nodo en la lista nodes dentro de los datos cargados.
Identificación del Tipo de Nodo: Obtiene el valor de 'nodeType' para cada nodo.
Eliminación de audioFile: Si el nodo es de tipo 'node1', 'node3' o 'node4', elimina el atributo 'audioFile' si existe utilizando node.pop('audioFile', None).
Nota Adicional: Para nodos de tipo 'node4', no existe el atributo 'receivedString', pero sí 'extensionNumber'. Aunque esta nota está presente en el comentario, en el código actual no se realiza ninguna acción específica para manejar 'extensionNumber'. Es importante asegurarse de que este atributo se maneje correctamente si es relevante para la lógica de la aplicación.
1.6.7. Devolución de la Respuesta JSON con los Datos Procesados
Propósito: Devuelve una respuesta JSON que contiene los datos de la pestaña cargados y procesados desde el archivo JSON.
1.6.8. Manejo de Excepciones y Registro de Errores
Propósito:
Registro del Error: Utiliza logger.error para registrar el mensaje de error, lo que es útil para la depuración y el monitoreo.
Respuesta de Error: Devuelve una respuesta JSON con un mensaje de error y un código de estado 500, indicando que ocurrió un error interno en el servidor.
1.7. delete_files.
La función delete_files es una vista de Django que procesa solicitudes POST para eliminar archivos de texto (.txt) asociados con nodos de tipo "node3" dentro de una pestaña específica. La función extrae información relevante de la solicitud, valida los datos proporcionados, construye las rutas de los archivos a eliminar y, si los archivos existen, los elimina del sistema de archivos. Finalmente, devuelve una respuesta JSON que indica el éxito o el fallo de la operación.
1.7.1. Decorador @csrf_exempt
Propósito: Exime a la vista de la protección contra ataques CSRF (Cross-Site Request Forgery). Esto es útil cuando la vista espera recibir solicitudes que no provienen de formularios de Django, como solicitudes API externas.
Consideración de Seguridad: Al eximir CSRF, es crucial asegurarse de que otros mecanismos de seguridad, como la autenticación y la validación de entradas, estén correctamente implementados para evitar vulnerabilidades.
1.7.2. Verificación del Método de Solicitud.
Propósito: Asegura que solo se procesen solicitudes HTTP POST. Si la solicitud no es POST, devuelve una respuesta de error con el código de estado 405 (Método No Permitido).
Importancia: Este control previene que métodos no permitidos accedan a la funcionalidad de eliminación de archivos, mejorando la seguridad de la aplicación.
1.7.3. Bloque try-except para Manejo de Excepciones
Propósito: Envuelve la lógica principal en un bloque try-except para capturar y manejar cualquier excepción que ocurra durante la ejecución. Si ocurre una excepción, devuelve una respuesta JSON con un mensaje de error y un código de estado 500 (Error Interno del Servidor).
Consideración: Aunque captura excepciones generales, sería más robusto capturar excepciones específicas para proporcionar mensajes de error más precisos y manejar diferentes tipos de errores de manera adecuada.
1.7.4. Extracción y Validación de Datos del Cuerpo de la Solicitud
Propósito:
Parseo del JSON: Convierte el cuerpo de la solicitud de formato JSON a un diccionario de Python utilizando json.loads.
Extracción de Campos: Obtiene los valores de 'tabId', 'nodeId', 'nodeType' y 'oldTitle'.
Validación de Datos: Verifica que todos los campos necesarios estén presentes y no sean None o vacíos. Si falta alguno, devuelve una respuesta de error indicando que los datos están incompletos con un código de estado 400 (Solicitud Incorrecta).
Importancia: Garantiza que la función reciba todos los datos necesarios para procesar la eliminación de archivos correctamente.
1.7.5. Verificación del Tipo de Nodo
Propósito: La función está diseñada para eliminar archivos asociados únicamente a nodos de tipo "node3". Si el tipo de nodo proporcionado no es "node3", devuelve una respuesta indicando que este nodo no tiene archivos para eliminar con un código de estado 200 (OK).
Importancia: Asegura que la función no intente eliminar archivos de nodos que no deberían tener archivos asociados, evitando operaciones innecesarias o erróneas.
1.7.6. Construcción de las Rutas de los Directorios y Archivos
Propósito:
tab_dir: Construye la ruta al directorio específico de la pestaña utilizando settings.MEDIA_ROOT, que generalmente apunta al directorio de medios configurado en Django (por defecto, suele ser media/).
text_dir: Construye la ruta al subdirectorio text_files dentro del directorio de la pestaña.
Creación de Directorios: Utiliza os.makedirs con exist_ok=True para crear el directorio text_files si no existe. Si ya existe, no se genera un error.
Importancia: Asegura que la ruta donde se espera encontrar los archivos de texto existe antes de intentar eliminar archivos, evitando errores relacionados con directorios inexistentes.
1.7.7. Generación del Nombre y Ruta del Archivo de Texto a Eliminar
Propósito:
Sanitización del Título: Crea una versión segura del old_title reemplazando cualquier carácter que no sea alfanumérico con un guion bajo (_). Esto previene problemas con nombres de archivos que contengan caracteres especiales o inválidos.
Construcción del Nombre del Archivo: Combina el safe_old_title, node_type y node_id para formar la base del nombre del archivo. Luego, añade la extensión .txt para completar el nombre del archivo.
Construcción de la Ruta Completa: Combina text_dir y txt_filename para obtener la ruta completa al archivo de texto que se desea eliminar.
Ejemplo: Si old_title es "Saludo Inicial", node_type es "node3" y node_id es "123", el nombre del archivo sería "Saludo_Inicial_node3_123.txt".
Importancia: Asegura que el archivo a eliminar tiene un nombre predecible y seguro, facilitando su localización y evitando errores de sistema de archivos.
1.7.8. Eliminación del Archivo de Texto si Existe
Verificación de Existencia: Utiliza os.path.exists para verificar si el archivo de texto especificado existe en la ruta construida. Eliminación del Archivo: Si el archivo existe, lo elimina utilizando os.remove. Importancia: Realiza la operación de eliminación solo si el archivo realmente existe, evitando errores que podrían ocurrir si se intenta eliminar un archivo inexistente.
1.7.9. Devolución de la Respuesta de Éxito
Propósito: Después de eliminar el archivo (o si el archivo no existe), devuelve una respuesta JSON indicando que la operación fue exitosa con un mensaje correspondiente y un código de estado 200 (OK) implícito.
Importancia: Informa al cliente que la operación de eliminación se completó correctamente, permitiendo acciones posteriores basadas en esta confirmación.
1.8. upload_audio.
La función upload_audio es una vista de Django que procesa solicitudes HTTP POST para subir archivos de audio (.wav). Estos archivos se asocian con nodos de tipo "node2" dentro de una pestaña específica (tabId). La función realiza varias operaciones, incluyendo la validación de datos, el almacenamiento del archivo en el sistema de archivos de Django, la copia del archivo al directorio de Asterisk y la generación de una URL para acceder al archivo subido.
1.8.1. Decorador @csrf_exempt.
Propósito:
Exime a la vista de la protección contra ataques CSRF (Cross-Site Request Forgery). Esto es útil cuando la vista espera recibir solicitudes que no provienen de formularios de Django, como solicitudes API externas.
Consideración de Seguridad:
Al eximir la vista de la protección CSRF, es crucial asegurarse de que otros mecanismos de seguridad (como la autenticación y la validación de entradas) estén correctamente implementados para prevenir vulnerabilidades.
1.8.2. Verificación del Método de Solicitud
Propósito:
Asegura que la función solo procese solicitudes HTTP POST. Si la solicitud no es POST, devuelve una respuesta de error con el código de estado 405 (Método No Permitido).
Importancia:
Previene que métodos HTTP no permitidos accedan a la funcionalidad de carga de archivos, mejorando la seguridad de la aplicación.
1.8.3. Bloque try-except para Manejo de Excepciones
Propósito:
Envuelve la lógica principal en un bloque try-except para capturar y manejar cualquier excepción que ocurra durante la ejecución. Si ocurre una excepción, devuelve una respuesta JSON con un mensaje de error y un código de estado 500 (Error Interno del Servidor).
Consideración:
Aunque captura excepciones generales, sería más robusto capturar excepciones específicas para proporcionar mensajes de error más precisos y manejar diferentes tipos de errores de manera adecuada.
1.8.4. Extracción y Validación de Datos del Cuerpo de la Solicitud
Propósito:
Extracción de Datos: Obtiene los valores de 'tabId', 'nodeId', 'nodeType', 'title' y 'audioFile' desde los datos POST y los archivos adjuntos.
Validación de Datos: Verifica que todos los campos necesarios estén presentes y no sean None o vacíos. Si falta alguno, devuelve una respuesta de error indicando que los datos están incompletos con un código de estado 400 (Solicitud Incorrecta).
Importancia:
Garantiza que la función reciba todos los datos necesarios para procesar la carga de archivos correctamente.
1.8.5. Verificación del Tipo de Nodo
Propósito:
La función está diseñada para procesar únicamente nodos de tipo "node2". Si el tipo de nodo proporcionado no es "node2", devuelve una respuesta de error con un mensaje correspondiente y un código de estado 400 (Solicitud Incorrecta).
Importancia:
Asegura que la función no intente procesar nodos que no están destinados a manejar archivos de audio, evitando operaciones innecesarias o erróneas.
1.8.6. Creación de Directorios Necesarios para Almacenar el Archivo de Audio
Propósito:
Construcción de Rutas:
tab_dir: Ruta al directorio específico de la pestaña dentro del directorio de medios configurado en Django (MEDIA_ROOT).
audio_dir: Ruta al subdirectorio audio_files dentro del directorio de la pestaña.
Creación de Directorios:
Utiliza os.makedirs con exist_ok=True para crear los directorios necesarios si no existen. Si ya existen, no genera un error.
Importancia:
Asegura que la estructura de directorios necesaria para almacenar los archivos de audio exista antes de intentar guardar archivos en ella, evitando errores relacionados con directorios inexistentes.
1.8.7. Generación de un Nombre de Archivo Único para el Archivo de Audio
Propósito:
Sanitización del Título: Crea una versión segura del title reemplazando cualquier carácter que no sea alfanumérico con un guion bajo (_). Esto previene problemas con nombres de archivos que contengan caracteres especiales o inválidos.
Construcción del Nombre del Archivo: Combina el safe_title, node_type y node_id para formar la base del nombre del archivo. Luego, añade la extensión .wav para completar el nombre del archivo.
Construcción de la Ruta Completa: Combina audio_dir y wav_filename para obtener la ruta completa al archivo de audio que se desea guardar.
Ejemplo: Si title es "Saludo Inicial", node_type es "node2" y node_id es "123", el nombre del archivo sería "Saludo_Inicial_node2_123.wav".
Importancia:
Asegura que el archivo a guardar tenga un nombre predecible y seguro, facilitando su localización y evitando errores del sistema de archivos.
1.8.8. Guardado del Archivo de Audio en el Directorio de Medios
Propósito:
Apertura del Archivo: Abre (o crea) el archivo en modo escritura binaria ('wb+') en la ruta especificada (wav_filepath).
Escritura en Bloques: Itera sobre los "chunks" del archivo de audio subido para escribirlos en el archivo de destino. Esto es eficiente para manejar archivos grandes sin cargar todo el contenido en memoria.
Importancia:
Realiza el almacenamiento efectivo del archivo de audio en el sistema de archivos de Django, asegurando que el archivo se guarde correctamente y de manera segura.
1.8.9. Copia del Archivo de Audio al Directorio de Grabaciones de Asterisk
Definición del Directorio de Asterisk: Define la ruta al directorio donde Asterisk almacena los archivos de audio (/var/lib/asterisk/sounds). Creación del Directorio: Utiliza os.makedirs para asegurar que el directorio de Asterisk exista. Si ya existe, no genera un error. Construcción de la Ruta Completa del Archivo en Asterisk: Combina asterisk_dir y wav_filename para obtener la ruta completa donde se copiará el archivo. Copia del Archivo: Utiliza shutil.copy para copiar el archivo de audio desde el directorio de medios de Django al directorio de Asterisk. Importancia:
Permite que el archivo de audio subido esté disponible para su uso por Asterisk, facilitando su integración en sistemas de telefonía. Consideración de Seguridad:
Asegurarse de que el usuario que ejecuta la aplicación Django tenga los permisos necesarios para escribir en el directorio de Asterisk. Validar que los archivos copiados no sobrescriban archivos críticos existentes en Asterisk.
1.8.10. Generación de la URL del Archivo de Audio
Construcción de la URL: Combina settings.MEDIA_URL con la ruta relativa al archivo de audio para generar una URL accesible públicamente que puede ser utilizada por el frontend u otros servicios para reproducir o acceder al archivo de audio. Importancia:
Facilita el acceso al archivo de audio subido desde el navegador o desde otros componentes de la aplicación. Consideración de Formato:
Es recomendable utilizar urljoin o métodos específicos de Django para construir URLs, ya que os.path.join puede no manejar correctamente las barras en URLs.
1.8.11. Devolución de la Respuesta JSON con la URL y Ruta del Archivo en Asterisk
Propósito:
Devuelve una respuesta JSON indicando que la operación fue exitosa.
Incluye:
'audioFile': La URL pública del archivo de audio subido.
'asteriskFile': La ruta completa al archivo de audio en el directorio de Asterisk.
Importancia:
Proporciona al cliente información relevante sobre la ubicación del archivo de audio, permitiendo su uso inmediato en la aplicación o en sistemas externos como Asterisk.
1.8.12. Manejo de Excepciones
Propósito:
Captura cualquier excepción que ocurra durante el proceso de carga, almacenamiento y copia del archivo.
Devuelve una respuesta JSON con un mensaje de error y un código de estado 500, indicando un error interno del servidor.
Importancia:
Asegura que los errores sean manejados de manera controlada, proporcionando retroalimentación adecuada al cliente sobre el fallo de la operación.
1.9. delete_audio.
La función delete_audio es una vista de Django que procesa solicitudes POST para eliminar archivos de audio asociados a nodos de tipo "node2" o "node6" dentro de una pestaña específica. La función extrae información relevante de la solicitud, valida los datos proporcionados, construye la ruta del archivo de audio a eliminar y, si el archivo existe, lo elimina del sistema de archivos. Finalmente, devuelve una respuesta JSON que indica el éxito o el fallo de la operación de eliminación.
1.9.1. Decorador @csrf_exempt
Propósito:
Exención de CSRF: El decorador @csrf_exempt exime a esta vista de la protección contra ataques CSRF (Cross-Site Request Forgery). Esto es útil para vistas que están destinadas a ser consumidas por APIs externas o clientes que no manejan tokens CSRF.
Consideración de Seguridad:
Riesgo: Al eximir la protección CSRF, se debe asegurar que la vista esté protegida por otros mecanismos de seguridad, como autenticación y autorización, para evitar que actores maliciosos puedan realizar solicitudes no autorizadas.
Recomendación: Implementar autenticación (por ejemplo, tokens de API, OAuth) para asegurarse de que solo usuarios autorizados puedan acceder a esta vista.
1.9.2. Verificación del Método de Solicitud
Propósito:
Restricción de Método: Asegura que solo se procesen solicitudes HTTP POST. Si la solicitud no es POST, devuelve una respuesta de error con el código de estado 405 (Método No Permitido).
Importancia:
Seguridad y Correctitud: Limitar la vista a métodos específicos ayuda a prevenir el uso indebido de la misma y garantiza que la lógica de eliminación de archivos se ejecute únicamente en el contexto adecuado.
1.9.3. Bloque try-except para Manejo de Excepciones
Propósito:
Manejo de Errores: Envuelve la lógica principal en un bloque try-except para capturar y manejar cualquier excepción que ocurra durante la ejecución. Si ocurre una excepción, devuelve una respuesta JSON con un mensaje de error y un código de estado 500 (Error Interno del Servidor).
Consideración:
Captura de Excepciones Generales: Capturar excepciones generales (Exception) puede ocultar errores específicos. Es más robusto capturar y manejar excepciones específicas para proporcionar respuestas más precisas y facilitar la depuración.
Recomendación:
Capturar Excepciones Específicas: Considerar capturar excepciones específicas como FileNotFoundError, PermissionError, etc., para manejar diferentes escenarios de error de manera adecuada.
1.9.4. Extracción y Validación de Datos del Cuerpo de la Solicitud
Propósito: Parseo del JSON: Convierte el cuerpo de la solicitud de formato JSON a un diccionario de Python utilizando json.loads. Extracción de Campos: Obtiene los valores de 'tabId', 'nodeId', 'nodeType' y 'oldAudioFile'. Validación de Datos: Verifica que todos los campos necesarios estén presentes y no sean None o vacíos. Si falta alguno, devuelve una respuesta de error indicando que los datos están incompletos con un código de estado 400 (Solicitud Incorrecta). Importancia:
Integridad de Datos: Garantiza que la función reciba todos los datos necesarios para procesar la eliminación de archivos correctamente. Consideraciones Adicionales:
Validación de Tipos de Datos: Además de verificar la presencia de los campos, sería beneficioso validar que los valores sean del tipo y formato esperado (por ejemplo, que tab_id y node_id sean enteros o cadenas alfanuméricas). Recomendación:
Uso de Esquemas de Validación: Considerar utilizar bibliotecas como django-rest-framework o pydantic para validar de manera más robusta los datos de entrada.
1.9.5. Verificación del Tipo de Nodo
Propósito:
Restricción de Tipo de Nodo: La función está diseñada para eliminar archivos de audio únicamente asociados a nodos de tipo "node2" o "node6". Si el tipo de nodo proporcionado no es uno de estos, devuelve una respuesta de error con un mensaje correspondiente y un código de estado 400 (Solicitud Incorrecta).
Importancia:
Seguridad y Correctitud: Asegura que la función no intente eliminar archivos asociados a nodos que no deberían tener archivos de audio, evitando operaciones innecesarias o erróneas.
1.9.6. Construcción de la Ruta Completa del Archivo de Audio
Propósito: Construcción de Ruta: Crea la ruta absoluta del archivo de audio a eliminar al eliminar la parte de la URL (settings.MEDIA_URL) y unir el resto con settings.BASE_DIR. Importancia:
Localización del Archivo: Permite ubicar correctamente el archivo en el sistema de archivos del servidor para proceder a su eliminación. Consideraciones de Seguridad:
Inyección de Rutas: Existe el riesgo de que old_audio_file contenga rutas manipuladas que podrían apuntar a archivos sensibles fuera del directorio previsto.
1.9.7. Eliminación del Archivo de Audio si Existe
Propósito:
Verificación de Existencia: Utiliza os.path.exists para verificar si el archivo de audio especificado existe en la ruta construida.
Eliminación del Archivo: Si el archivo existe, lo elimina utilizando os.remove.
Importancia:
Operación Segura: Realiza la operación de eliminación solo si el archivo realmente existe, evitando errores que podrían ocurrir si se intenta eliminar un archivo inexistente. Consideraciones Adicionales:
Manejo de Permisos: Asegurarse de que el usuario que ejecuta la aplicación Django tenga los permisos necesarios para eliminar el archivo.
1.9.8. Devolución de la Respuesta JSON de Éxito
Propósito:
Confirmación de Éxito: Después de eliminar el archivo (o si el archivo no existe), devuelve una respuesta JSON indicando que la operación fue exitosa con un mensaje correspondiente y un código de estado 200 (OK) implícito.
Importancia:
Retroalimentación al Cliente: Informa al cliente que la operación de eliminación se completó correctamente, permitiendo acciones posteriores basadas en esta confirmación.
1.10. rename_audio.
La función rename_audio es una vista de Django que procesa solicitudes POST para renombrar archivos de audio (.wav) asociados a nodos de tipo "node2" o "node6" dentro de una pestaña específica (tabId). La función realiza varias operaciones, incluyendo la validación de datos, la sanitización de nombres de archivos, la renombración del archivo en el sistema de archivos de Django, la copia del archivo renombrado al directorio de Asterisk y la generación de una URL para acceder al archivo renombrado.
1.10.1. Decorador @csrf_exempt.
Propósito:
Exención de CSRF: El decorador @csrf_exempt exime a esta vista de la protección contra ataques CSRF (Cross-Site Request Forgery). Esto es útil para vistas que están destinadas a ser consumidas por APIs externas o clientes que no manejan tokens CSRF.
Consideración de Seguridad:
Riesgo: Al eximir la protección CSRF, se debe asegurar que la vista esté protegida por otros mecanismos de seguridad, como autenticación y autorización, para evitar que actores maliciosos puedan realizar solicitudes no autorizadas.
Recomendación: Implementar autenticación (por ejemplo, tokens de API, OAuth) para asegurarse de que solo usuarios autorizados puedan acceder a esta vista.
1.10.2. Verificación del Método de Solicitud
Propósito:
Restricción de Método: Asegura que la función solo procese solicitudes HTTP POST. Si la solicitud no es POST, devuelve una respuesta de error con el código de estado 405 (Método No Permitido).
Importancia:
Seguridad y Correctitud: Limitar la vista a métodos específicos ayuda a prevenir el uso indebido de la misma y garantiza que la lógica de renombramiento de archivos se ejecute únicamente en el contexto adecuado.
1.10.3. Bloque try-except para Manejo de Excepciones
Manejo de Errores: Envuelve la lógica principal en un bloque try-except para capturar y manejar cualquier excepción que ocurra durante la ejecución. Si ocurre una excepción, devuelve una respuesta JSON con un mensaje de error y un código de estado 500 (Error Interno del Servidor). Consideración:
Captura de Excepciones Generales: Capturar excepciones generales (Exception) puede ocultar errores específicos. Es más robusto capturar y manejar excepciones específicas para proporcionar respuestas más precisas y facilitar la depuración. Recomendación:
Capturar Excepciones Específicas: Considerar capturar excepciones como FileNotFoundError, PermissionError, etc., para manejar diferentes escenarios de error de manera adecuada.
1.10.4. Extracción y Validación de Datos del Cuerpo de la Solicitud
Parseo del JSON: Convierte el cuerpo de la solicitud de formato JSON a un diccionario de Python utilizando json.loads. Extracción de Campos: Obtiene los valores de 'tabId', 'nodeId', 'nodeType', 'oldTitle', 'newTitle' y 'currentAudioFile'. Validación de Datos: Verifica que todos los campos necesarios estén presentes y no sean None o vacíos. Si falta alguno, devuelve una respuesta de error indicando que los datos están incompletos con un código de estado 400 (Solicitud Incorrecta). Importancia:
Integridad de Datos: Garantiza que la función reciba todos los datos necesarios para procesar el renombramiento de archivos correctamente. Consideraciones Adicionales:
Validación de Tipos de Datos: Además de verificar la presencia de los campos, sería beneficioso validar que los valores sean del tipo y formato esperado (por ejemplo, que tab_id y node_id sean enteros o cadenas alfanuméricas). Recomendación:
Uso de Esquemas de Validación: Considerar utilizar bibliotecas como django-rest-framework o pydantic para validar de manera más robusta los datos de entrada.
1.10.5. Verificación del Tipo de Nodo
Propósito:
Restricción de Tipo de Nodo: La función está diseñada para renombrar archivos de audio únicamente asociados a nodos de tipo "node2" o "node6". Si el tipo de nodo proporcionado no es uno de estos, devuelve una respuesta de error con un mensaje correspondiente y un código de estado 400 (Solicitud Incorrecta).
Importancia:
Seguridad y Correctitud: Asegura que la función no intente renombrar archivos asociados a nodos que no deberían tener archivos de audio, evitando operaciones innecesarias o erróneas.
1.10.6. Creación de Directorios Necesarios para Almacenar el Archivo de Audio
Propósito:
Construcción de Rutas:
audio_dir: Ruta al subdirectorio audio_files dentro del directorio específico de la pestaña (tab_<tab_id>) en el directorio de medios configurado en Django (MEDIA_ROOT).
Creación de Directorios:
Utiliza os.makedirs con exist_ok=True para crear los directorios necesarios si no existen. Si ya existen, no genera un error.
Importancia:
Estructura de Directorios: Asegura que la estructura de directorios necesaria para almacenar los archivos de audio exista antes de intentar renombrar o copiar archivos en ella, evitando errores relacionados con directorios inexistentes.
1.10.7. Generación de Nombres de Archivos Seguros y Únicos
Sanitización de Títulos: Utiliza la función get_safe_filename para crear versiones seguras de los títulos antiguos y nuevos, reemplazando caracteres no alfanuméricos con guiones bajos (_). Esto previene problemas con nombres de archivos que contengan caracteres especiales o inválidos. Construcción del Nombre del Archivo: Base del Nombre del Archivo: Combina el node_id con el título sanitizado para formar la base del nombre del archivo. Nombre Completo del Archivo: Añade la extensión .wav para completar el nombre del archivo. Construcción de las Rutas Completa: Combina audio_dir con los nombres de archivo para obtener las rutas completas de los archivos antiguos y nuevos. Importancia:
Nombres de Archivos Seguros: Asegura que los nombres de archivos sean seguros y compatibles con el sistema de archivos. Unicidad: Al incluir node_id en el nombre del archivo, se reduce la posibilidad de colisiones de nombres de archivos. Recomendación:
Uso Consistente de Funciones de Sanitización: Asegurarse de utilizar funciones de sanitización consistentes en toda la aplicación para evitar inconsistencias y vulnerabilidades.
1.10.8. Renombrar el Archivo de Audio
Propósito:
Verificación de Existencia del Archivo Original: Utiliza os.path.exists para verificar si el archivo de audio antiguo existe en la ruta construida.
Renombramiento del Archivo: Si el archivo existe, lo renombra utilizando os.rename, cambiando su nombre de old_wav_filename a new_wav_filename.
Copia del Archivo Renombrado a Asterisk:
Definición del Directorio de Asterisk: Especifica la ruta al directorio donde Asterisk almacena los archivos de audio (/var/lib/asterisk/sounds).
Construcción de la Ruta Completa del Archivo en Asterisk: Combina asterisk_dir con new_wav_filename para obtener la ruta completa donde se copiará el archivo.
Copia del Archivo: Utiliza shutil.copy para copiar el archivo renombrado desde el directorio de medios de Django al directorio de Asterisk.
Generación de la URL del Nuevo Archivo:
Combina settings.MEDIA_URL con la ruta relativa al archivo de audio para generar una URL accesible públicamente que puede ser utilizada por el frontend u otros servicios para reproducir o acceder al archivo de audio.
Reemplaza las barras invertidas () por barras normales (/) para asegurar la compatibilidad en sistemas Windows.
Respuesta de Éxito: Devuelve una respuesta JSON indicando que la operación fue exitosa, incluyendo la URL del nuevo archivo de audio.
Manejo de Archivo Inexistente: Si el archivo de audio antiguo no existe, devuelve una respuesta JSON indicando que el archivo original no fue encontrado con un código de estado 404 (No Encontrado).
Importancia:
Actualización de Referencias: Al renombrar el archivo y copiarlo a Asterisk, se asegura que el sistema de telefonía tiene acceso al archivo actualizado.
Integridad de Datos: Evita que referencias a archivos antiguos queden obsoletas, manteniendo la coherencia en la aplicación.
Consideraciones de Seguridad:
Permisos de Escritura en Directorios de Asterisk: Asegurarse de que el usuario que ejecuta la aplicación Django tenga los permisos necesarios para escribir en el directorio de Asterisk.
Validación de Rutas: Asegurar que las rutas construidas no puedan ser manipuladas para acceder a ubicaciones no autorizadas.
1.10.9. Devolución de la Respuesta JSON de Éxito o Error
Propósito:
Confirmación de Éxito: Después de renombrar y copiar el archivo, devuelve una respuesta JSON indicando que la operación fue exitosa.
Información Adicional: Incluye la URL pública del nuevo archivo de audio, lo que permite su uso inmediato en la aplicación o en sistemas externos como Asterisk.
Importancia:
Retroalimentación al Cliente: Informa al cliente que la operación de renombramiento y copia se completó correctamente, permitiendo acciones posteriores basadas en esta confirmación.
Error (Archivo Original No Encontrado):
Propósito:
Notificación de Error: Informa al cliente que el archivo de audio original que se intentó renombrar no fue encontrado, con un código de estado 404 (No Encontrado).
Importancia:
Claridad en la Comunicación: Proporciona una razón clara por la cual la operación no pudo completarse, lo que facilita la resolución del problema.
1.11. rename_tab.
La función rename_tab es una vista de Django que procesa solicitudes POST para renombrar una pestaña específica (tab) en la aplicación. Este proceso implica localizar el archivo JSON correspondiente a la pestaña, renombrar el archivo en el sistema de archivos y actualizar el contenido interno del JSON para reflejar el nuevo nombre de la pestaña. La función garantiza que el nuevo nombre sea seguro para el sistema de archivos y maneja posibles errores que puedan surgir durante el proceso.
1.11.1. Decorador @csrf_exempt
Propósito:
Exención de CSRF: El decorador @csrf_exempt exime a esta vista de la protección contra ataques CSRF (Cross-Site Request Forgery). Esto es útil para vistas que están destinadas a ser consumidas por APIs externas o clientes que no manejan tokens CSRF.
Consideración de Seguridad:
Riesgo: Al eximir la protección CSRF, se incrementa la vulnerabilidad a ataques CSRF, donde un atacante podría realizar solicitudes no autorizadas en nombre de un usuario autenticado.
Recomendación: Si es posible, evita eximir la protección CSRF. En su lugar, implementa mecanismos de autenticación robustos, como tokens de autenticación, para asegurar que solo usuarios autorizados puedan acceder a esta vista. Si es absolutamente necesario eximir CSRF, asegúrate de que otros mecanismos de seguridad estén en su lugar.
1.11.2. Verificación del Método de Solicitud
Propósito:
Restricción de Método: Asegura que solo se procesen solicitudes HTTP POST. Si la solicitud no es POST, devuelve una respuesta de error con el código de estado 405 (Método No Permitido).
Importancia:
Seguridad y Correctitud: Limita el acceso a la funcionalidad de renombramiento únicamente a solicitudes POST, evitando métodos HTTP no deseados como GET, PUT o DELETE que podrían ser utilizados de manera inapropiada.
1.11.3. Bloque try-except para Manejo de Excepciones
Propósito:
Manejo de Errores: Envuelve la lógica principal en un bloque try-except para capturar y manejar cualquier excepción que ocurra durante la ejecución. Si ocurre una excepción, devuelve una respuesta JSON con un mensaje de error y un código de estado 500 (Error Interno del Servidor).
Consideración:
Captura de Excepciones Generales: Capturar excepciones generales (Exception) puede ocultar errores específicos, lo que dificulta la identificación y resolución de problemas.
Recomendación: Es más robusto capturar y manejar excepciones específicas para proporcionar mensajes de error más precisos y manejar diferentes tipos de errores de manera adecuada.
1.11.4. Extracción y Validación de Datos del Cuerpo de la Solicitud
Propósito:
Parseo del JSON: Convierte el cuerpo de la solicitud de formato JSON a un diccionario de Python utilizando json.loads.
Extracción de Campos: Obtiene los valores de 'tabId' y 'newTabName'.
Validación de Datos: Verifica que ambos campos estén presentes y no sean None o vacíos. Si falta alguno, devuelve una respuesta de error indicando que los datos están incompletos con un código de estado 400 (Solicitud Incorrecta).
Importancia:
Integridad de Datos: Garantiza que la función reciba todos los datos necesarios para procesar correctamente el renombramiento de la pestaña.
Recomendaciones Adicionales:
Validación de Tipos de Datos: Además de verificar la presencia de los campos, sería beneficioso validar que los valores sean del tipo y formato esperado (por ejemplo, que tab_id sea un entero o una cadena alfanumérica válida).
Manejo de json.JSONDecodeError: Capturar errores específicos al parsear JSON, como json.JSONDecodeError, para manejar casos donde el cuerpo de la solicitud no es un JSON válido.
1.11.5. Sanitización del Nuevo Nombre de la Pestaña
Propósito:
Sanitización: Utiliza una función get_safe_filename (presumiblemente definida en otro lugar) para sanitizar el new_tab_name, asegurando que no contenga caracteres inválidos que puedan causar problemas en el sistema de archivos.
Importancia:
Prevención de Vulnerabilidades: Evita la inyección de rutas y otros problemas relacionados con nombres de archivos inválidos o maliciosos.
1.11.6. Construcción de la Ruta al Directorio de Datos
Propósito:
Definición de Ruta: Construye la ruta completa al directorio flow/data dentro del directorio base del proyecto Django utilizando os.path.join para asegurar compatibilidad entre diferentes sistemas operativos.
Importancia:
Organización de Archivos: Centraliza la ubicación de los archivos JSON de las pestañas, facilitando su gestión y acceso.
1.11.7. Búsqueda del Archivo JSON Correspondiente al tab_id
Propósito:
Listado de Archivos: Utiliza os.listdir(data_dir) para listar todos los archivos en el directorio flow/data.
Filtrado de Archivos: Filtra los archivos que comienzan con tab_<tab_id>_ y terminan con .json, asegurando que coincidan con el patrón esperado para el archivo de la pestaña.
Verificación de Existencia: Si no se encuentran archivos coincidentes (matching_files está vacío), devuelve una respuesta JSON con un mensaje de error y un código de estado 404 (No Encontrado).
Importancia:
Localización Correcta: Garantiza que la función opera sobre el archivo correcto asociado al tab_id proporcionado.
1.11.8. Renombramiento del Archivo JSON y Actualización del Contenido Interno
Propósito:
Definición de Rutas:
old_filename y old_file_path: Determinan el nombre y la ruta del archivo JSON original de la pestaña.
new_filename y new_file_path: Generan el nuevo nombre y ruta para el archivo JSON renombrado.
Renombramiento del Archivo:
Utiliza os.rename para cambiar el nombre del archivo JSON en el sistema de archivos.
Actualización del Contenido del JSON:
Abre el archivo JSON renombrado, carga su contenido, actualiza el campo 'tabName' con el nuevo nombre proporcionado (new_tab_name), y guarda los cambios de vuelta al archivo JSON con una indentación de 4 espacios para mejorar la legibilidad.
Respuesta de Éxito:
Devuelve una respuesta JSON indicando que la pestaña ha sido renombrada exitosamente.
Importancia:
Consistencia de Datos: Asegura que tanto el nombre del archivo en el sistema de archivos como el contenido interno del JSON reflejen el nuevo nombre de la pestaña.
1.11.9. Manejo de Excepciones y Respuesta de Error
Propósito:
Captura de Errores: Captura cualquier excepción que ocurra durante la ejecución de la función y devuelve una respuesta JSON con el mensaje de error y un código de estado 500 (Error Interno del Servidor).
Importancia:
Retroalimentación al Cliente: Informa al cliente que ocurrió un error durante el procesamiento de la solicitud.
1.12. update_node4.
La función update_node4 es una vista de Django que procesa solicitudes POST para actualizar el atributo extensionNumber de un nodo de tipo "node4" dentro de un archivo JSON que representa una pestaña específica. Este proceso implica extraer y validar los datos de la solicitud, localizar el archivo JSON correspondiente a la pestaña, buscar y actualizar el nodo objetivo dentro del JSON, y guardar los cambios de vuelta al archivo.
1.12.1. Decorador @csrf_exempt
Propósito:
Exención de CSRF: El decorador @csrf_exempt exime a esta vista de la protección contra ataques CSRF (Cross-Site Request Forgery). Esto es útil para vistas que están destinadas a ser consumidas por APIs externas o clientes que no manejan tokens CSRF.
1.12.2. Verificación del Método de Solicitud
Propósito:
Restricción de Método: Asegura que solo se procesen solicitudes HTTP POST. Si la solicitud no es POST, devuelve una respuesta de error con el código de estado 405 (Método No Permitido).
1.12.3. Bloque try-except para Manejo de Excepciones
Propósito:
Manejo de Errores: Envuelve la lógica principal en un bloque try-except para capturar y manejar cualquier excepción que ocurra durante la ejecución. Si ocurre una excepción, devuelve una respuesta JSON con un mensaje de error y un código de estado 500 (Error Interno del Servidor).
1.12.4. Extracción y Validación de Datos del Cuerpo de la Solicitud
Propósito:
Parseo del JSON: Convierte el cuerpo de la solicitud de formato JSON a un diccionario de Python utilizando json.loads.
Extracción de Campos: Obtiene los valores de 'tabId', 'tabName', 'nodeId', 'nodeType' y 'extensionNumber'.
Validación de Datos: Verifica que todos los campos necesarios estén presentes y que extension_number no sea None. Si falta alguno, devuelve una respuesta de error indicando que los datos están incompletos con un código de estado 400 (Solicitud Incorrecta).
1.12.5. Verificación del Tipo de Nodo
Propósito:
Restricción de Tipo de Nodo: La función está diseñada para actualizar nodos de tipo "node4". Si el tipo de nodo proporcionado no es "node4", devuelve una respuesta de error con un mensaje correspondiente y un código de estado 400 (Solicitud Incorrecta).
1.12.6. Localización del Archivo JSON de la Pestaña
Propósito:
Construcción de la Ruta del Directorio de Datos: Define la ruta al directorio flow/data dentro del directorio base del proyecto Django.
Búsqueda del Archivo JSON: Lista todos los archivos en data_dir y filtra aquellos que coinciden con el patrón tab_<tab_id>_*.json utilizando una expresión regular.
Verificación de Existencia: Si no se encuentra ningún archivo que coincida, devuelve una respuesta JSON con un mensaje de error y un código de estado 404 (No Encontrado).
Definición de la Ruta Completa del Archivo: Toma el primer archivo coincidente y construye la ruta completa al mismo.
1.12.7. Carga y Actualización del Archivo JSON
Propósito:
Carga del Archivo JSON: Abre el archivo JSON de la pestaña en modo lectura y carga su contenido en el diccionario tab_data.
Búsqueda y Actualización del Nodo:
Itera sobre la lista de nodos (nodes) en tab_data.
Busca un nodo que coincida con el node_id proporcionado y que sea de tipo "node4".
Si encuentra el nodo, actualiza su atributo extensionNumber con el valor proporcionado y establece node_found en True.
Si no encuentra el nodo, devuelve una respuesta JSON con un mensaje de error y un código de estado 404 (No Encontrado).
Guardado de Cambios en el Archivo JSON: Abre el archivo JSON en modo escritura y guarda el diccionario tab_data actualizado con una indentación de 4 espacios para mejorar la legibilidad.
Respuesta de Éxito: Devuelve una respuesta JSON indicando que el nodo4 ha sido actualizado exitosamente.
1.13. tts_module.
La función tts_module es una vista de Django que procesa solicitudes HTTP POST para generar archivos de audio a partir de un texto proporcionado. Utiliza la biblioteca gTTS (Google Text-to-Speech) para convertir el texto en audio, ajusta la velocidad del audio utilizando pydub, convierte el archivo a formato WAV a 8000 Hz, y finalmente guarda el archivo en el sistema de archivos de Django y lo copia al directorio de Asterisk para su uso en sistemas de telefonía.
1.13.1. Decorador @csrf_exempt
Propósito:
Exención de CSRF: El decorador @csrf_exempt exime a esta vista de la protección contra ataques CSRF (Cross-Site Request Forgery). Esto es útil para vistas que están destinadas a ser consumidas por APIs externas o clientes que no manejan tokens CSRF.
1.13.2. Verificación del Método de Solicitud
Propósito:
Restricción de Método: Asegura que solo se procesen solicitudes HTTP POST. Si la solicitud no es POST, devuelve una respuesta de error con el código de estado 405 (Método No Permitido).
1.13.3. Bloque try-except para Manejo de Excepciones
Propósito:
Manejo de Errores: Envuelve la lógica principal en un bloque try-except para capturar y manejar cualquier excepción que ocurra durante la ejecución. Si ocurre una excepción, devuelve una respuesta JSON con un mensaje de error y un código de estado 500 (Error Interno del Servidor).
1.13.4. Extracción y Validación de Datos del Cuerpo de la Solicitud
Propósito:
Parseo del JSON: Convierte el cuerpo de la solicitud de formato JSON a un diccionario de Python utilizando json.loads.
Extracción de Campos: Obtiene los valores de 'tabId', 'title', 'text', 'nodeId' y 'nodeType'.
Validación de Datos: Verifica que todos los campos necesarios estén presentes y no sean None o vacíos. Si falta alguno, devuelve una respuesta de error indicando que los datos están incompletos con un código de estado 400 (Solicitud Incorrecta).
1.13.5. Definición y Creación de Directorios Específicos para la Pestaña
Propósito:
Construcción de Rutas:
audio_dir: Ruta al subdirectorio audio_files dentro del directorio específico de la pestaña (tab_<tab_id>) en el directorio de medios configurado en Django (MEDIA_ROOT).
Creación de Directorios:
Utiliza os.makedirs con exist_ok=True para crear los directorios necesarios si no existen. Si ya existen, no genera un error.
1.13.6. Generación del Nombre Único para el Archivo de Audio
Propósito:
Construcción del Nombre del Archivo:
Combina title, node_type y node_id para formar un nombre único para el archivo de audio con la extensión .wav.
Construcción de la Ruta Completa:
Combina audio_dir y wav_filename para obtener la ruta completa al archivo de audio que se desea guardar.
1.13.7. Conversión de Texto a Voz utilizando gTTS
Propósito:
Creación del Objeto TTS:
Utiliza gTTS para convertir el texto proporcionado en audio, especificando el idioma (language) y la velocidad (slow=False).
Guardado del Archivo de Audio:
Guarda el archivo de audio generado en formato MP3 temporalmente en speech.mp3.
1.13.8. Ajuste de la Velocidad del Audio con pydub
Propósito:
Carga del Archivo de Audio:
Utiliza pydub para cargar el archivo MP3 generado (speech.mp3).
Ajuste de Velocidad:
Aumenta la velocidad del audio en un factor de 1.1 (10% más rápido) modificando la tasa de cuadros (frame_rate).
Configuración de la Tasa de Cuadros:
Restablece la tasa de cuadros al valor original para mantener la calidad del audio después del ajuste de velocidad.
1.13.9. Conversión del Audio a Formato WAV a 8000 Hz
Propósito:
Conversión de Formato:
Convierte el audio ajustado a formato WAV con una tasa de cuadros de 8000 Hz.
Exportación del Archivo de Audio:
Guarda el archivo WAV en la ruta especificada (wav_filepath).
1.13.10. Eliminación del Archivo Temporal MP3
Propósito:
Limpieza de Archivos Temporales:
Elimina el archivo MP3 temporal (speech.mp3) ya que ya se ha generado y guardado el archivo WAV final.
1.13.11. Copia del Archivo de Audio al Directorio de Asterisk
Propósito:
Definición del Directorio de Asterisk:
Especifica la ruta al directorio donde Asterisk almacena los archivos de audio (/var/lib/asterisk/sounds).
Creación del Directorio:
Asegura que el directorio de Asterisk exista, creando los directorios necesarios si no existen.
Construcción de la Ruta Completa:
Combina asterisk_dir y wav_filename para obtener la ruta completa donde se copiará el archivo de audio.
Copia del Archivo:
Utiliza shutil.copy para copiar el archivo WAV generado desde el directorio de medios de Django al directorio de Asterisk.
1.13.12. Generación de la URL del Archivo de Audio
Propósito:
Construcción de la URL:
Combina settings.MEDIA_URL con la ruta relativa al archivo de audio para generar una URL accesible públicamente que puede ser utilizada por el frontend u otros servicios para reproducir o acceder al archivo de audio.
1.13.13. Respuesta de Éxito
Propósito:
Confirmación de Éxito:
Devuelve una respuesta JSON indicando que la operación fue exitosa.
Incluye:
'audioFile': La URL pública del archivo de audio generado.
'message': Un mensaje de confirmación de que el audio se ha guardado correctamente.
1.13.14. Manejo de Excepciones
Propósito:
Captura de Errores:
Captura cualquier excepción que ocurra durante el proceso y devuelve una respuesta JSON con un mensaje de error y un código de estado 500 (Error Interno del Servidor).
Table of Contents
- 1. views.py
- 1.1. get_safe_filename()
- 1.2. create_tabs_flow()
- 1.3. list_tabs()
- 1.3.1. Definición de la Función.
- 1.3.2. Docstring.
- 1.3.3. Construcción de la Ruta al Directorio de Datos.
- 1.3.4. Verificación de la Existencia del Directorio.
- 1.3.5. Iteración Sobre los Archivos del Directorio.
- 1.3.6. Extracción de tabId y tabName del Nombre del Archivo.
- 1.3.7. Lectura del Contenido del Archivo JSON
- 1.3.8. Agregando la Pestaña a la Lista.
- 1.3.9. Retorno de la Respuesta JSON.
- 1.4. save_tts.
- 1.4.1. Decorador @csrf_exempt.
- 1.4.2. Verificación del Método de Solicitud.
- 1.4.3. Manejo de Excepciones Generales.
- 1.4.4. Extracción y Validación de Datos del Cuerpo de la Solicitud.
- 1.4.5. Formateo del Nombre del Archivo de Audio.
- 1.4.6. Construcción de la Ruta del Archivo Python AGI.
- 1.4.7. Generación del Contenido del Archivo Python AGI.
- 1.4.8. Escritura del Archivo AGI y Configuración de Permisos.
- 1.4.9. Respuesta de Éxito.
- 1.5. save_tab_data.
- 1.5.1. Decorador @csrf_exempt.
- 1.5.2. Verificación del Método de Solicitud.
- 1.5.3. Manejo de Excepciones Generales.
- 1.5.4. Extracción y Validación de Datos del Cuerpo de la Solicitud.
- 1.5.5. Sanitización del Nombre de la Pestaña.
- 1.5.6. Formateo y Construcción de la Ruta del Archivo JSON.
- 1.5.7. Filtrado y Procesamiento de Nodos
- 1.5.8. Creación de Directorios Necesarios
- 1.5.9. Guardado del Archivo JSON de la Pestaña
- 1.5.10. Extracción y Guardado de Condiciones de node3
- 1.5.11. Respuesta de Éxito
- 1.6. load_tab_data.
- 1.6.1. Definición de la Función y Docstring
- 1.6.2. Bloque try-except para Manejo de Excepciones
- 1.6.3. Construcción de la Ruta al Directorio de Datos
- 1.6.4. Búsqueda del Archivo JSON Correspondiente al tab_id
- 1.6.5. Carga de los Datos desde el Archivo JSON
- 1.6.6. Procesamiento de los Nodos para Eliminar el Atributo audioFile
- 1.6.7. Devolución de la Respuesta JSON con los Datos Procesados
- 1.6.8. Manejo de Excepciones y Registro de Errores
- 1.7. delete_files.
- 1.7.1. Decorador @csrf_exempt
- 1.7.2. Verificación del Método de Solicitud.
- 1.7.3. Bloque try-except para Manejo de Excepciones
- 1.7.4. Extracción y Validación de Datos del Cuerpo de la Solicitud
- 1.7.5. Verificación del Tipo de Nodo
- 1.7.6. Construcción de las Rutas de los Directorios y Archivos
- 1.7.7. Generación del Nombre y Ruta del Archivo de Texto a Eliminar
- 1.7.8. Eliminación del Archivo de Texto si Existe
- 1.7.9. Devolución de la Respuesta de Éxito
- 1.8. upload_audio.
- 1.8.1. Decorador @csrf_exempt.
- 1.8.2. Verificación del Método de Solicitud
- 1.8.3. Bloque try-except para Manejo de Excepciones
- 1.8.4. Extracción y Validación de Datos del Cuerpo de la Solicitud
- 1.8.5. Verificación del Tipo de Nodo
- 1.8.6. Creación de Directorios Necesarios para Almacenar el Archivo de Audio
- 1.8.7. Generación de un Nombre de Archivo Único para el Archivo de Audio
- 1.8.8. Guardado del Archivo de Audio en el Directorio de Medios
- 1.8.9. Copia del Archivo de Audio al Directorio de Grabaciones de Asterisk
- 1.8.10. Generación de la URL del Archivo de Audio
- 1.8.11. Devolución de la Respuesta JSON con la URL y Ruta del Archivo en Asterisk
- 1.8.12. Manejo de Excepciones
- 1.9. delete_audio.
- 1.9.1. Decorador @csrf_exempt
- 1.9.2. Verificación del Método de Solicitud
- 1.9.3. Bloque try-except para Manejo de Excepciones
- 1.9.4. Extracción y Validación de Datos del Cuerpo de la Solicitud
- 1.9.5. Verificación del Tipo de Nodo
- 1.9.6. Construcción de la Ruta Completa del Archivo de Audio
- 1.9.7. Eliminación del Archivo de Audio si Existe
- 1.9.8. Devolución de la Respuesta JSON de Éxito
- 1.10. rename_audio.
- 1.10.1. Decorador @csrf_exempt.
- 1.10.2. Verificación del Método de Solicitud
- 1.10.3. Bloque try-except para Manejo de Excepciones
- 1.10.4. Extracción y Validación de Datos del Cuerpo de la Solicitud
- 1.10.5. Verificación del Tipo de Nodo
- 1.10.6. Creación de Directorios Necesarios para Almacenar el Archivo de Audio
- 1.10.7. Generación de Nombres de Archivos Seguros y Únicos
- 1.10.8. Renombrar el Archivo de Audio
- 1.10.9. Devolución de la Respuesta JSON de Éxito o Error
- 1.11. rename_tab.
- 1.11.1. Decorador @csrf_exempt
- 1.11.2. Verificación del Método de Solicitud
- 1.11.3. Bloque try-except para Manejo de Excepciones
- 1.11.4. Extracción y Validación de Datos del Cuerpo de la Solicitud
- 1.11.5. Sanitización del Nuevo Nombre de la Pestaña
- 1.11.6. Construcción de la Ruta al Directorio de Datos
- 1.11.7. Búsqueda del Archivo JSON Correspondiente al tab_id
- 1.11.8. Renombramiento del Archivo JSON y Actualización del Contenido Interno
- 1.11.9. Manejo de Excepciones y Respuesta de Error
- 1.12. update_node4.
- 1.12.1. Decorador @csrf_exempt
- 1.12.2. Verificación del Método de Solicitud
- 1.12.3. Bloque try-except para Manejo de Excepciones
- 1.12.4. Extracción y Validación de Datos del Cuerpo de la Solicitud
- 1.12.5. Verificación del Tipo de Nodo
- 1.12.6. Localización del Archivo JSON de la Pestaña
- 1.12.7. Carga y Actualización del Archivo JSON
- 1.13. tts_module.
- 1.13.1. Decorador @csrf_exempt
- 1.13.2. Verificación del Método de Solicitud
- 1.13.3. Bloque try-except para Manejo de Excepciones
- 1.13.4. Extracción y Validación de Datos del Cuerpo de la Solicitud
- 1.13.5. Definición y Creación de Directorios Específicos para la Pestaña
- 1.13.6. Generación del Nombre Único para el Archivo de Audio
- 1.13.7. Conversión de Texto a Voz utilizando gTTS
- 1.13.8. Ajuste de la Velocidad del Audio con pydub
- 1.13.9. Conversión del Audio a Formato WAV a 8000 Hz
- 1.13.10. Eliminación del Archivo Temporal MP3
- 1.13.11. Copia del Archivo de Audio al Directorio de Asterisk
- 1.13.12. Generación de la URL del Archivo de Audio
- 1.13.13. Respuesta de Éxito
- 1.13.14. Manejo de Excepciones