Files
RenewCMS/api/handlers/media/variantsHandler.go
T

162 lines
4.7 KiB
Go

package media
import (
"RenewCMS/api/pkg/apperr"
domainImage "RenewCMS/internal/domain/image"
"RenewCMS/internal/infrastructure/useCases"
"errors"
"net/http"
"github.com/go-chi/chi/v5"
)
type imageVariantResponse struct {
Name string `json:"name"`
Width *int `json:"width"`
Height *int `json:"height"`
Fit domainImage.VariantFit `json:"fit"`
Format domainImage.VariantFormat `json:"format"`
OutputWidth int `json:"output_width"`
OutputHeight int `json:"output_height"`
OutputFormat domainImage.VariantFormat `json:"output_format"`
Generated bool `json:"generated"`
Size *int64 `json:"size"`
URL string `json:"url"`
}
type imageVariantListResponse struct {
Unsupported *string `json:"unsupported"`
Items []imageVariantResponse `json:"items"`
}
type variantFailureResponse struct {
Name string `json:"name"`
Cause string `json:"cause"`
}
type generateAllResponse struct {
Generated int `json:"generated"`
Failed int `json:"failed"`
Failures []variantFailureResponse `json:"failures"`
Items []imageVariantResponse `json:"items"`
}
type variantPurgeResponse struct {
PurgedFiles int `json:"purged_files"`
PurgedBytes int64 `json:"purged_bytes"`
}
func toImageVariantResponse(view useCases.ImageVariantView) imageVariantResponse {
response := imageVariantResponse{
Name: view.Variant.Name,
Width: view.Variant.Width,
Height: view.Variant.Height,
Fit: view.Variant.Fit,
Format: view.Variant.Format,
OutputWidth: view.OutputWidth,
OutputHeight: view.OutputHeight,
OutputFormat: view.OutputFormat,
Generated: view.Generated,
URL: view.URL,
}
if view.Generated {
size := view.Size
response.Size = &size
}
return response
}
func toImageVariantResponses(views []useCases.ImageVariantView) []imageVariantResponse {
items := make([]imageVariantResponse, 0, len(views))
for _, view := range views {
items = append(items, toImageVariantResponse(view))
}
return items
}
func writeImageVariantError(w http.ResponseWriter, err error) {
switch {
case errors.Is(err, domainImage.ErrVariantNotFound):
http.Error(w, apperr.VariantNotFoundErrorMessage, http.StatusNotFound)
case errors.Is(err, domainImage.ErrVariantSourceUnsupported):
http.Error(w, apperr.VariantSourceUnsupportedErrorMessage, http.StatusUnprocessableEntity)
case errors.Is(err, domainImage.ErrSourceTooLarge):
http.Error(w, apperr.VariantSourceTooLargeErrorMessage, http.StatusRequestEntityTooLarge)
case errors.Is(err, domainImage.ErrVariantSourceUnreadable):
http.Error(w, apperr.VariantSourceUnreadableErrorMessage, http.StatusUnsupportedMediaType)
default:
writeImageError(w, err)
}
}
func (h *Handler) ListVariants(w http.ResponseWriter, r *http.Request) {
id, ok := parseImageId(w, r)
if !ok {
return
}
list, err := h.ListVariantsUseCase.List(id)
if err != nil {
writeImageVariantError(w, err)
return
}
response := imageVariantListResponse{Items: toImageVariantResponses(list.Items)}
if list.Unsupported != "" {
response.Unsupported = &list.Unsupported
}
writeJSON(w, http.StatusOK, response)
}
func (h *Handler) GenerateVariant(w http.ResponseWriter, r *http.Request) {
id, ok := parseImageId(w, r)
if !ok {
return
}
view, err := h.GenerateVariantUseCase.Generate(r.Context(), id, chi.URLParam(r, "name"))
if err != nil {
writeImageVariantError(w, err)
return
}
writeJSON(w, http.StatusOK, toImageVariantResponse(view))
}
func (h *Handler) GenerateAllVariants(w http.ResponseWriter, r *http.Request) {
id, ok := parseImageId(w, r)
if !ok {
return
}
result, err := h.GenerateAllUseCase.Generate(r.Context(), id)
if err != nil {
writeImageVariantError(w, err)
return
}
failures := make([]variantFailureResponse, 0, len(result.Failures))
for _, failure := range result.Failures {
failures = append(failures, variantFailureResponse{Name: failure.Name, Cause: failure.Cause})
}
writeJSON(w, http.StatusOK, generateAllResponse{
Generated: result.Generated,
Failed: result.Failed,
Failures: failures,
Items: toImageVariantResponses(result.Items),
})
}
func (h *Handler) PurgeVariant(w http.ResponseWriter, r *http.Request) {
id, ok := parseImageId(w, r)
if !ok {
return
}
purged, err := h.PurgeVariantUseCase.Purge(r.Context(), id, chi.URLParam(r, "name"))
if err != nil {
writeImageVariantError(w, err)
return
}
writeJSON(w, http.StatusOK, variantPurgeResponse{PurgedFiles: purged.Files, PurgedBytes: purged.Bytes})
}