2025-08-28 11:39:25 +03:00

149 lines
3.8 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("temp/%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
}
func MoveFile(sourceKey, destinationKey string) error {
const op = "s3.MoveFile"
client, err := getS3Client()
if err != nil {
return fmt.Errorf("%s: failed to create S3 client: %w", op, err)
}
// Копируем файл
_, err = client.CopyObject(context.TODO(), &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"
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("tailly"),
Key: aws.String(key),
})
if err != nil {
return fmt.Errorf("%s: failed to delete temp file: %w", op, err)
}
return nil
}