Skip to content

Instantly share code, notes, and snippets.

@rluisr
Last active February 5, 2018 09:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rluisr/b644212cffc7c184c2914970e073c12b to your computer and use it in GitHub Desktop.
Save rluisr/b644212cffc7c184c2914970e073c12b to your computer and use it in GitHub Desktop.
Delete photos which is uploaded by user from S3
package lib
import (
"sync"
"hoge/model"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/s3"
"github.com/aws/aws-sdk-go/aws/session"
)
func initS3() (*s3.S3) {
config := model.NewConfig()
sess, _ := session.NewSession(&aws.Config{
Region: aws.String(config.AWSS3Region)},
)
svc := s3.New(sess)
return svc
}
// Get key size that is to make array which has 1000 keys from the array have more 1000 keys.
// for s3 delete method.(It's up to 1000 keys once.)
func size(s int) (int) {
i := s / 1000
f := float32(s) / 1000
if f > float32(i) {
i++
}
return i
}
func chunk(logs []string) ([][]string) {
var div [][]string
size := size(len(logs))
cSize := (len(logs) + size - 1) / size
for i := 0; i < len(logs); i += cSize {
end := i + cSize
if end > len(logs) {
end = len(logs)
}
div = append(div, logs[i:end])
}
return div
}
func getAllObject(userID string) ([]string, error) {
var objects []string
var result *s3.ListObjectsOutput
svc := initS3()
config := model.NewConfig()
isTruncated := true // for getting more 1000 keys in loop
input := &s3.ListObjectsInput{
Bucket: aws.String(config.AWSS3Bucket),
Prefix: aws.String(userID + "/"),
Delimiter: aws.String(userID + "/"),
MaxKeys: aws.Int64(1000), // max: 1000
}
result, err := svc.ListObjects(input)
if err != nil {
return objects, err
}
for _, v := range result.Contents {
objects = append(objects, *v.Key)
}
// If isTruncated is true, User has more 1000 keys.
if bool(*result.IsTruncated) {
for {
if isTruncated {
input = &s3.ListObjectsInput{
Bucket: aws.String(config.AWSS3Bucket),
Prefix: aws.String(userID + "/"),
Delimiter: aws.String(userID + "/"),
Marker: result.NextMarker,
MaxKeys: aws.Int64(1000), // max: 1000
}
result, err = svc.ListObjects(input)
if err != nil {
return objects, err
}
for _, v := range result.Contents {
objects = append(objects, *v.Key)
}
isTruncated = *result.IsTruncated
} else {
break
}
}
}
return objects, nil
}
func DeletePhotosFromS3(userID string, wg *sync.WaitGroup) {
defer wg.Done()
var delObj []*s3.ObjectIdentifier
svc := initS3()
config := model.NewConfig()
objects, err := getAllObject(userID)
if err != nil {
Slack("DeletePhotosFromS3", "getAllObject", "", userID)
return
}
if len(objects) > 1000 {
// delete method can delete objects up to 1000 key.
// So I need divided objects.
divided := chunk(objects)
for _, v := range divided {
// &s3.Delete.Objects required []*s3.ObjectIdentifier
// insert key(string) into deleteObjects
for _, vv := range v {
vvcopy := vv
delObj = append(delObj, &s3.ObjectIdentifier{Key: &vvcopy})
}
// Delete files under the bucket/user_id
input := &s3.DeleteObjectsInput{
Bucket: aws.String(config.AWSS3Bucket),
Delete: &s3.Delete{
Objects: delObj,
Quiet: aws.Bool(false),
},
}
_, err := svc.DeleteObjects(input)
if err != nil {
Slack("DeletePhotosFromS3", "svc.DeleteObjects(input)", "more 1000 keys", userID)
return
}
delObj = nil
}
} else {
for _, v := range objects {
delObj = append(delObj, &s3.ObjectIdentifier{Key: &v})
}
// Delete files under the bucket/user_id
input := &s3.DeleteObjectsInput{
Bucket: aws.String(config.AWSS3Bucket),
Delete: &s3.Delete{
Objects: delObj,
Quiet: aws.Bool(false),
},
}
_, err = svc.DeleteObjects(input)
if err != nil {
Slack("DeletePhotosFromS3", "svc.DeleteObjects(input)", "less than 1000", userID)
return
}
}
// Delete bucket/user_id
input1 := &s3.DeleteObjectInput{
Bucket: aws.String(config.AWSS3Bucket),
Key: aws.String(userID),
}
_, err = svc.DeleteObject(input1)
if err != nil {
Slack("DeletePhotosFromS3", "svc.DeleteObjects(input)", "delete bucket/"+userID, userID)
return
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment