diff --git a/media/media.go b/media/media.go index 7f295d4..f023612 100644 --- a/media/media.go +++ b/media/media.go @@ -81,7 +81,18 @@ func (m *MediaClient) Seed() ([]string, error) { return new_buckets, nil } -func (m *MediaClient) UploadFormFiles(fileHeaders []*multipart.FileHeader) (statusCode int, result string) { +func (m *MediaClient) UploadFormFiles(bucketName string, fileHeaders []*multipart.FileHeader) (statusCode int, result string) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + ok, err := m.MinioClient.BucketExists(ctx, bucketName) + if err != nil { + return http.StatusInternalServerError, fmt.Sprintf("Erreur lors de vérification d'existence de bucket '%s': %s", bucketName, err) + } + if !ok { + return http.StatusBadRequest, fmt.Sprintf("Bucket '%s' n'existe pas", bucketName) + } + switch count := len(fileHeaders); count { case 0: return http.StatusBadRequest, "Veuillez sélectionner au moins 1 document à téléverser" @@ -98,6 +109,8 @@ func (m *MediaClient) UploadFormFiles(fileHeaders []*multipart.FileHeader) (stat fileNames = append(fileNames, fileHeader.Filename) } + var validFileHeaders []*multipart.FileHeader + for i, fileHeader := range fileHeaders { // Check for conflicting file names in upload for j, fileName := range fileNames { @@ -106,8 +119,6 @@ func (m *MediaClient) UploadFormFiles(fileHeaders []*multipart.FileHeader) (stat } } - //TODO check for conflicting fileNames with existing files - // Check media type mediaType, _, err := mime.ParseMediaType(fileHeader.Header.Get("Content-Type")) if err != nil { @@ -123,13 +134,51 @@ func (m *MediaClient) UploadFormFiles(fileHeaders []*multipart.FileHeader) (stat } if !isAllowedMediaType { - return http.StatusBadRequest, fmt.Sprintf("Type de fichier interdit '%s' pour '%s'.\nTypes de fichiers permis: %s", mediaType, fileHeader.Filename, allowedMediaTypes) + return http.StatusUnsupportedMediaType, 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) + // Check for conflicting fileNames with existing files + objectInfo, err := m.MinioClient.StatObject(ctx, bucketName, fileHeader.Filename, minio.StatObjectOptions{}) + if err == nil && objectInfo.Key == fileHeader.Filename { + return http.StatusConflict, fmt.Sprintf("Un document au nom '%s' de catégorie '%s' existe déjà et ne peut pas être inséré de cette façon.", fileHeader.Filename, bucketName) + } - //TODO Upload file + switch msg := err.Error(); msg { + case "The specified key does not exist.": + default: + return http.StatusInternalServerError, fmt.Sprintf("Erreur inattendue lors de vérification de conflit de nom de fichier avec la base de données: %s", err) + } + + validFileHeaders = append(validFileHeaders, fileHeader) + } + + if len(validFileHeaders) == 0 { + return http.StatusOK, "Aucun fichier valide envoyé au serveur, rien à faire." + } + + for i, fileHeader := range validFileHeaders { + 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()) + } + + // Get file content + fileContent, err := fileHeader.Open() + if err != nil { + return http.StatusBadRequest, fmt.Sprintf("Impossible de lire le contenu de '%s': %s", fileHeader.Filename, err) + } + defer fileContent.Close() + + // Upload file + info, err := m.MinioClient.PutObject(ctx, bucketName, fileHeader.Filename, fileContent, fileHeader.Size, minio.PutObjectOptions{ + ContentType: mediaType, + }) + if err != nil { + return http.StatusInternalServerError, fmt.Sprintf("Impossible d'ajouter '%s' à la base de donnée: %s", fileHeader.Filename, err) + } + + result = fmt.Sprintf("%sDocument %d '%s' de type '%s' et de taille '%d' téléversé à '%s' avec succès\n", + result, i, info.Key, mediaType, info.Size, info.Bucket) } return http.StatusCreated, result