package S3 import ( "fmt" "strings" "time" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/credentials" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/s3" ) func DeleteFromS3(imageURL string) error { const op = "s3.DeleteFromS3" parts := strings.SplitN(strings.TrimPrefix(imageURL, "https://s3.regru.cloud/"), "/", 2) if len(parts) != 2 { return fmt.Errorf("%s: invalid S3 URL format", op) } bucket := parts[0] key := parts[1] sess := session.Must(session.NewSession(&aws.Config{ Region: aws.String("ru-central1"), Endpoint: aws.String("https://s3.regru.cloud"), S3ForcePathStyle: aws.Bool(true), Credentials: credentials.NewStaticCredentials( "TJ946G2S1Z5FEI3I7DQQ", "C2H2aITHRDpek8H921yhnrINZwDoADsjW3F6HURl", "", ), })) svc := s3.New(sess) _, err := svc.DeleteObject(&s3.DeleteObjectInput{ Bucket: aws.String(bucket), Key: aws.String(key), }) if err != nil { return fmt.Errorf("%s: failed to delete object from S3: %w", op, err) } err = svc.WaitUntilObjectNotExists(&s3.HeadObjectInput{ Bucket: aws.String(bucket), Key: aws.String(key), }) if err != nil { return fmt.Errorf("%s: failed to wait for object deletion: %w", op, err) } return nil } func GeneratePresignedUploadURL(userID int, filename string) (string, string, error) { const op = "s3.GeneratePresignedUploadURL" sess := session.Must(session.NewSession(&aws.Config{ Region: aws.String("ru-central1"), Endpoint: aws.String("https://s3.regru.cloud"), Credentials: credentials.NewStaticCredentials( "TJ946G2S1Z5FEI3I7DQQ", "C2H2aITHRDpek8H921yhnrINZwDoADsjW3F6HURl", "", ), })) svc := s3.New(sess) // Генерируем уникальный ключ с userID для безопасности uniqueKey := fmt.Sprintf("temp/%d/%d_%s", userID, time.Now().UnixNano(), filename) req, _ := svc.PutObjectRequest(&s3.PutObjectInput{ Bucket: aws.String("tailly"), Key: aws.String(uniqueKey), ContentLength: aws.Int64(10 * 1024 * 1024), // Макс 10MB }) // URL действителен 15 минут url, err := req.Presign(15 * time.Minute) if err != nil { return "", "", fmt.Errorf("%s: failed to generate presigned URL: %w", op, err) } return url, uniqueKey, nil } func MoveFile(sourceKey, destinationKey string) error { const op = "s3.MoveFile" sess := session.Must(session.NewSession(&aws.Config{ Region: aws.String("ru-central1"), Endpoint: aws.String("https://s3.regru.cloud"), Credentials: credentials.NewStaticCredentials( "TJ946G2S1Z5FEI3I7DQQ", "C2H2aITHRDpek8H921yhnrINZwDoADsjW3F6HURl", "", ), })) svc := s3.New(sess) // Копируем файл _, err := svc.CopyObject(&s3.CopyObjectInput{ Bucket: aws.String("tailly"), CopySource: aws.String(fmt.Sprintf("tailly/%s", sourceKey)), Key: aws.String(destinationKey), }) if err != nil { return fmt.Errorf("%s: failed to copy file: %w", op, err) } // Удаляем исходный файл return DeleteTempFile(sourceKey) } func DeleteTempFile(key string) error { const op = "s3.DeleteTempFile" sess := session.Must(session.NewSession(&aws.Config{ Region: aws.String("ru-central1"), Endpoint: aws.String("https://s3.regru.cloud"), Credentials: credentials.NewStaticCredentials( "TJ946G2S1Z5FEI3I7DQQ", "C2H2aITHRDpek8H921yhnrINZwDoADsjW3F6HURl", "", ), })) svc := s3.New(sess) _, err := svc.DeleteObject(&s3.DeleteObjectInput{ Bucket: aws.String("tailly"), Key: aws.String(key), }) if err != nil { return fmt.Errorf("%s: failed to delete temp file: %w", op, err) } return nil }