Files
soft_usite/rest/controllers/ocr_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

85 lines
2.5 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 OcrConfigPage(c *fiber.Ctx) error {
cfg, _ := models.GetOcrConfig()
return c.Render("ocr_config", fiber.Map{
"user": c.Locals("user"),
"modules": c.Locals("userModules"),
"cfg": cfg,
}, "layouts/main")
}
func GetOcrConfigHandler(c *fiber.Ctx) error {
cfg, err := models.GetOcrConfig()
if err != nil {
return c.JSON(fiber.Map{"data": nil})
}
return c.JSON(fiber.Map{"data": cfg})
}
func SaveOcrConfigHandler(c *fiber.Ctx) error {
type body struct {
ID uint `json:"id"`
BaseURL string `json:"base_url"`
Token string `json:"token"`
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.Token == "" {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "token es requerido"})
}
cfg := models.OcrConfig{BaseURL: b.BaseURL, Token: b.Token, Notas: b.Notas}
cfg.ID = b.ID
if err := models.SaveOcrConfig(cfg); err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
}
return c.JSON(fiber.Map{"message": "Configuración guardada"})
}
// TestOcrConfigHandler recibe una imagen de prueba y devuelve el texto que
// extrae el servicio configurado — confirma que la URL/token funcionan de
// verdad, no solo que se guardaron.
func TestOcrConfigHandler(c *fiber.Ctx) error {
fh, err := c.FormFile("imagen")
if err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "imagen requerida"})
}
if fh.Size > 8*1024*1024 {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "máximo 8MB"})
}
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"})
}
mimeType := fh.Header.Get("Content-Type")
if mimeType == "" {
mimeType = "image/png"
}
texto, err := services.ExtraerTextoOCR(data, mimeType)
if err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": err.Error()})
}
return c.JSON(fiber.Map{"text": texto})
}