127 lines
3.2 KiB
Go
127 lines
3.2 KiB
Go
package media
|
|
|
|
import (
|
|
"errors"
|
|
"net/http"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
type Handler struct {
|
|
service *Service
|
|
}
|
|
|
|
func NewHandler(service *Service) *Handler {
|
|
return &Handler{service: service}
|
|
}
|
|
|
|
type mediaResponse struct {
|
|
ID uuid.UUID `json:"id"`
|
|
Filename string `json:"filename"`
|
|
URL string `json:"url"`
|
|
MimeType string `json:"mime_type"`
|
|
SizeBytes int64 `json:"size_bytes"`
|
|
AltText string `json:"alt_text"`
|
|
}
|
|
|
|
func toResponse(m *Media) mediaResponse {
|
|
return mediaResponse{
|
|
ID: m.ID,
|
|
Filename: m.Filename,
|
|
URL: m.URL,
|
|
MimeType: m.MimeType,
|
|
SizeBytes: m.SizeBytes,
|
|
AltText: m.AltText,
|
|
}
|
|
}
|
|
|
|
func (h *Handler) List(c *gin.Context) {
|
|
list, err := h.service.List(c.Request.Context())
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to list media"})
|
|
return
|
|
}
|
|
resp := make([]mediaResponse, 0, len(list))
|
|
for _, m := range list {
|
|
resp = append(resp, toResponse(m))
|
|
}
|
|
c.JSON(http.StatusOK, gin.H{"media": resp})
|
|
}
|
|
|
|
func (h *Handler) Upload(c *gin.Context) {
|
|
fileHeader, err := c.FormFile("file")
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "missing file field"})
|
|
return
|
|
}
|
|
|
|
file, err := fileHeader.Open()
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "failed to open uploaded file"})
|
|
return
|
|
}
|
|
defer file.Close()
|
|
|
|
contentType := fileHeader.Header.Get("Content-Type")
|
|
altText := c.PostForm("alt_text")
|
|
|
|
m, err := h.service.Upload(c.Request.Context(), fileHeader.Filename, file, fileHeader.Size, contentType, altText)
|
|
if err != nil {
|
|
switch {
|
|
case errors.Is(err, ErrFileTooLarge):
|
|
c.JSON(http.StatusRequestEntityTooLarge, gin.H{"error": "file exceeds the maximum allowed size"})
|
|
case errors.Is(err, ErrUnsupportedType):
|
|
c.JSON(http.StatusUnsupportedMediaType, gin.H{"error": "unsupported file type"})
|
|
default:
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to upload file"})
|
|
}
|
|
return
|
|
}
|
|
c.JSON(http.StatusCreated, toResponse(m))
|
|
}
|
|
|
|
type updateRequest struct {
|
|
AltText string `json:"alt_text"`
|
|
}
|
|
|
|
func (h *Handler) Update(c *gin.Context) {
|
|
id, err := uuid.Parse(c.Param("id"))
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid id"})
|
|
return
|
|
}
|
|
var req updateRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "validation error", "details": err.Error()})
|
|
return
|
|
}
|
|
m, err := h.service.UpdateAltText(c.Request.Context(), id, req.AltText)
|
|
if err != nil {
|
|
if errors.Is(err, ErrNotFound) {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "media not found"})
|
|
return
|
|
}
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to update media"})
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, toResponse(m))
|
|
}
|
|
|
|
func (h *Handler) Delete(c *gin.Context) {
|
|
id, err := uuid.Parse(c.Param("id"))
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid id"})
|
|
return
|
|
}
|
|
if err := h.service.Delete(c.Request.Context(), id); err != nil {
|
|
if errors.Is(err, ErrNotFound) {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "media not found"})
|
|
return
|
|
}
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to delete media"})
|
|
return
|
|
}
|
|
c.Status(http.StatusNoContent)
|
|
}
|