5
5
package models
6
6
7
7
import (
8
+ "context"
8
9
"fmt"
9
10
"io"
10
- "os"
11
11
"path"
12
12
13
13
"code.gitea.io/gitea/modules/setting"
@@ -16,6 +16,7 @@ import (
16
16
17
17
"github.com/go-xorm/xorm"
18
18
gouuid "github.com/satori/go.uuid"
19
+ "gocloud.dev/blob"
19
20
)
20
21
21
22
// Attachment represent a attachment of issue/comment/release.
@@ -71,33 +72,41 @@ func (a *Attachment) DownloadURL() string {
71
72
return fmt .Sprintf ("%sattachments/%s" , setting .AppURL , a .UUID )
72
73
}
73
74
74
- // NewAttachment creates a new attachment object.
75
- func NewAttachment (attach * Attachment , buf []byte , file io.Reader ) (_ * Attachment , err error ) {
76
- attach .UUID = gouuid .NewV4 ().String ()
77
-
78
- localPath := attach .LocalPath ()
79
- if err = os .MkdirAll (path .Dir (localPath ), os .ModePerm ); err != nil {
80
- return nil , fmt .Errorf ("MkdirAll: %v" , err )
75
+ // uploadAttachmentToBucket uploads attachments to bucket
76
+ func (attach * Attachment ) UploadAttachmentToBucket (buf []byte , file io.Reader ) (* Attachment , error ) {
77
+ ctx := context .Background ()
78
+ bucket , err := blob .OpenBucket (ctx , setting .FileStorage .Bucket )
79
+ if err != nil {
80
+ return nil , fmt .Errorf ("Failed to setup bucket: %v" , err )
81
81
}
82
+ bucket = blob .PrefixedBucket (bucket , "data/attachments/" )
82
83
83
- fw , err := os . Create ( localPath )
84
+ bucketWriter , err := bucket . NewWriter ( ctx , attach . LocalPath (), nil )
84
85
if err != nil {
85
- return nil , fmt .Errorf ("Create : %v" , err )
86
+ return nil , fmt .Errorf ("Failed to obtain writer : %v" , err )
86
87
}
87
- defer fw .Close ()
88
+ var fileSize int64
89
+ if _ , err = bucketWriter .Write (buf ); err != nil {
90
+ return nil , fmt .Errorf ("error occurred while writing: %v" , err )
91
+ } else if fileSize , err = io .Copy (bucketWriter , file ); err != nil {
92
+ return nil , fmt .Errorf ("error occurred while copying: %v" , err )
93
+ }
94
+ attach .Size = fileSize
88
95
89
- if _ , err = fw .Write (buf ); err != nil {
90
- return nil , fmt .Errorf ("Write: %v" , err )
91
- } else if _ , err = io .Copy (fw , file ); err != nil {
92
- return nil , fmt .Errorf ("Copy: %v" , err )
96
+ if err = bucketWriter .Close (); err != nil {
97
+ return nil , fmt .Errorf ("Failed to close: %v" , err )
93
98
}
99
+ return attach , nil
100
+ }
101
+
102
+ // NewAttachment creates a new attachment object.
103
+ func NewAttachment (attach * Attachment , buf []byte , file io.Reader ) (_ * Attachment , err error ) {
104
+ attach .UUID = gouuid .NewV4 ().String ()
94
105
95
- // Update file size
96
- var fi os.FileInfo
97
- if fi , err = fw .Stat (); err != nil {
98
- return nil , fmt .Errorf ("file size: %v" , err )
106
+ attach , err = attach .UploadAttachmentToBucket (buf , file )
107
+ if err != nil {
108
+ return nil , err
99
109
}
100
- attach .Size = fi .Size ()
101
110
102
111
if _ , err := x .Insert (attach ); err != nil {
103
112
return nil , err
@@ -185,6 +194,49 @@ func getAttachmentByReleaseIDFileName(e Engine, releaseID int64, fileName string
185
194
return attach , nil
186
195
}
187
196
197
+ // GetAttachmentReader provides attachment reader from bucket
198
+ func (attach * Attachment ) GetAttachmentReader () (io.ReadCloser , error ) {
199
+ ctx := context .Background ()
200
+ bucket , err := blob .OpenBucket (ctx , setting .FileStorage .Bucket )
201
+ if err != nil {
202
+ return nil , fmt .Errorf ("Failed to setup bucket %v" , err )
203
+ }
204
+ bucket = blob .PrefixedBucket (bucket , "data/attachments/" )
205
+
206
+ exist , err := bucket .Exists (ctx , attach .LocalPath ())
207
+ if err != nil {
208
+ return nil , err
209
+ } else if ! exist {
210
+ return nil , fmt .Errorf ("Attachment not found" )
211
+ }
212
+
213
+ reader , err := bucket .NewReader (ctx , attach .LocalPath (), nil )
214
+ if err != nil {
215
+ return nil , err
216
+ }
217
+
218
+ return reader , nil
219
+ }
220
+
221
+ // deleteAttachmentFromBucket deletes attachments from bucket
222
+ func (attach * Attachment ) deleteAttachmentFromBucket () error {
223
+ ctx := context .Background ()
224
+ bucket , err := blob .OpenBucket (ctx , setting .FileStorage .Bucket )
225
+ if err != nil {
226
+ return fmt .Errorf ("Failed to setup bucket: %v" , err )
227
+ }
228
+ bucket = blob .PrefixedBucket (bucket , "data/attachments/" )
229
+
230
+ exist , err := bucket .Exists (ctx , attach .LocalPath ())
231
+ if err != nil {
232
+ return err
233
+ } else if ! exist {
234
+ return fmt .Errorf ("repo avatar not found" )
235
+ }
236
+
237
+ return bucket .Delete (ctx , attach .LocalPath ())
238
+ }
239
+
188
240
// DeleteAttachment deletes the given attachment and optionally the associated file.
189
241
func DeleteAttachment (a * Attachment , remove bool ) error {
190
242
_ , err := DeleteAttachments ([]* Attachment {a }, remove )
@@ -209,7 +261,7 @@ func DeleteAttachments(attachments []*Attachment, remove bool) (int, error) {
209
261
210
262
if remove {
211
263
for i , a := range attachments {
212
- if err := os . Remove ( a . LocalPath () ); err != nil {
264
+ if err := a . deleteAttachmentFromBucket ( ); err != nil {
213
265
return i , err
214
266
}
215
267
}
0 commit comments