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}) }