|
|
package space
import ( "context" "errors" "fmt" "git.aiterp.net/rpdata/api/internal/config" "io"
minio "github.com/minio/minio-go" )
type Client struct { bucket string urlRoot string spaceRoot string maxSize int64
s3 *minio.Client }
func (client *Client) MaxSize() int64 { return client.maxSize }
// UploadFile uploads the file to the space. This does not do any checks on it, so the endpoints should
// ensure that's all okay.
func (client *Client) UploadFile(ctx context.Context, folder string, name string, mimeType string, reader io.Reader, size int64) (string, error) { path := folder + "/" + name
if size > client.maxSize { return "", errors.New("file is too big") }
_, err := client.s3.PutObjectWithContext(ctx, client.bucket, client.spaceRoot+"/"+path, reader, size, minio.PutObjectOptions{ ContentType: mimeType, UserMetadata: map[string]string{ "x-amz-acl": "public-read", }, }) if err != nil { return "", err }
_, err = client.s3.StatObject(client.bucket, client.spaceRoot+"/"+path, minio.StatObjectOptions{}) if err != nil { return "", err }
return path, nil }
// RemoveFile removes a file from the space
func (client *Client) RemoveFile(folder string, name string) error { path := folder + "/" + name
return client.s3.RemoveObject(client.bucket, client.spaceRoot+"/"+path) }
// DownloadFile opens a file for download, using the same path format as the UploadFile function. Remember to Close it!
// The returned stream also has `ReaderAt` and `Seeker`, but those are impl. details.
func (client *Client) DownloadFile(ctx context.Context, path string) (io.ReadCloser, error) { return client.s3.GetObjectWithContext(ctx, client.bucket, client.spaceRoot+"/"+path, minio.GetObjectOptions{}) }
// URLFromPath gets the URL from the path returned by UploadFile
func (client *Client) URLFromPath(path string) string { return client.urlRoot + path }
// Connect connects to a S3 space.
func Connect(cfg config.Space) (*Client, error) { client, err := minio.New(cfg.Host, cfg.AccessKey, cfg.SecretKey, true) if err != nil { return nil, err }
exists, err := client.BucketExists(cfg.Bucket) if err != nil { return nil, err } if !exists { return nil, errors.New("bucket not found") }
return &Client{ bucket: cfg.Bucket, urlRoot: fmt.Sprintf("https://%s.%s/%s/", cfg.Bucket, cfg.Host, cfg.Root), spaceRoot: cfg.Root, maxSize: cfg.MaxSize, s3: client, }, nil }
|