82 lines
2 KiB
Go
82 lines
2 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"github.com/aws/aws-sdk-go-v2/aws"
|
|
"github.com/aws/aws-sdk-go-v2/config"
|
|
"github.com/aws/aws-sdk-go-v2/service/s3"
|
|
"github.com/aws/aws-sdk-go-v2/service/s3/types"
|
|
)
|
|
|
|
var s3Client *s3.Client
|
|
|
|
func initS3() error {
|
|
cfg, err := config.LoadDefaultConfig(context.Background(), config.WithRegion("us-east-1"))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
s3Client = s3.NewFromConfig(cfg)
|
|
return nil
|
|
}
|
|
|
|
// iconHashToPath converts a SHA-256 hash to a sharded file path.
|
|
func iconHashToPath(iconsDir, hash string) string {
|
|
if len(hash) < 6 {
|
|
return filepath.Join(iconsDir, hash)
|
|
}
|
|
return filepath.Join(iconsDir, hash[:2], hash[2:4], hash[4:6], hash)
|
|
}
|
|
|
|
// readIconFromDisk reads an icon file from the local sharded directory.
|
|
func readIconFromDisk(iconsDir, hash string) ([]byte, error) {
|
|
return os.ReadFile(iconHashToPath(iconsDir, hash))
|
|
}
|
|
|
|
// s3UploadBundle uploads a bundle JSON to S3.
|
|
func s3UploadBundle(bucket, key string, data []byte) error {
|
|
_, err := s3Client.PutObject(context.Background(), &s3.PutObjectInput{
|
|
Bucket: aws.String(bucket),
|
|
Key: aws.String(key),
|
|
Body: bytes.NewReader(data),
|
|
ContentType: aws.String("application/json"),
|
|
})
|
|
return err
|
|
}
|
|
|
|
// s3DeletePrefix deletes all objects under a prefix in S3.
|
|
func s3DeletePrefix(bucket, prefix string) error {
|
|
ctx := context.Background()
|
|
paginator := s3.NewListObjectsV2Paginator(s3Client, &s3.ListObjectsV2Input{
|
|
Bucket: aws.String(bucket),
|
|
Prefix: aws.String(prefix),
|
|
})
|
|
|
|
for paginator.HasMorePages() {
|
|
page, err := paginator.NextPage(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if len(page.Contents) == 0 {
|
|
continue
|
|
}
|
|
|
|
var objects []types.ObjectIdentifier
|
|
for _, obj := range page.Contents {
|
|
objects = append(objects, types.ObjectIdentifier{Key: obj.Key})
|
|
}
|
|
|
|
_, err = s3Client.DeleteObjects(ctx, &s3.DeleteObjectsInput{
|
|
Bucket: aws.String(bucket),
|
|
Delete: &types.Delete{Objects: objects},
|
|
})
|
|
if err != nil {
|
|
return fmt.Errorf("delete batch: %w", err)
|
|
}
|
|
}
|
|
return nil
|
|
}
|