admin 8e247cdb0d
All checks were successful
continuous-integration/drone/push Build is passing
v0.0.27.3
2025-08-28 12:19:17 +03:00

109 lines
3.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package S3
import (
"context"
"fmt"
"strings"
"time"
"github.com/aws/aws-sdk-go-v2/aws"
awsConfig "github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/credentials"
"github.com/aws/aws-sdk-go-v2/service/s3"
)
// Получаем S3 клиент
func getS3Client() (*s3.Client, error) {
cfg, err := awsConfig.LoadDefaultConfig(context.TODO(),
awsConfig.WithRegion("ru-central1"),
awsConfig.WithCredentialsProvider(credentials.NewStaticCredentialsProvider(
"TJ946G2S1Z5FEI3I7DQQ",
"C2H2aITHRDpek8H921yhnrINZwDoADsjW3F6HURl",
"",
)),
awsConfig.WithEndpointResolver(aws.EndpointResolverFunc(
func(service, region string) (aws.Endpoint, error) {
return aws.Endpoint{
URL: "https://s3.regru.cloud",
SigningRegion: "ru-central1",
Source: aws.EndpointSourceCustom,
}, nil
},
)),
)
if err != nil {
return nil, err
}
// Создаем клиент с кастомным эндпоинтом
client := s3.NewFromConfig(cfg, func(o *s3.Options) {
o.UsePathStyle = true // Важно для некоторых S3 провайдеров
})
return client, nil
}
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]
client, err := getS3Client()
if err != nil {
return fmt.Errorf("%s: failed to create S3 client: %w", op, err)
}
_, err = client.DeleteObject(context.TODO(), &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)
}
// Ждем пока объект исчезнет
waiter := s3.NewObjectNotExistsWaiter(client)
err = waiter.Wait(context.TODO(), &s3.HeadObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(key),
}, 30*time.Second)
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"
client, err := getS3Client()
if err != nil {
return "", "", fmt.Errorf("%s: failed to create S3 client: %w", op, err)
}
// Генерируем ключ сразу в конечной папке с уникальным именем
uniqueKey := fmt.Sprintf("posts/%d/%d_%s", userID, time.Now().UnixNano(), filename)
presignClient := s3.NewPresignClient(client)
result, err := presignClient.PresignPutObject(context.TODO(),
&s3.PutObjectInput{
Bucket: aws.String("tailly"),
Key: aws.String(uniqueKey),
ContentLength: aws.Int64(10 * 1024 * 1024),
},
s3.WithPresignExpires(15*time.Minute),
)
if err != nil {
return "", "", fmt.Errorf("%s: failed to generate presigned URL: %w", op, err)
}
return result.URL, uniqueKey, nil
}