| package clients |
| |
| import ( |
| "context" |
| "fmt" |
| "io/ioutil" |
| "log" |
| |
| "cloud.google.com/go/storage" |
| "google.golang.org/api/iterator" |
| ) |
| |
| type CloudStorageClient struct { |
| client *storage.Client |
| } |
| |
| func CreateCloudStorageClient() (*CloudStorageClient, error) { |
| ctx := context.Background() |
| client, err := storage.NewClient(ctx) |
| if err != nil { |
| return nil, err |
| } |
| return &CloudStorageClient{client: client}, nil |
| } |
| |
| func (c *CloudStorageClient) ReadAllFiles(bucket, directory string) (*cloudStorageFileIter, error) { |
| log.Printf("Reading all files in bucket %s and directory %s", bucket, directory) |
| files, err := c.listFiles(bucket, directory) |
| if err != nil { |
| return nil, fmt.Errorf("Failed to list files in directory %s in bucket %s: %v", directory, bucket, err) |
| } |
| |
| iter := &cloudStorageFileIter{client: c.client, bucket: bucket, files: files} |
| return iter, nil |
| } |
| |
| func (c *CloudStorageClient) listFiles(bucket, directory string) ([]string, error) { |
| names := make([]string, 0) |
| ctx := context.Background() |
| q := &storage.Query{Prefix: directory} |
| it := c.client.Bucket(bucket).Objects(ctx, q) |
| for { |
| attrs, err := it.Next() |
| if err == iterator.Done { |
| break |
| } else if err != nil { |
| return nil, err |
| } |
| names = append(names, attrs.Name) |
| } |
| return names, nil |
| } |
| |
| type cloudStorageFileIter struct { |
| client *storage.Client |
| bucket string |
| files []string |
| pos int |
| } |
| |
| func (iter *cloudStorageFileIter) HasNext() bool { |
| return iter.pos < len(iter.files) |
| } |
| |
| func (iter *cloudStorageFileIter) Get() (string, []byte, error) { |
| pos := iter.pos |
| if pos >= len(iter.files) { |
| pos = len(iter.files) - 1 |
| } |
| iter.pos += 1 |
| |
| name := iter.files[pos] |
| content, err := iter.readFile(name) |
| if err != nil { |
| err = fmt.Errorf("Failed to read file %s in bucket %s: %v", name, iter.bucket, err) |
| } |
| return name, content, err |
| } |
| |
| func (iter *cloudStorageFileIter) readFile(object string) ([]byte, error) { |
| ctx := context.Background() |
| rc, err := iter.client.Bucket(iter.bucket).Object(object).NewReader(ctx) |
| if err != nil { |
| return nil, err |
| } |
| defer rc.Close() |
| |
| data, err := ioutil.ReadAll(rc) |
| if err != nil { |
| return nil, err |
| } |
| return data, nil |
| } |