133 lines
3.8 KiB
Go
133 lines
3.8 KiB
Go
package api
|
|
|
|
import (
|
|
"io"
|
|
"os"
|
|
"fmt"
|
|
"strings"
|
|
"net/http"
|
|
"encoding/json"
|
|
log "github.com/sirupsen/logrus"
|
|
"github.com/dsoprea/go-exif/v3"
|
|
|
|
"reichard.io/imagini/internal/models"
|
|
)
|
|
|
|
|
|
func (api *API) mediaItemsHandler(w http.ResponseWriter, r *http.Request) {
|
|
if r.Method == http.MethodPost {
|
|
// CREATE
|
|
api.createMediaItem(w, r)
|
|
} else if r.Method == http.MethodPut {
|
|
// UPDATE / REPLACE
|
|
} else if r.Method == http.MethodPatch {
|
|
// UPDATE / MODIFY
|
|
} else if r.Method == http.MethodDelete {
|
|
// DELETE
|
|
} else if r.Method == http.MethodGet {
|
|
// GET
|
|
} else {
|
|
errorJSON(w, "Method is not supported.", http.StatusMethodNotAllowed)
|
|
return
|
|
}
|
|
}
|
|
|
|
func (api *API) createMediaItem(w http.ResponseWriter, r *http.Request) {
|
|
r.ParseMultipartForm(64 << 20)
|
|
|
|
// Parse metadata
|
|
metadata := r.FormValue("metadata")
|
|
var mediaItem models.MediaItem
|
|
err := json.Unmarshal([]byte(metadata), &mediaItem)
|
|
if err != nil {
|
|
log.Warn("[api] createMediaItem - Invalid metadata: ", err)
|
|
errorJSON(w, "Metadata invalid.", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
// TODO: Verify mediaItem contains appropriate values
|
|
|
|
|
|
// fmt.Printf("Media Item: %+v\n", mediaItem)
|
|
|
|
// Open form file
|
|
formFile, multipartFileHeader, err := r.FormFile("file")
|
|
if err != nil {
|
|
errorJSON(w, "Upload failed.", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
defer formFile.Close()
|
|
|
|
// File header placeholder
|
|
fileHeader := make([]byte, 512)
|
|
|
|
// Copy headers into the buffer
|
|
if _, err := formFile.Read(fileHeader); err != nil {
|
|
errorJSON(w, "Upload failed.", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
// Reset position
|
|
if _, err := formFile.Seek(0, 0); err != nil {
|
|
errorJSON(w, "Upload failed.", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
// Determine media type
|
|
var mediaType string
|
|
contentType := http.DetectContentType(fileHeader)
|
|
if strings.HasPrefix(contentType, "image/") {
|
|
mediaType = "Image"
|
|
} else if strings.HasPrefix(contentType, "video/") {
|
|
mediaType = "Video"
|
|
} else {
|
|
errorJSON(w, "Invalid filetype.", http.StatusUnsupportedMediaType)
|
|
return
|
|
}
|
|
|
|
_ = mediaType
|
|
_ = multipartFileHeader
|
|
|
|
// Print details
|
|
// Filename: multipartFileHeader.Filename
|
|
// Size: multipartFileHeader.Size
|
|
// ContentType: http.DetectContentType(fileHeader)
|
|
|
|
// Open file to store
|
|
filePath := "./test.png" // TODO: Change dynamic
|
|
f, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE, 0600)
|
|
if err != nil {
|
|
log.Warn("[api] createMediaItem - Unable to open file: ", filePath)
|
|
errorJSON(w, "Upload failed.", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
defer f.Close()
|
|
|
|
// Copy data to file
|
|
_, err = io.Copy(f, formFile)
|
|
if err != nil {
|
|
errorJSON(w, "Upload failed.", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
// Gather EXIF Data
|
|
mediaItem = deriveEXIFData(filePath, mediaItem)
|
|
|
|
// TODO: Add resource location in response
|
|
successJSON(w, "Upload succeeded.", http.StatusCreated)
|
|
}
|
|
|
|
func deriveEXIFData(filePath string, mediaItem models.MediaItem) models.MediaItem {
|
|
rawExif, err := exif.SearchFileAndExtractExif(filePath)
|
|
entries, _, err := exif.GetFlatExifData(rawExif, nil)
|
|
_ = err
|
|
// parsedJSON, err := json.MarshalIndent(entries, "", " ")
|
|
// fmt.Printf("EXIF String: %+v\n", string(parsedJSON))
|
|
|
|
for _, entry := range entries {
|
|
fmt.Printf("IFD-PATH=[%s] ID=(0x%04x) NAME=[%s] COUNT=(%d) TYPE=[%s] VALUE=[%s]\n", entry.IfdPath, entry.TagId, entry.TagName, entry.UnitCount, entry.TagTypeName, entry.Formatted)
|
|
}
|
|
|
|
return mediaItem
|
|
}
|