Contains the Concourse pipeline definition for building a line-server container
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

170 lines
3.4 KiB

package localfs
import (
"errors"
"io"
"io/ioutil"
"net/http"
"os"
"path"
"github.com/andreimarcu/linx-server/backends"
"github.com/andreimarcu/linx-server/torrent"
"github.com/aws/aws-sdk-go/aws"
"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"
"github.com/zeebo/bencode"
)
type S3Backend struct {
bucket string
svc *S3
}
func (b S3Backend) Delete(key string) error {
input := &s3.DeleteObjectInput{
Bucket: aws.String(b.bucket),
Key: aws.String(key),
}
_, err := b.svc.DeleteObject(input)
return os.Remove(path.Join(b.bucket, key))
}
func (b S3Backend) Exists(key string) (bool, error) {
input := &s3.HeadObjectInput{
Bucket: aws.String(b.bucket),
Key: aws.String(key),
}
_, err := b.svc.HeadObject(input)
return err == nil, err
}
func (b S3Backend) Get(key string) ([]byte, error) {
input := &s3.GetObjectInput{
Bucket: aws.String(b.bucket),
Key: aws.String(key),
}
result, err := b.svc.GetObject(input)
if err != nil {
return []byte{}, err
}
defer result.Body.Close()
return ioutil.ReadAll(result.Body)
}
func (b S3Backend) Put(key string, r io.Reader) (int64, error) {
uploader := s3manager.NewUploaderWithClient(b.svc)
input := &s3manager.UploadInput{
Bucket: aws.String(b.bucket),
Key: aws.String(key),
Body: r,
}
result, err := uploader.Upload(input)
if err != nil {
return 0, err
}
return -1, nil
}
func (b S3Backend) Open(key string) (backends.ReadSeekCloser, error) {
input := &s3.GetObjectInput{
Bucket: aws.String(b.bucket),
Key: aws.String(key),
}
result, err := b.svc.GetObject(input)
if err != nil {
return nil, err
}
return result.Body, nil
}
func (b S3Backend) ServeFile(key string, w http.ResponseWriter, r *http.Request) {
input := &s3.GetObjectInput{
Bucket: aws.String(b.bucket),
Key: aws.String(key),
}
result, err := b.svc.GetObject(input)
if err != nil {
return err
}
defer result.Body.Close()
http.ServeContent(w, r, key, *result.LastModified, result.Body)
return nil
}
func (b S3Backend) Size(key string) (int64, error) {
input := &s3.HeadObjectInput{
Bucket: aws.String(b.bucket),
Key: aws.String(key),
}
result, err := b.svc.HeadObject(input)
if err != nil {
return 0, err
}
return *result.ContentLength, nil
}
func (b S3Backend) GetTorrent(fileName string, url string) (t torrent.Torrent, err error) {
input := &s3.GetObjectTorrentInput{
Bucket: aws.String(b.bucket),
Key: aws.String(fileName),
}
result, err := b.svc.GetObjectTorrent(input)
if err != nil {
return
}
defer result.Body.Close()
data, err := ioutil.ReadAll(result.Body)
if err != nil {
return
}
err = bencode.DecodeBytes(data, &t)
if err != nil {
return
}
t.Info.Name = fileName
t.UrlList = []string{url}
return
}
func (b S3Backend) List() ([]string, error) {
var output []string
input := &s3.ListObjectsInput{
bucket: aws.String(b.bucket),
}
results, err := b.svc.ListObjects(input)
if err != nil {
return nil, err
}
for _, object := range results.Contents {
output = append(output, *object.Key)
}
return output, nil
}
func NewS3Backend(bucket string, region string, endpoint string) S3Backend {
awsConfig := &aws.Config{}
if region != "" {
awsConfig.Region = aws.String(region)
}
if endpoint != "" {
awsConfig.Endpoint = aws.String(endpoint)
}
sess := session.Must(session.NewSession(awsConfig))
svc := s3.New(sess)
return S3Backend{bucket: bucket, svc: svc}
}