-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfile_utils.go
155 lines (131 loc) · 3.25 KB
/
file_utils.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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package bsshgo
//get_run_file.go an enhancement of trying to reach out actual file contents
// https://api.basespace.illumina.com/v2/runs/219846639/files?recursive=false&filehrefcontentresolution=false&sortdir=Asc&sortby=Name&limit=2000&directory=/
//ref https://developer.basespace.illumina.com/docs/content/documentation/rest-api/api-reference#operation--runs--id--files-get
import (
"context"
"encoding/json"
"fmt"
"net/url"
)
var ERR_NOT_FOUND = fmt.Errorf(`not found`)
type FileItem struct {
Id string
Href string
HrefContent string
Name string
ContentType string
Size int64
Path string
IsArchived bool
DateCreated string
DateModified string
ETag string
}
type FileResp struct {
Items []*FileItem
Paging struct {
DisplayedCount int
Offset int
Limit int
SortDir string
SortBy string
}
}
type FileFilterFn func(*FileItem) bool
func (self *Client) GetFileFromDir(pctx context.Context,
runId string,
params map[string]string,
dir string,
fn FileFilterFn,
) (*FileItem, error) {
ctx, cancelfn := context.WithCancel(pctx)
defer cancelfn()
ch := self.GetAllFilesFromDir(ctx, runId, params, dir)
for fileitem := range ch {
if fn(fileitem) {
return fileitem, nil
}
}
return nil, ERR_NOT_FOUND
}
func (self *Client) GetAllFilesFromDir(ctx context.Context,
runId string,
params map[string]string,
dir string) chan *FileItem {
limit := 20
ret := make(chan *FileItem, 3*limit)
go func() {
defer close(ret)
offset := 0
for {
params[`limit`] = fmt.Sprintf(`%d`, limit)
params[`offset`] = fmt.Sprintf(`%d`, offset)
page, err := self.GetFileRespFromDir(ctx, runId, params, dir)
if err != nil {
fmt.Println(err.Error())
return
}
offset += limit
for _, found := range page.Items {
ret <- found
select {
case <-ctx.Done():
return
default:
continue
}
}
if page.Paging.DisplayedCount < limit || page.Paging.DisplayedCount == 0 {
return
}
}
}()
return ret
}
//GetFileRespByName seach one page
func (self *Client) GetFileRespFromDir(ctx context.Context,
runId string,
params map[string]string,
dir string) (*FileResp, error) {
// /v2/runs/219846639/files?recursive=false&filehrefcontentresolution=false&sortdir=Asc&sortby=Name&limit=2000&directory=/&
// extensions=.xml
_url := fmt.Sprintf(`/v2/runs/%s/files`, runId)
q := url.Values{}
if params != nil {
for k, v := range params {
q.Add(k, v)
}
}
base, err := url.Parse(_url)
if err != nil {
return nil, err
}
base.RawQuery = q.Encode()
body, err := self.GetBytes(ctx, base.String())
if err != nil {
return nil, err
}
ret := new(FileResp)
if err := json.Unmarshal(body, ret); err != nil {
return nil, err
}
return ret, nil
}
type FileS3PresignedUrlResp struct {
Expires string
HrefContent string
SupportsRange bool
}
func (self *Client) GetFileS3PresignedUrlResp(ctx context.Context, fileId string) (*FileS3PresignedUrlResp, error) {
url := fmt.Sprintf(`/v2/files/%s/content?redirect=meta`, fileId)
body, err := self.GetBytes(ctx, url)
if err != nil {
return nil, err
}
ret := new(FileS3PresignedUrlResp)
if err := json.Unmarshal(body, ret); err != nil {
return nil, err
}
return ret, nil
}