2026-04-03 22:04:22 +00:00
package html
2026-01-16 14:52:11 +00:00
import (
"bytes"
"fmt"
2026-05-04 19:07:29 +00:00
"github.com/Gleipnir-Technology/nidus-sync/lint"
2026-03-13 17:33:39 +00:00
"github.com/Gleipnir-Technology/nidus-sync/platform"
"github.com/Gleipnir-Technology/nidus-sync/platform/file"
"github.com/google/uuid"
"github.com/rs/zerolog/log"
2026-01-16 14:52:11 +00:00
"image"
_ "image/gif" // register GIF format
_ "image/jpeg" // register JPEG format
_ "image/png" // register PNG format
"io"
"mime/multipart"
"net/http"
)
2026-04-03 22:04:22 +00:00
func ExtractImageUpload ( headers * multipart . FileHeader ) ( upload platform . ImageUpload , err error ) {
2026-03-12 23:49:16 +00:00
f , err := headers . Open ( )
2026-01-16 14:52:11 +00:00
if err != nil {
return upload , fmt . Errorf ( "Failed to open header: %w" , err )
}
2026-05-04 19:07:29 +00:00
defer lint . LogOnErr ( f . Close , "close headers" )
2026-01-16 14:52:11 +00:00
2026-03-12 23:49:16 +00:00
file_bytes , err := io . ReadAll ( f )
2026-01-16 14:52:11 +00:00
content_type := http . DetectContentType ( file_bytes )
2026-03-13 17:33:39 +00:00
exif , err := platform . ImageExtractExif ( content_type , file_bytes )
2026-01-16 14:52:11 +00:00
if err != nil {
2026-02-05 21:43:29 +00:00
return upload , fmt . Errorf ( "Failed to extract EXIF data: %w" , err )
2026-01-16 14:52:11 +00:00
}
i , format , err := image . Decode ( bytes . NewReader ( file_bytes ) )
if err != nil {
return upload , fmt . Errorf ( "Failed to decode image file: %w" , err )
}
u , err := uuid . NewUUID ( )
if err != nil {
return upload , fmt . Errorf ( "Failed to create quick report photo uuid" , err )
}
2026-04-01 21:23:28 +00:00
err = file . ImageFileFromReader ( file . CollectionPublicImage , u , bytes . NewReader ( file_bytes ) )
2026-01-16 14:52:11 +00:00
if err != nil {
return upload , fmt . Errorf ( "Failed to write image 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" )
2026-03-13 17:33:39 +00:00
return platform . ImageUpload {
2026-01-16 14:52:11 +00:00
Bounds : i . Bounds ( ) ,
ContentType : content_type ,
Exif : exif ,
Format : format ,
UploadFilename : headers . Filename ,
UploadFilesize : len ( file_bytes ) ,
UUID : u ,
} , nil
}
2026-04-03 22:04:22 +00:00
func ExtractImageUploads ( r * http . Request ) ( uploads [ ] platform . ImageUpload , err error ) {
2026-03-13 17:33:39 +00:00
uploads = make ( [ ] platform . ImageUpload , 0 )
2026-01-16 14:52:11 +00:00
for _ , fheaders := range r . MultipartForm . File {
for _ , headers := range fheaders {
2026-04-03 22:04:22 +00:00
upload , err := ExtractImageUpload ( headers )
2026-01-16 14:52:11 +00:00
if err != nil {
2026-03-13 17:33:39 +00:00
return make ( [ ] platform . ImageUpload , 0 ) , fmt . Errorf ( "Failed to extract photo upload: %w" , err )
2026-01-16 14:52:11 +00:00
}
uploads = append ( uploads , upload )
}
}
return uploads , nil
}