| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- package handlers
- import (
- "crypto/sha256"
- "encoding/hex"
- "encoding/json"
- "io"
- "net/http"
- "os"
- "cmr-backend/internal/apperr"
- "cmr-backend/internal/httpx"
- "cmr-backend/internal/service"
- )
- type AdminAssetHandler struct {
- service *service.AdminAssetService
- }
- func NewAdminAssetHandler(service *service.AdminAssetService) *AdminAssetHandler {
- return &AdminAssetHandler{service: service}
- }
- func (h *AdminAssetHandler) ListAssets(w http.ResponseWriter, r *http.Request) {
- result, err := h.service.ListManagedAssets(r.Context(), parseAdminLimit(r))
- if err != nil {
- httpx.WriteError(w, err)
- return
- }
- httpx.WriteJSON(w, http.StatusOK, map[string]any{"data": result})
- }
- func (h *AdminAssetHandler) GetAsset(w http.ResponseWriter, r *http.Request) {
- result, err := h.service.GetManagedAsset(r.Context(), r.PathValue("assetPublicID"))
- if err != nil {
- httpx.WriteError(w, err)
- return
- }
- httpx.WriteJSON(w, http.StatusOK, map[string]any{"data": result})
- }
- func (h *AdminAssetHandler) RegisterLink(w http.ResponseWriter, r *http.Request) {
- var req service.RegisterLinkAssetInput
- if err := httpx.DecodeJSON(r, &req); err != nil {
- httpx.WriteError(w, apperr.New(http.StatusBadRequest, "invalid_json", "invalid request body: "+err.Error()))
- return
- }
- result, err := h.service.RegisterExternalLink(r.Context(), req)
- if err != nil {
- httpx.WriteError(w, err)
- return
- }
- httpx.WriteJSON(w, http.StatusCreated, map[string]any{"data": result})
- }
- func (h *AdminAssetHandler) UploadFile(w http.ResponseWriter, r *http.Request) {
- if err := r.ParseMultipartForm(64 << 20); err != nil {
- httpx.WriteError(w, apperr.New(http.StatusBadRequest, "invalid_multipart", "invalid multipart form: "+err.Error()))
- return
- }
- file, header, err := r.FormFile("file")
- if err != nil {
- httpx.WriteError(w, apperr.New(http.StatusBadRequest, "file_required", "multipart file field 'file' is required"))
- return
- }
- defer file.Close()
- tmpFile, err := os.CreateTemp("", "cmr-upload-*"+header.Filename)
- if err != nil {
- httpx.WriteError(w, err)
- return
- }
- tmpPath := tmpFile.Name()
- defer os.Remove(tmpPath)
- hash := sha256.New()
- written, err := io.Copy(io.MultiWriter(tmpFile, hash), file)
- if err != nil {
- tmpFile.Close()
- httpx.WriteError(w, err)
- return
- }
- if err := tmpFile.Close(); err != nil {
- httpx.WriteError(w, err)
- return
- }
- input := service.UploadAssetFileInput{
- AssetType: r.FormValue("assetType"),
- AssetCode: r.FormValue("assetCode"),
- Version: r.FormValue("version"),
- Title: stringPtrOrNil(r.FormValue("title")),
- ObjectDir: stringPtrOrNil(r.FormValue("objectDir")),
- FileName: header.Filename,
- ContentType: header.Header.Get("Content-Type"),
- FileSize: written,
- Checksum: hex.EncodeToString(hash.Sum(nil)),
- TempPath: tmpPath,
- Status: r.FormValue("status"),
- Metadata: parseMetadataJSON(r.FormValue("metadataJson")),
- }
- result, err := h.service.UploadAssetFile(r.Context(), input)
- if err != nil {
- httpx.WriteError(w, err)
- return
- }
- httpx.WriteJSON(w, http.StatusCreated, map[string]any{
- "data": result,
- "meta": map[string]any{
- "uploadedBytes": written,
- "checksumSha256": input.Checksum,
- },
- })
- }
- func stringPtrOrNil(value string) *string {
- if value == "" {
- return nil
- }
- return &value
- }
- func parseMetadataJSON(raw string) map[string]any {
- if raw == "" {
- return nil
- }
- var payload map[string]any
- _ = json.Unmarshal([]byte(raw), &payload)
- return payload
- }
|