File size: 2,767 Bytes
5c33153
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0a618d9
 
 
 
 
 
 
5c33153
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package controller

import (
	"fmt"
	"mime/multipart"

	models "github.com/abdanhafidz/ai-visual-multi-modal-backend/models"
	services "github.com/abdanhafidz/ai-visual-multi-modal-backend/services"
	utils "github.com/abdanhafidz/ai-visual-multi-modal-backend/utils"
	"github.com/gin-gonic/gin"
)

type (
	PredictionController interface {
		Controller
		Predict(ctx *gin.Context)
	}

	predictionController struct {
		*controller[services.PredictionService]
	}
)

func requestImage(ctx *gin.Context, image *multipart.File, imageFilename *string) {
	imageHeader, err := ctx.FormFile("image_file")
	if err != nil {
		utils.ResponseFAIL(ctx, 400, models.Exception{
			BadRequest: true,
			Message:    "Image file is required",
		})
		return
	}
	imageFile, err := imageHeader.Open()
	if err != nil {
		utils.ResponseFAIL(ctx, 400, models.Exception{
			BadRequest: true,
			Message:    "Failed to open image file",
		})
		return
	}
	*image = imageFile
	*imageFilename = imageHeader.Filename
	defer imageFile.Close()
}

func requestAudio(ctx *gin.Context, audio *multipart.File, audioFilename *string) {
	audioHeader, err := ctx.FormFile("audio_file")
	fmt.Println(audioHeader.Filename)
	if err != nil {
		utils.ResponseFAIL(ctx, 400, models.Exception{
			BadRequest: true,
			Message:    "Audio file is required",
		})
		return
	}
	audioFile, err := audioHeader.Open()
	if err != nil {
		utils.ResponseFAIL(ctx, 400, models.Exception{
			BadRequest: true,
			Message:    "Failed to open audio file",
		})
		return
	}
	*audio = audioFile
	*audioFilename = audioHeader.Filename
	defer audioFile.Close()
}

func NewPredictionController(predictionService services.PredictionService) PredictionController {
	return &predictionController{
		controller: &controller[services.PredictionService]{
			service: predictionService,
		},
	}
}
func (c *predictionController) Predict(ctx *gin.Context) {

	var predictionRequest models.PredictionRequest
	if err := ctx.ShouldBind(&predictionRequest); err != nil {
		utils.ResponseFAIL(ctx, 400, models.Exception{
			BadRequest: true,
			Message:    "Invalid request format",
		})
		return
	}
	requestImage(ctx, &predictionRequest.ImageFile, &predictionRequest.ImageFileName)
	requestAudio(ctx, &predictionRequest.AudioQuestionFile, &predictionRequest.AudioQuestionFilename)

	predictionResult, text_output := c.service.Predict(ctx.Request.Context(), predictionRequest)

	if c.service.Error() != nil {
		c.Response(ctx, nil)
		return
	}

	ctx.Header("Content-Type", "audio/mpeg")
	ctx.Header("Content-Disposition", "inline; filename=response.mp3")
	ctx.Header("X-Response-Text", text_output)
	ctx.Data(200, "audio/mpeg", predictionResult)
}