2023-07-04 16:47:03 -04:00
package media
import (
2023-07-04 20:33:27 -04:00
"context"
2023-07-04 18:41:27 -04:00
"errors"
2023-12-18 17:40:37 -05:00
"fmt"
"mime"
"mime/multipart"
"net/http"
2023-07-04 18:41:27 -04:00
2023-07-04 16:47:03 -04:00
"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 ) {
2023-07-04 18:41:27 -04:00
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" )
}
2023-07-04 16:47:03 -04:00
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
}
2023-07-04 20:33:27 -04:00
func ( m * MediaClient ) Seed ( ) ( [ ] string , error ) {
var cfg config . Config
if err := viper . Unmarshal ( & cfg ) ; err != nil {
return nil , err
}
var new_buckets [ ] string
2023-08-15 15:51:42 -04:00
for bucket := range cfg . Server . Documents . Buckets {
2023-07-04 20:33:27 -04:00
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
2023-07-04 16:47:03 -04:00
}
2023-12-18 17:40:37 -05:00
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
}