package b2_client import ( "backea/internal/logging" "context" "fmt" "os" "github.com/joho/godotenv" "gopkg.in/kothar/go-backblaze.v0" ) // B2Error represents an error in B2 client operations type B2Error struct { Message string Cause error } func (e *B2Error) Error() string { if e.Cause != nil { return e.Message + ": " + e.Cause.Error() } return e.Message } func (e *B2Error) Unwrap() error { return e.Cause } func NewB2Error(message string, cause error) *B2Error { return &B2Error{ Message: message, Cause: cause, } } // Client represents a B2 client type Client struct { b2 *backblaze.B2 logger *logging.Logger } // NewClientFromEnv creates a new B2 client using credentials from .env func NewClientFromEnv() (*Client, error) { logger := logging.GetLogger() // Load .env file if err := godotenv.Load(); err != nil { return nil, NewB2Error("error loading .env file", err) } // Get credentials from environment keyID := os.Getenv("B2_KEY_ID") applicationKey := os.Getenv("B2_APPLICATION_KEY") if keyID == "" || applicationKey == "" { return nil, NewB2Error("B2_KEY_ID and B2_APPLICATION_KEY must be set in .env file", nil) } // Create B2 client b2, err := backblaze.NewB2(backblaze.Credentials{ AccountID: keyID, ApplicationKey: applicationKey, }) if err != nil { return nil, NewB2Error("error creating B2 client", err) } return &Client{ b2: b2, logger: logger, }, nil } // ListBuckets lists all buckets func (c *Client) ListBuckets(ctx context.Context) ([]*backblaze.Bucket, error) { // List all buckets buckets, err := c.b2.ListBuckets() if err != nil { return nil, NewB2Error("error listing buckets", err) } return buckets, nil } // GetBucket gets a bucket by name func (c *Client) GetBucket(ctx context.Context, name string) (*backblaze.Bucket, error) { // List all buckets buckets, err := c.b2.ListBuckets() if err != nil { return nil, NewB2Error("error listing buckets", err) } // Find bucket by name for _, bucket := range buckets { if bucket.Name == name { return bucket, nil } } return nil, NewB2Error(fmt.Sprintf("bucket not found: %s", name), nil) } // CreateBucket creates a new bucket func (c *Client) CreateBucket(ctx context.Context, name string, public bool) (*backblaze.Bucket, error) { // Set bucket type bucketType := backblaze.AllPrivate if public { bucketType = backblaze.AllPublic } // Create bucket bucket, err := c.b2.CreateBucket(name, bucketType) if err != nil { return nil, NewB2Error(fmt.Sprintf("error creating bucket '%s'", name), err) } c.logger.Info("Created B2 bucket: %s", name) return bucket, nil }