Yimaru-BackEnd/internal/pkgs/minio/client.go
Yared Yemane 0d02eb1a24 add MinIO media URL refresh endpoint
Add POST /api/v1/files/refresh-url to issue fresh presigned URLs from object keys, minio:// references, or stale presigned URLs so clients can refresh media links before render.

Made-with: Cursor
2026-04-27 05:25:16 -07:00

69 lines
1.7 KiB
Go

package minio
import (
"context"
"io"
"time"
"github.com/minio/minio-go/v7"
"github.com/minio/minio-go/v7/pkg/credentials"
)
type Client struct {
mc *minio.Client
bucketName string
}
func (c *Client) BucketName() string {
return c.bucketName
}
func NewClient(endpoint, accessKey, secretKey string, useSSL bool, bucketName string) (*Client, error) {
mc, err := minio.New(endpoint, &minio.Options{
Creds: credentials.NewStaticV4(accessKey, secretKey, ""),
Secure: useSSL,
})
if err != nil {
return nil, err
}
return &Client{
mc: mc,
bucketName: bucketName,
}, nil
}
// EnsureBucket creates the bucket if it doesn't exist.
func (c *Client) EnsureBucket(ctx context.Context) error {
exists, err := c.mc.BucketExists(ctx, c.bucketName)
if err != nil {
return err
}
if !exists {
return c.mc.MakeBucket(ctx, c.bucketName, minio.MakeBucketOptions{})
}
return nil
}
// UploadFile uploads a file to MinIO and returns the object key.
func (c *Client) UploadFile(ctx context.Context, objectKey string, reader io.Reader, fileSize int64, contentType string) error {
_, err := c.mc.PutObject(ctx, c.bucketName, objectKey, reader, fileSize, minio.PutObjectOptions{
ContentType: contentType,
})
return err
}
// GetFileURL returns a presigned URL valid for the given duration.
func (c *Client) GetFileURL(ctx context.Context, objectKey string, expiry time.Duration) (string, error) {
u, err := c.mc.PresignedGetObject(ctx, c.bucketName, objectKey, expiry, nil)
if err != nil {
return "", err
}
return u.String(), nil
}
// DeleteFile removes an object from the bucket.
func (c *Client) DeleteFile(ctx context.Context, objectKey string) error {
return c.mc.RemoveObject(ctx, c.bucketName, objectKey, minio.RemoveObjectOptions{})
}