package media import ( "context" "errors" "github.com/minio/minio-go/v7" "github.com/minio/minio-go/v7/pkg/credentials" "git.mstar.dev/mstar/linstrom/config" ) type Server struct { client *minio.Client } /* TODO: Figure out an api for a microservice for transcoding media, see https://tech.lgbt/@lina/114682780787448797 - Read endpoint from config - Try to reach transcoder - If transcoder is alive, use it for transcoding - If not alive, store files as is */ var ( ErrNoBucketAccess = errors.New("can't access configured bucket") ) func NewServer() (*Server, error) { client, err := minio.New(config.GlobalConfig.S3.Endpoint, &minio.Options{ Creds: credentials.NewStaticV4( config.GlobalConfig.S3.KeyId, config.GlobalConfig.S3.Secret, "", ), Secure: config.GlobalConfig.S3.UseSSL, Region: config.GlobalConfig.S3.Region, }) if err != nil { return nil, err } ctx := context.Background() // Ensure we can access the bucket err = client.MakeBucket( ctx, config.GlobalConfig.S3.BucketName, minio.MakeBucketOptions{Region: config.GlobalConfig.S3.Region}, ) if err != nil { exists, err := client.BucketExists(ctx, config.GlobalConfig.S3.BucketName) if err != nil { return nil, err } if !exists { return nil, ErrNoBucketAccess } } return &Server{client: client}, nil } // UsernameFilename converts a userId and filename into a proper filepath for s3. // Reason for this is that the userId for external users is a valid url which needs to be encoded func UsernameFilename(userId, filename string) string { return userId + "//" + filename } func (s *Server) HasFileScoped(userId, filename string) (bool, error) { info, err := s.client.StatObject( context.Background(), config.GlobalConfig.S3.BucketName, UsernameFilename(userId, filename), minio.GetObjectOptions{}, ) if err != nil { return false, err } return info.IsDeleteMarker, nil }