linstrom/media/media.go
mstar e317da1b66
Some checks failed
/ docker (push) Failing after 1m48s
More work on file storage
2025-06-16 17:01:15 +02:00

81 lines
2 KiB
Go

package media
import (
"context"
"errors"
"github.com/rs/zerolog/log"
"net/rpc"
"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
transcoderClient *rpc.Client
}
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
}
}
transcoderClient, err := rpc.DialHTTP("tcp", config.GlobalConfig.Transcoder.Address())
if err != nil {
log.Warn().Err(err).
Str("address", config.GlobalConfig.Transcoder.Address()).
Msg("failed to dial transcoder, various media related features won't be available")
transcoderClient = nil
}
return &Server{client: client, transcoderClient: transcoderClient}, 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
}