✨ Basic queue for processing
This commit is contained in:
68
pkg/internal/services/analyzer.go
Normal file
68
pkg/internal/services/analyzer.go
Normal file
@ -0,0 +1,68 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"image"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"git.solsynth.dev/hydrogen/paperclip/pkg/internal/database"
|
||||
"git.solsynth.dev/hydrogen/paperclip/pkg/internal/models"
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
_ "image/gif"
|
||||
_ "image/jpeg"
|
||||
_ "image/png"
|
||||
)
|
||||
|
||||
var fileAnalyzeQueue = make(chan models.Attachment, 256)
|
||||
|
||||
func PublishAnalyzeTask(file models.Attachment) {
|
||||
fileAnalyzeQueue <- file
|
||||
}
|
||||
|
||||
func AnalyzeAttachment(file models.Attachment) error {
|
||||
if file.Destination != models.AttachmentDstTemporary {
|
||||
return fmt.Errorf("attachment isn't in temporary storage, unable to analyze")
|
||||
}
|
||||
|
||||
destMap := viper.GetStringMap("destinations.temporary")
|
||||
|
||||
var dest models.LocalDestination
|
||||
rawDest, _ := jsoniter.Marshal(destMap)
|
||||
_ = jsoniter.Unmarshal(rawDest, &dest)
|
||||
|
||||
dst := filepath.Join(dest.Path, file.Uuid)
|
||||
if _, err := os.Stat(dst); !os.IsExist(err) {
|
||||
return fmt.Errorf("attachment doesn't exists in temporary storage")
|
||||
}
|
||||
|
||||
if t := strings.SplitN(file.MimeType, "/", 2)[0]; t == "image" {
|
||||
// Dealing with image
|
||||
reader, err := os.Open(dst)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to open file: %v", err)
|
||||
}
|
||||
defer reader.Close()
|
||||
im, _, err := image.Decode(reader)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to decode file as an image: %v", err)
|
||||
}
|
||||
width := im.Bounds().Dx()
|
||||
height := im.Bounds().Dy()
|
||||
ratio := width / height
|
||||
file.Metadata = map[string]any{
|
||||
"width": width,
|
||||
"height": height,
|
||||
"ratio": ratio,
|
||||
}
|
||||
}
|
||||
|
||||
if err := database.C.Save(&file).Error; err != nil {
|
||||
return fmt.Errorf("unable to save file record: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
@ -58,19 +58,13 @@ func NewAttachmentMetadata(tx *gorm.DB, user *models.Account, file *multipart.Fi
|
||||
exists.Metadata = attachment.Metadata
|
||||
attachment = exists
|
||||
attachment.ID = 0
|
||||
|
||||
if user != nil {
|
||||
attachment.AccountID = &user.ID
|
||||
}
|
||||
attachment.AccountID = user.ID
|
||||
} else {
|
||||
// Upload the new file
|
||||
attachment.Uuid = uuid.NewString()
|
||||
attachment.Size = file.Size
|
||||
attachment.Name = file.Filename
|
||||
|
||||
if user != nil {
|
||||
attachment.AccountID = &user.ID
|
||||
}
|
||||
attachment.AccountID = user.ID
|
||||
|
||||
// If the user didn't provide file mimetype manually, we have to detect it
|
||||
if len(attachment.MimeType) == 0 {
|
||||
|
@ -14,17 +14,18 @@ import (
|
||||
)
|
||||
|
||||
func DeleteFile(meta models.Attachment) error {
|
||||
destMap := viper.GetStringMap("destinations")
|
||||
dest, destOk := destMap[meta.Destination]
|
||||
if !destOk {
|
||||
return fmt.Errorf("invalid destination: destination configuration was not found")
|
||||
var destMap map[string]any
|
||||
if meta.Destination == models.AttachmentDstTemporary {
|
||||
destMap = viper.GetStringMap("destinations.temporary")
|
||||
} else {
|
||||
destMap = viper.GetStringMap("destinations.permanent")
|
||||
}
|
||||
|
||||
var destParsed models.BaseDestination
|
||||
rawDest, _ := jsoniter.Marshal(dest)
|
||||
_ = jsoniter.Unmarshal(rawDest, &destParsed)
|
||||
var dest models.BaseDestination
|
||||
rawDest, _ := jsoniter.Marshal(destMap)
|
||||
_ = jsoniter.Unmarshal(rawDest, &dest)
|
||||
|
||||
switch destParsed.Type {
|
||||
switch dest.Type {
|
||||
case models.DestinationTypeLocal:
|
||||
var destConfigured models.LocalDestination
|
||||
_ = jsoniter.Unmarshal(rawDest, &destConfigured)
|
||||
@ -34,7 +35,7 @@ func DeleteFile(meta models.Attachment) error {
|
||||
_ = jsoniter.Unmarshal(rawDest, &destConfigured)
|
||||
return DeleteFileFromS3(destConfigured, meta)
|
||||
default:
|
||||
return fmt.Errorf("invalid destination: unsupported protocol %s", destParsed.Type)
|
||||
return fmt.Errorf("invalid destination: unsupported protocol %s", dest.Type)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,18 +16,31 @@ import (
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func UploadFile(destName string, ctx *fiber.Ctx, file *multipart.FileHeader, meta models.Attachment) error {
|
||||
destMap := viper.GetStringMap("destinations")
|
||||
dest, destOk := destMap[destName]
|
||||
if !destOk {
|
||||
return fmt.Errorf("invalid destination: destination configuration was not found")
|
||||
func UploadFileToTemporary(ctx *fiber.Ctx, file *multipart.FileHeader, meta models.Attachment) error {
|
||||
destMap := viper.GetStringMap("destinations.temporary")
|
||||
|
||||
var dest models.BaseDestination
|
||||
rawDest, _ := jsoniter.Marshal(destMap)
|
||||
_ = jsoniter.Unmarshal(rawDest, &dest)
|
||||
|
||||
switch dest.Type {
|
||||
case models.DestinationTypeLocal:
|
||||
var destConfigured models.LocalDestination
|
||||
_ = jsoniter.Unmarshal(rawDest, &destConfigured)
|
||||
return UploadFileToLocal(destConfigured, ctx, file, meta)
|
||||
default:
|
||||
return fmt.Errorf("invalid destination: unsupported protocol %s", dest.Type)
|
||||
}
|
||||
}
|
||||
|
||||
var destParsed models.BaseDestination
|
||||
rawDest, _ := jsoniter.Marshal(dest)
|
||||
_ = jsoniter.Unmarshal(rawDest, &destParsed)
|
||||
func UploadFileToPermanent(ctx *fiber.Ctx, file *multipart.FileHeader, meta models.Attachment) error {
|
||||
destMap := viper.GetStringMap("destinations.permanent")
|
||||
|
||||
switch destParsed.Type {
|
||||
var dest models.BaseDestination
|
||||
rawDest, _ := jsoniter.Marshal(destMap)
|
||||
_ = jsoniter.Unmarshal(rawDest, &dest)
|
||||
|
||||
switch dest.Type {
|
||||
case models.DestinationTypeLocal:
|
||||
var destConfigured models.LocalDestination
|
||||
_ = jsoniter.Unmarshal(rawDest, &destConfigured)
|
||||
@ -37,7 +50,7 @@ func UploadFile(destName string, ctx *fiber.Ctx, file *multipart.FileHeader, met
|
||||
_ = jsoniter.Unmarshal(rawDest, &destConfigured)
|
||||
return UploadFileToS3(destConfigured, file, meta)
|
||||
default:
|
||||
return fmt.Errorf("invalid destination: unsupported protocol %s", destParsed.Type)
|
||||
return fmt.Errorf("invalid destination: unsupported protocol %s", dest.Type)
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user