nidus-sync/userfile/upload.go
Eli Ribble fdd783c19c
Rework userfile yet again
I'm settling on the idea that strings should never be returned from the
userfile system. Instead, indicate which collection you want and pass
objects across.
2026-02-08 04:36:12 +00:00

76 lines
2 KiB
Go

package userfile
import (
"bytes"
"fmt"
"io"
"mime/multipart"
"net/http"
"github.com/google/uuid"
"github.com/rs/zerolog/log"
)
type FileUpload struct {
ContentType string
Name string
SizeBytes int
UUID uuid.UUID
}
func SaveFileUpload(r *http.Request, name string, collection Collection) ([]FileUpload, error) {
results := make([]FileUpload, 0)
for n, fheaders := range r.MultipartForm.File {
log.Debug().Str("n", n).Msg("looking at header")
if n != name {
continue
}
for _, headers := range fheaders {
f, err := saveFileUpload(headers, collection)
if err != nil {
return results, fmt.Errorf("Failed to extract photo upload: %w", err)
}
results = append(results, f)
}
}
return results, nil
}
func saveFileUploads(r *http.Request, collection Collection) ([]FileUpload, error) {
results := make([]FileUpload, 0)
for name, fheaders := range r.MultipartForm.File {
for _, headers := range fheaders {
upload, err := saveFileUpload(headers, collection)
if err != nil {
return results, fmt.Errorf("Failed to save upload '%s': %w", name, err)
}
results = append(results, upload)
}
}
return results, nil
}
func saveFileUpload(headers *multipart.FileHeader, collection Collection) (upload FileUpload, err error) {
file, err := headers.Open()
if err != nil {
return upload, fmt.Errorf("Failed to open header: %w", err)
}
defer file.Close()
file_bytes, err := io.ReadAll(file)
content_type := http.DetectContentType(file_bytes)
u, err := uuid.NewUUID()
if err != nil {
return upload, fmt.Errorf("Failed to create uuid", err)
}
err = FileContentWrite(bytes.NewReader(file_bytes), collection, u)
if err != nil {
return upload, fmt.Errorf("Failed to write file to disk: %w", err)
}
log.Info().Int("size", len(file_bytes)).Str("uploaded_filename", headers.Filename).Str("content-type", content_type).Str("uuid", u.String()).Msg("Saved an uploaded file to disk")
return FileUpload{
ContentType: content_type,
Name: headers.Filename,
SizeBytes: len(file_bytes),
UUID: u,
}, nil
}