github.com/aavshr/aws-sdk-go@v1.41.3/example/service/s3/sync/sync.go (about) 1 //go:build example 2 // +build example 3 4 package main 5 6 import ( 7 "flag" 8 "fmt" 9 "mime" 10 "os" 11 "path/filepath" 12 "strings" 13 14 "github.com/aavshr/aws-sdk-go/aws" 15 "github.com/aavshr/aws-sdk-go/aws/session" 16 "github.com/aavshr/aws-sdk-go/service/s3/s3manager" 17 ) 18 19 // SyncFolderIterator is used to upload a given folder 20 // to Amazon S3. 21 type SyncFolderIterator struct { 22 bucket string 23 fileInfos []fileInfo 24 err error 25 } 26 27 type fileInfo struct { 28 key string 29 fullpath string 30 } 31 32 // NewSyncFolderIterator will walk the path, and store the key and full path 33 // of the object to be uploaded. This will return a new SyncFolderIterator 34 // with the data provided from walking the path. 35 func NewSyncFolderIterator(path, bucket string) *SyncFolderIterator { 36 metadata := []fileInfo{} 37 filepath.Walk(path, func(p string, info os.FileInfo, err error) error { 38 if !info.IsDir() { 39 key := strings.TrimPrefix(p, path) 40 metadata = append(metadata, fileInfo{key, p}) 41 } 42 43 return nil 44 }) 45 46 return &SyncFolderIterator{ 47 bucket, 48 metadata, 49 nil, 50 } 51 } 52 53 // Next will determine whether or not there is any remaining files to 54 // be uploaded. 55 func (iter *SyncFolderIterator) Next() bool { 56 return len(iter.fileInfos) > 0 57 } 58 59 // Err returns any error when os.Open is called. 60 func (iter *SyncFolderIterator) Err() error { 61 return iter.err 62 } 63 64 // UploadObject will prep the new upload object by open that file and constructing a new 65 // s3manager.UploadInput. 66 func (iter *SyncFolderIterator) UploadObject() s3manager.BatchUploadObject { 67 fi := iter.fileInfos[0] 68 iter.fileInfos = iter.fileInfos[1:] 69 body, err := os.Open(fi.fullpath) 70 if err != nil { 71 iter.err = err 72 } 73 74 extension := filepath.Ext(fi.key) 75 mimeType := mime.TypeByExtension(extension) 76 77 if mimeType == "" { 78 mimeType = "binary/octet-stream" 79 } 80 81 input := s3manager.UploadInput{ 82 Bucket: &iter.bucket, 83 Key: &fi.key, 84 Body: body, 85 ContentType: &mimeType, 86 } 87 88 return s3manager.BatchUploadObject{ 89 Object: &input, 90 } 91 } 92 93 // Upload a directory to a given bucket 94 // 95 // Usage: 96 // sync <params> 97 // -region <region> // required 98 // -bucket <bucket> // required 99 // -path <path> // required 100 func main() { 101 bucketPtr := flag.String("bucket", "", "bucket to upload to") 102 regionPtr := flag.String("region", "", "region to be used when making requests") 103 pathPtr := flag.String("path", "", "path of directory to be synced") 104 flag.Parse() 105 106 sess := session.New(&aws.Config{ 107 Region: regionPtr, 108 }) 109 uploader := s3manager.NewUploader(sess) 110 111 iter := NewSyncFolderIterator(*pathPtr, *bucketPtr) 112 if err := uploader.UploadWithIterator(aws.BackgroundContext(), iter); err != nil { 113 fmt.Fprintf(os.Stderr, "unexpected error has occurred: %v", err) 114 } 115 116 if err := iter.Err(); err != nil { 117 fmt.Fprintf(os.Stderr, "unexpected error occurred during file walking: %v", err) 118 } 119 120 fmt.Println("Success") 121 }