/
file_query.go
84 lines (67 loc) · 1.88 KB
/
file_query.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package gcs
import (
"context"
"regexp"
"strings"
"cloud.google.com/go/storage"
"github.com/harusame0616/GoFilerth/gofilerth/usecase"
"google.golang.org/api/iterator"
"google.golang.org/api/option"
)
type FileQuery struct {
client *storage.Client
ctx context.Context
}
func NewFileQueryByCredential(credentialFilePath string) (*FileQuery, error) {
ctx := context.Background()
client, err := storage.NewClient(ctx, option.WithCredentialsFile(credentialFilePath))
if err != nil {
return nil, err
}
return &FileQuery{client, ctx}, nil
}
func (fileQuery *FileQuery) ListFiles(path string) ([]usecase.FileDto, error) {
pathFormat := regexp.MustCompile(`^gcs://(.+?)(/(.*))*$`)
matches := pathFormat.FindAllStringSubmatch(path, -1)
bucketName, path := matches[0][1], matches[0][3]
if !strings.HasSuffix(path, "/") {
path += "/"
}
// バケットルートを取得したいときに / を指定してしまうと
// オブジェクト一覧が取得できない
if path == "/" {
path = ""
}
var files []usecase.FileDto
for it := fileQuery.client.Bucket(bucketName).Objects(fileQuery.ctx, &storage.Query{Prefix: path, Delimiter: "/"}); ; {
attrs, err := it.Next()
if err == iterator.Done {
break
}
if err != nil {
return nil, err
}
file := usecase.FileDto{
Size: attrs.Size,
Path: path,
ModifiedAt: attrs.Updated,
}
if len(attrs.Prefix) > 0 {
paths := strings.Split(attrs.Prefix, "/")
file.Name = paths[len(paths)-2] // 最後が空白要素になるので -2
file.FileType = "_directory"
} else if len(attrs.Name) > 0 {
paths := strings.Split(attrs.Name, "/")
file.Name = paths[len(paths)-1]
file.FileType = ""
splits := strings.Split(file.Name, ".")
if len(splits) <= 1 {
file.FileType = ""
} else {
file.FileType = splits[len(splits)-1]
}
}
files = append(files, file)
}
return files, nil
}