...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package gcsfs
18
19 import (
20 "os"
21 "path/filepath"
22 "strings"
23 "time"
24
25 "cloud.google.com/go/storage"
26 )
27
28 const (
29 folderSize = 42
30 )
31
32 type FileInfo struct {
33 name string
34 size int64
35 updated time.Time
36 isDir bool
37 fileMode os.FileMode
38 }
39
40 func newFileInfo(name string, fs *Fs, fileMode os.FileMode) (*FileInfo, error) {
41 res := &FileInfo{
42 name: name,
43 size: folderSize,
44 updated: time.Time{},
45 isDir: false,
46 fileMode: fileMode,
47 }
48
49 obj, err := fs.getObj(name)
50 if err != nil {
51 return nil, err
52 }
53
54 objAttrs, err := obj.Attrs(fs.ctx)
55 if err != nil {
56 if err.Error() == ErrEmptyObjectName.Error() {
57
58 res.name = fs.ensureTrailingSeparator(res.name)
59 res.isDir = true
60 return res, nil
61 } else if err.Error() == ErrObjectDoesNotExist.Error() {
62
63
64 bucketName, bucketPath := fs.splitName(name)
65 it := fs.client.Bucket(bucketName).Objects(
66 fs.ctx, &storage.Query{Delimiter: fs.separator, Prefix: bucketPath, Versions: false})
67 if _, err = it.Next(); err == nil {
68 res.name = fs.ensureTrailingSeparator(res.name)
69 res.isDir = true
70 return res, nil
71 }
72
73 return nil, ErrFileNotFound
74 }
75 return nil, err
76 }
77
78 res.size = objAttrs.Size
79 res.updated = objAttrs.Updated
80
81 return res, nil
82 }
83
84 func newFileInfoFromAttrs(objAttrs *storage.ObjectAttrs, fileMode os.FileMode) *FileInfo {
85 res := &FileInfo{
86 name: objAttrs.Name,
87 size: objAttrs.Size,
88 updated: objAttrs.Updated,
89 isDir: false,
90 fileMode: fileMode,
91 }
92
93 if res.name == "" {
94 if objAttrs.Prefix != "" {
95
96
97 res.name = objAttrs.Prefix
98 res.size = folderSize
99 res.isDir = true
100 }
101 }
102
103 return res
104 }
105
106 func (fi *FileInfo) Name() string {
107 return filepath.Base(filepath.FromSlash(fi.name))
108 }
109
110 func (fi *FileInfo) Size() int64 {
111 return fi.size
112 }
113
114 func (fi *FileInfo) Mode() os.FileMode {
115 if fi.IsDir() {
116 return os.ModeDir | fi.fileMode
117 }
118 return fi.fileMode
119 }
120
121 func (fi *FileInfo) ModTime() time.Time {
122 return fi.updated
123 }
124
125 func (fi *FileInfo) IsDir() bool {
126 return fi.isDir
127 }
128
129 func (fi *FileInfo) Sys() interface{} {
130 return nil
131 }
132
133 type ByName []*FileInfo
134
135 func (a ByName) Len() int { return len(a) }
136 func (a ByName) Swap(i, j int) {
137 a[i].name, a[j].name = a[j].name, a[i].name
138 a[i].size, a[j].size = a[j].size, a[i].size
139 a[i].updated, a[j].updated = a[j].updated, a[i].updated
140 a[i].isDir, a[j].isDir = a[j].isDir, a[i].isDir
141 }
142 func (a ByName) Less(i, j int) bool { return strings.Compare(a[i].Name(), a[j].Name()) == -1 }
143
View as plain text