Victor Lacasse-Beaudoin
24855a4115
Une fois terminé, permettra de téléverser plusieurs documents à la fois dans un même bucket. Pour l'instant, est capable de recevoir des `[]*multipart.FileHeader` et de valider leur `Content-Type` selon une liste prédéfinie (pdf, markdown et plain text). Valide aussi que les pointeurs mémoires sont non-nil. Retourne `http.StatusCreated` ainsi que la liste des documents validés qui doivent être insérés. Le travail restant est écrit en commentaires TODO
136 lines
3.6 KiB
Go
136 lines
3.6 KiB
Go
package media
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"mime"
|
|
"mime/multipart"
|
|
"net/http"
|
|
|
|
"git.agecem.com/agecem/agecem-org/config"
|
|
"github.com/minio/minio-go/v7"
|
|
"github.com/minio/minio-go/v7/pkg/credentials"
|
|
"github.com/spf13/viper"
|
|
)
|
|
|
|
func NewMediaClient(endpoint, accessKeyId, secretAccessKey string, useSSL bool) (*MediaClient, error) {
|
|
if accessKeyId == "" {
|
|
return nil, errors.New("accessKeyId was found empty, but cannot be")
|
|
}
|
|
|
|
if secretAccessKey == "" {
|
|
return nil, errors.New("secretAccessKey was found empty, but cannot be")
|
|
}
|
|
|
|
var mediaClient MediaClient
|
|
minioClient, err := minio.New(endpoint, &minio.Options{
|
|
Creds: credentials.NewStaticV4(accessKeyId, secretAccessKey, ""),
|
|
Secure: useSSL,
|
|
})
|
|
if err != nil {
|
|
return &mediaClient, err
|
|
}
|
|
|
|
mediaClient.MinioClient = *minioClient
|
|
return &mediaClient, nil
|
|
}
|
|
|
|
func NewMediaClientFromViper() (*MediaClient, error) {
|
|
var cfg config.Config
|
|
if err := viper.Unmarshal(&cfg); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
mediaClient, err := NewMediaClient(cfg.Server.Documents.Endpoint, cfg.Server.Documents.AccessKeyId, cfg.Server.Documents.SecretAccessKey, cfg.Server.Documents.UseSSL)
|
|
if err != nil {
|
|
return mediaClient, err
|
|
}
|
|
|
|
return mediaClient, nil
|
|
}
|
|
|
|
type MediaClient struct {
|
|
MinioClient minio.Client
|
|
}
|
|
|
|
func (m *MediaClient) Seed() ([]string, error) {
|
|
var cfg config.Config
|
|
if err := viper.Unmarshal(&cfg); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var new_buckets []string
|
|
|
|
for bucket := range cfg.Server.Documents.Buckets {
|
|
exists, err := m.MinioClient.BucketExists(context.Background(), bucket)
|
|
if err != nil {
|
|
return new_buckets, err
|
|
}
|
|
|
|
if exists {
|
|
continue
|
|
}
|
|
|
|
if err = m.MinioClient.MakeBucket(context.Background(), bucket, minio.MakeBucketOptions{}); err != nil {
|
|
return new_buckets, err
|
|
}
|
|
new_buckets = append(new_buckets, bucket)
|
|
}
|
|
|
|
return new_buckets, nil
|
|
}
|
|
|
|
func (m *MediaClient) UploadFormFiles(fileHeaders []*multipart.FileHeader) (statusCode int, result string) {
|
|
switch count := len(fileHeaders); count {
|
|
case 0:
|
|
return http.StatusBadRequest, "Veuillez sélectionner au moins 1 document à téléverser"
|
|
case 1:
|
|
result = "Téléversement de 1 fichier\n"
|
|
default:
|
|
result = fmt.Sprintf("Téléversement de %d fichiers\n", count)
|
|
}
|
|
|
|
var allowedMediaTypes = []string{"application/pdf", "text/markdown", "text/plain"}
|
|
|
|
var fileNames []string
|
|
for _, fileHeader := range fileHeaders {
|
|
fileNames = append(fileNames, fileHeader.Filename)
|
|
}
|
|
|
|
for i, fileHeader := range fileHeaders {
|
|
// Check for conflicting file names in upload
|
|
for j, fileName := range fileNames {
|
|
if fileName == fileHeader.Filename && i != j {
|
|
return http.StatusBadRequest, fmt.Sprintf("Doublon de nom de fichier '%s' trouvé, les noms de fichiers doivent être uniques", fileName)
|
|
}
|
|
}
|
|
|
|
//TODO check for conflicting fileNames with existing files
|
|
|
|
// Check media type
|
|
mediaType, _, err := mime.ParseMediaType(fileHeader.Header.Get("Content-Type"))
|
|
if err != nil {
|
|
return http.StatusBadRequest, fmt.Sprintf("Impossible de déterminer le type de fichier pour %d '%s'.\nPlus de détails: %s", i, fileHeader.Filename, err.Error())
|
|
}
|
|
|
|
var isAllowedMediaType bool
|
|
|
|
for _, allowedMediaType := range allowedMediaTypes {
|
|
if allowedMediaType == mediaType {
|
|
isAllowedMediaType = true
|
|
}
|
|
}
|
|
|
|
if !isAllowedMediaType {
|
|
return http.StatusBadRequest, fmt.Sprintf("Type de fichier interdit '%s' pour '%s'.\nTypes de fichiers permis: %s", mediaType, fileHeader.Filename, allowedMediaTypes)
|
|
}
|
|
|
|
result = fmt.Sprintf("%sDocument %d '%s' est de type '%s'\n",
|
|
result, i, fileHeader.Filename, mediaType)
|
|
|
|
//TODO Upload file
|
|
}
|
|
|
|
return http.StatusCreated, result
|
|
}
|