Skip to content

Commit

Permalink
✨ feat: Enhance AWS uploader utility
Browse files Browse the repository at this point in the history
Enhanced uploader.go to improve the AWS S3 uploading process with better error handling and file naming.

Related issue: #42
  • Loading branch information
yuminn-k committed Mar 2, 2024
1 parent ec1c4f2 commit bfc69d8
Showing 1 changed file with 57 additions and 8 deletions.
65 changes: 57 additions & 8 deletions utils/uploader.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,20 @@ import (
"github.com/YJU-OKURA/project_minori-gin-deployment-repo/constants"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/credentials"
"github.com/aws/aws-sdk-go-v2/feature/s3/manager"
"github.com/aws/aws-sdk-go-v2/service/s3"
"io"
"log"
"mime/multipart"
"os"
"path/filepath"
"strings"
"time"
)

type Uploader interface {
UploadImage(file *multipart.FileHeader) (string, error)
UploadImage(file *multipart.FileHeader, classID uint, isLogo bool) (string, error)
}

type awsUploader struct {
Expand All @@ -27,24 +32,49 @@ func NewAwsUploader() Uploader {

// initializeS3Client S3クライアントを初期化
func initializeS3Client() (*s3.Client, error) {
cfg, err := config.LoadDefaultConfig(context.TODO())
awsRegion := os.Getenv("AWS_REGION")

cfg, err := config.LoadDefaultConfig(context.TODO(),
config.WithRegion(awsRegion),
config.WithCredentialsProvider(credentials.NewStaticCredentialsProvider(
os.Getenv("AWS_S3_ACCESS_KEY"),
os.Getenv("AWS_S3_SECRET_ACCESS_KEY"),
"",
)),
)
if err != nil {
return nil, fmt.Errorf("%s: %w", constants.DatabaseError, err) // Using constants for error message
return nil, fmt.Errorf("%s: %w", constants.DatabaseError, err)
}
return s3.NewFromConfig(cfg), nil
}

// UploadImage 画像をアップロード
func (u *awsUploader) UploadImage(fileHeader *multipart.FileHeader) (string, error) {
func (u *awsUploader) UploadImage(fileHeader *multipart.FileHeader, classID uint, isLogo bool) (string, error) {
log.Printf("UploadImage called with classID: %d, isLogo: %t", classID, isLogo)
if fileHeader == nil {
return "", fmt.Errorf(constants.ErrNoFileHeaderJP)
}

const maxSize = 10 << 20 // 10MB
if fileHeader.Size > maxSize {
return "", fmt.Errorf(constants.ErrFileSizeJP)
}

mimeType := fileHeader.Header.Get("Content-Type")
if !strings.HasPrefix(mimeType, "image/") {
return "", fmt.Errorf("%s:%s", constants.ErrMimeTypeJP, mimeType)
}

file, err := fileHeader.Open()
if err != nil {
return "", fmt.Errorf("%s: %w", constants.ErrOpenFileJP, err)
}
defer file.Close()
defer func() {
if cerr := file.Close(); cerr != nil && err == nil {
log.Printf("Failed to close file: %v", cerr)
err = cerr
}
}()

fileData, err := io.ReadAll(file)
if err != nil {
Expand All @@ -57,14 +87,32 @@ func (u *awsUploader) UploadImage(fileHeader *multipart.FileHeader) (string, err
}
uploader := manager.NewUploader(s3Client)

// ファイル名の生成
extension := filepath.Ext(fileHeader.Filename)
uniqueFileName := fmt.Sprintf("images/%d/%s-%d%s", classID, strings.TrimSuffix(fileHeader.Filename, extension), time.Now().Unix(), extension)
//log.Printf("Generated uniqueFileName: %s", uniqueFileName)

// ロゴの場合、パスに 'logo/' を追加
if isLogo {
uniqueFileName = fmt.Sprintf("images/%d/logo/%s-%d%s", classID, strings.TrimSuffix(fileHeader.Filename, extension), time.Now().Unix(), extension)
} else {
uniqueFileName = fmt.Sprintf("images/%d/%s-%d%s", classID, strings.TrimSuffix(fileHeader.Filename, extension), time.Now().Unix(), extension)
}

bucketName := os.Getenv("AWS_S3_BUCKET_NAME")
if bucketName == "" {
return "", fmt.Errorf(constants.ErrLoadAWSConfigJP)
}

upParams := &s3.PutObjectInput{
Bucket: aws.String("images"), // Assuming bucket name is 'images'
Key: aws.String(fileHeader.Filename),
Bucket: aws.String(bucketName),
Key: aws.String(uniqueFileName),
Body: bytes.NewReader(fileData),
}

_, err = uploader.Upload(context.TODO(), upParams)
if err != nil {
log.Printf("Error in uploader.Upload: %v", err)
return "", fmt.Errorf("%s: %w", constants.ErrUploadToS3JP, err)
}

Expand All @@ -73,6 +121,7 @@ func (u *awsUploader) UploadImage(fileHeader *multipart.FileHeader) (string, err
return "", fmt.Errorf(constants.ErrCloudFrontURLNotSetJP)
}

finalURL := fmt.Sprintf("%s/%s", cloudFrontURL, fileHeader.Filename) // Ensure the URL is correctly formatted
finalURL := fmt.Sprintf("%s/%s", cloudFrontURL, uniqueFileName)
log.Printf("Final URL: %s", finalURL)
return finalURL, nil
}

0 comments on commit bfc69d8

Please sign in to comment.