This commit is contained in:
parent
d4764ce485
commit
f1d98b605f
239
backend_s3.go
Normal file
239
backend_s3.go
Normal file
@ -0,0 +1,239 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"image"
|
||||
"image/jpeg"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"path"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
"github.com/aws/aws-sdk-go/service/s3"
|
||||
"github.com/aws/aws-sdk-go/service/s3/s3manager"
|
||||
)
|
||||
|
||||
func init() {
|
||||
existing_backends = append(existing_backends, "s3")
|
||||
}
|
||||
|
||||
type S3FileBackend struct {
|
||||
Endpoint string
|
||||
Region string
|
||||
Bucket string
|
||||
AccessKey string
|
||||
SecretKey string
|
||||
PathStyle bool
|
||||
BaseDir string
|
||||
}
|
||||
|
||||
func (l *S3FileBackend) getPath(box, name string) string {
|
||||
if l.BaseDir == "" {
|
||||
return path.Join(box, name+".jpg")
|
||||
} else {
|
||||
return path.Join(l.BaseDir, box, name+".jpg")
|
||||
}
|
||||
}
|
||||
|
||||
func (l *S3FileBackend) newSession() (*session.Session, error) {
|
||||
return session.NewSession(&aws.Config{
|
||||
Credentials: credentials.NewStaticCredentials(l.AccessKey, l.SecretKey, ""),
|
||||
Endpoint: &l.Endpoint,
|
||||
Region: &l.Region,
|
||||
S3ForcePathStyle: &l.PathStyle,
|
||||
})
|
||||
}
|
||||
|
||||
func (l *S3FileBackend) DeletePicture(box, name string) error {
|
||||
s, err := l.newSession()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Println(l.getPath(box, name))
|
||||
|
||||
input := &s3.DeleteObjectsInput{
|
||||
Bucket: aws.String(l.Bucket),
|
||||
Delete: &s3.Delete{
|
||||
Objects: []*s3.ObjectIdentifier{
|
||||
{
|
||||
Key: aws.String(l.getPath(box, name)),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
_, err = s3.New(s).DeleteObjects(input)
|
||||
return err
|
||||
}
|
||||
|
||||
func (l *S3FileBackend) ServeFile() http.Handler {
|
||||
return l
|
||||
}
|
||||
|
||||
func (l *S3FileBackend) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
s, err := l.newSession()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
result, err := s3.New(s).GetObject(&s3.GetObjectInput{
|
||||
Bucket: aws.String(l.Bucket),
|
||||
Key: aws.String(r.URL.Path),
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
io.Copy(w, result.Body)
|
||||
}
|
||||
|
||||
func (l *S3FileBackend) createPictureInfo(local_path, name string, file *s3.Object) *Picture {
|
||||
return &Picture{
|
||||
local_path, // Path
|
||||
name, // Basename
|
||||
name[:len(name)-len(path.Ext(name))], // Sanitized filename
|
||||
*file.LastModified, // UploadTime
|
||||
}
|
||||
}
|
||||
|
||||
func (l *S3FileBackend) GetPicture(box, name string, w io.Writer) error {
|
||||
s, err := l.newSession()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s3_path := l.getPath(box, name)
|
||||
|
||||
input := &s3.GetObjectInput{
|
||||
Bucket: aws.String(l.Bucket),
|
||||
Key: aws.String(s3_path),
|
||||
}
|
||||
|
||||
result, err := s3.New(s).GetObject(input)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = io.Copy(w, result.Body)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (l *S3FileBackend) GetPictureInfo(box, name string) (*Picture, error) {
|
||||
s, err := l.newSession()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
input := &s3.ListObjectsInput{
|
||||
Bucket: aws.String(l.Bucket),
|
||||
Prefix: aws.String(l.getPath(box, name)),
|
||||
}
|
||||
|
||||
result, err := s3.New(s).ListObjects(input)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var pictures []*Picture
|
||||
for _, file := range result.Contents {
|
||||
pictures = append(pictures, l.createPictureInfo(*file.Key, path.Base(*file.Key), file))
|
||||
break
|
||||
}
|
||||
|
||||
if len(pictures) == 0 {
|
||||
return nil, fmt.Errorf("Object not found")
|
||||
}
|
||||
|
||||
return pictures[0], nil
|
||||
}
|
||||
|
||||
func (l *S3FileBackend) ListPictures(box string) ([]*Picture, error) {
|
||||
s, err := l.newSession()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
input := &s3.ListObjectsInput{
|
||||
Bucket: aws.String(l.Bucket),
|
||||
}
|
||||
|
||||
if l.BaseDir == "" {
|
||||
input.Prefix = aws.String(box)
|
||||
} else {
|
||||
input.Prefix = aws.String(path.Join(l.BaseDir, box))
|
||||
}
|
||||
|
||||
result, err := s3.New(s).ListObjects(input)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pictures := make([]*Picture, 0)
|
||||
for _, file := range result.Contents {
|
||||
pictures = append(pictures, l.createPictureInfo(path.Join(box, *file.Key), path.Base(*file.Key), file))
|
||||
}
|
||||
|
||||
return pictures, nil
|
||||
}
|
||||
|
||||
func (l *S3FileBackend) MovePicture(box_from, box_to, name string) error {
|
||||
s, err := l.newSession()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Println(l.getPath(box_from, name), l.getPath(box_to, name))
|
||||
|
||||
_, err = s3.New(s).CopyObject(&s3.CopyObjectInput{
|
||||
Bucket: aws.String(l.Bucket),
|
||||
CopySource: aws.String(path.Join("", l.Bucket, l.getPath(box_from, name))),
|
||||
Key: aws.String(l.getPath(box_to, name)),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Println(l.getPath(box_from, name))
|
||||
|
||||
input := &s3.DeleteObjectsInput{
|
||||
Bucket: aws.String(l.Bucket),
|
||||
Delete: &s3.Delete{
|
||||
Objects: []*s3.ObjectIdentifier{
|
||||
{
|
||||
Key: aws.String(l.getPath(box_from, name)),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
_, err = s3.New(s).DeleteObjects(input)
|
||||
return err
|
||||
}
|
||||
|
||||
func (l *S3FileBackend) PutPicture(box, name string, img *image.Image) error {
|
||||
s, err := l.newSession()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
bbuf := new(bytes.Buffer)
|
||||
err = jpeg.Encode(bbuf, *img, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = s3manager.NewUploader(s).Upload(&s3manager.UploadInput{
|
||||
Bucket: aws.String(l.Bucket),
|
||||
ACL: aws.String("public-read"),
|
||||
Key: aws.String(l.getPath(box, name)),
|
||||
Body: bbuf,
|
||||
})
|
||||
|
||||
return err
|
||||
}
|
1
go.mod
1
go.mod
@ -3,6 +3,7 @@ module git.nemunai.re/youp0m
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/aws/aws-sdk-go v1.44.91
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
|
||||
gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b
|
||||
)
|
||||
|
17
go.sum
17
go.sum
@ -1,4 +1,21 @@
|
||||
github.com/aws/aws-sdk-go v1.44.91 h1:SRWmuX7PTyhBdLuvSfM7KWrWISJsrRsUPcFDSFduRxY=
|
||||
github.com/aws/aws-sdk-go v1.44.91/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
|
||||
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b h1:7gd+rd8P3bqcn/96gOZa3F5dpJr/vEiDQYlNb/y2uNs=
|
||||
gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b/go.mod h1:T3BPAOm2cqquPa0MKWeNkmOM5RQsRhkrwMWonFMN7fE=
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
|
Loading…
Reference in New Issue
Block a user