Files
soft_usite/rest/controllers/whisper_asr_controller.go
T
Lizandro GuarnizoandClaude Sonnet 5 d493d6dee6 feat: agrega integraciones OCR y Whisper ASR (servicios propios)
Nuevos submódulos en Integraciones para conectar el servicio propio de
OCR (extracción de texto de imágenes) y el de transcripción de audio
self-hosted (whisper-asr-webservice, Basic Auth), con panel de
configuración y prueba en vivo, siguiendo el patrón ya usado por
WebSMS/Hostinger.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-13 10:09:40 -05:00

81 lines
2.6 KiB
Go

package controllers
import (
"io"
"github.com/gofiber/fiber/v2"
"github.com/sujit-baniya/fiber-boilerplate/pkg/models"
"github.com/sujit-baniya/fiber-boilerplate/pkg/services"
)
func WhisperAsrConfigPage(c *fiber.Ctx) error {
cfg, _ := models.GetWhisperAsrConfig()
return c.Render("whisper_asr_config", fiber.Map{
"user": c.Locals("user"),
"modules": c.Locals("userModules"),
"cfg": cfg,
}, "layouts/main")
}
func GetWhisperAsrConfigHandler(c *fiber.Ctx) error {
cfg, err := models.GetWhisperAsrConfig()
if err != nil {
return c.JSON(fiber.Map{"data": nil})
}
return c.JSON(fiber.Map{"data": cfg})
}
func SaveWhisperAsrConfigHandler(c *fiber.Ctx) error {
type body struct {
ID uint `json:"id"`
BaseURL string `json:"base_url"`
Username string `json:"username"`
Password string `json:"password"`
Notas string `json:"notas"`
}
var b body
if err := c.BodyParser(&b); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "body inválido"})
}
if b.BaseURL == "" {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "base_url es requerida"})
}
if b.Username == "" || b.Password == "" {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "usuario y contraseña son requeridos"})
}
cfg := models.WhisperAsrConfig{BaseURL: b.BaseURL, Username: b.Username, Password: b.Password, Notas: b.Notas}
cfg.ID = b.ID
if err := models.SaveWhisperAsrConfig(cfg); err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
}
return c.JSON(fiber.Map{"message": "Configuración guardada"})
}
// TestWhisperAsrConfigHandler recibe un audio de prueba y devuelve la
// transcripción — confirma que la URL/credenciales funcionan de verdad.
func TestWhisperAsrConfigHandler(c *fiber.Ctx) error {
fh, err := c.FormFile("audio")
if err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "audio requerido"})
}
if fh.Size > 20*1024*1024 {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "máximo 20MB"})
}
f, err := fh.Open()
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "no se pudo leer el archivo"})
}
defer f.Close()
data, err := io.ReadAll(f)
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "no se pudo leer el archivo"})
}
texto, err := services.TranscribirAudioSelfHosted(data, fh.Filename)
if err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": err.Error()})
}
return c.JSON(fiber.Map{"text": texto})
}