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  }