package handlers import ( "fmt" "io" "net/http" "os" "path/filepath" "time" "git.vakhrushev.me/av/transcriber/database" "git.vakhrushev.me/av/transcriber/models" "github.com/gin-gonic/gin" "github.com/google/uuid" ) type TranscribeHandler struct { db *database.DB } func NewTranscribeHandler(db *database.DB) *TranscribeHandler { return &TranscribeHandler{db: db} } type TranscribeResponse struct { JobID string `json:"job_id"` FileID string `json:"file_id"` Status string `json:"status"` } func (h *TranscribeHandler) UploadAndTranscribe(c *gin.Context) { // Получаем файл из формы file, header, err := c.Request.FormFile("audio") if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "No audio file provided"}) return } defer file.Close() // Генерируем UUID для файла fileID := uuid.New().String() // Определяем расширение файла ext := filepath.Ext(header.Filename) if ext == "" { ext = ".audio" // fallback если расширение не определено } // Создаем путь для сохранения файла fileName := fmt.Sprintf("%s%s", fileID, ext) filePath := filepath.Join("data", "files", fileName) // Создаем файл на диске dst, err := os.Create(filePath) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create file"}) return } defer dst.Close() // Копируем содержимое загруженного файла size, err := io.Copy(dst, file) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to save file"}) return } // Создаем запись в таблице files fileRecord := &models.File{ ID: fileID, Type: header.Header.Get("Content-Type"), Size: size, CreatedAt: time.Now(), } if err := h.db.CreateFile(fileRecord); err != nil { // Удаляем файл если не удалось создать запись в БД os.Remove(filePath) c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to save file record"}) return } // Создаем запись в таблице transcribe_jobs jobID := uuid.New().String() job := &models.TranscribeJob{ ID: jobID, Status: models.StatusPending, FileID: fileID, CreatedAt: time.Now(), UpdatedAt: time.Now(), } if err := h.db.CreateTranscribeJob(job); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create transcribe job"}) return } // Возвращаем успешный ответ response := TranscribeResponse{ JobID: jobID, FileID: fileID, Status: models.StatusPending, } c.JSON(http.StatusCreated, response) } func (h *TranscribeHandler) GetJobStatus(c *gin.Context) { jobID := c.Param("id") job, err := h.db.GetTranscribeJobByID(jobID) if err != nil { c.JSON(http.StatusNotFound, gin.H{"error": "Job not found"}) return } c.JSON(http.StatusOK, job) }