You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

144 lines
4.4 KiB

package blossom
import (
"os"
"path/filepath"
"lol.mleku.dev/log"
"next.orly.dev/pkg/database"
)
// Storage provides blob storage operations using the database interface.
// This is a thin wrapper that delegates to the database's blob methods.
type Storage struct {
db database.Database
blobDir string // Directory for storing blob files (for backward compatibility info)
}
// NewStorage creates a new storage instance using the database interface.
func NewStorage(db database.Database) *Storage {
// Derive blob directory from database path (for informational purposes)
blobDir := filepath.Join(db.Path(), "blossom")
// Ensure blob directory exists (the database implementation handles this,
// but we keep this for backward compatibility with code that checks the directory)
if err := os.MkdirAll(blobDir, 0755); err != nil {
log.E.F("failed to create blob directory %s: %v", blobDir, err)
}
return &Storage{
db: db,
blobDir: blobDir,
}
}
// SaveBlob stores a blob with its metadata.
// Delegates to the database interface's SaveBlob method.
func (s *Storage) SaveBlob(
sha256Hash []byte, data []byte, pubkey []byte, mimeType string, extension string,
) error {
return s.db.SaveBlob(sha256Hash, data, pubkey, mimeType, extension)
}
// GetBlob retrieves blob data by SHA256 hash.
// Returns the data and metadata from the database.
func (s *Storage) GetBlob(sha256Hash []byte) (data []byte, metadata *BlobMetadata, err error) {
data, dbMeta, err := s.db.GetBlob(sha256Hash)
if err != nil {
return nil, nil, err
}
// Convert database.BlobMetadata to blossom.BlobMetadata
metadata = &BlobMetadata{
Pubkey: dbMeta.Pubkey,
MimeType: dbMeta.MimeType,
Uploaded: dbMeta.Uploaded,
Size: dbMeta.Size,
Extension: dbMeta.Extension,
}
return data, metadata, nil
}
// HasBlob checks if a blob exists.
func (s *Storage) HasBlob(sha256Hash []byte) (exists bool, err error) {
return s.db.HasBlob(sha256Hash)
}
// DeleteBlob deletes a blob and its metadata.
func (s *Storage) DeleteBlob(sha256Hash []byte, pubkey []byte) error {
return s.db.DeleteBlob(sha256Hash, pubkey)
}
// ListBlobs lists all blobs for a given pubkey.
// Returns blob descriptors with time filtering.
func (s *Storage) ListBlobs(pubkey []byte, since, until int64) ([]*BlobDescriptor, error) {
dbDescriptors, err := s.db.ListBlobs(pubkey, since, until)
if err != nil {
return nil, err
}
// Convert database.BlobDescriptor to blossom.BlobDescriptor
descriptors := make([]*BlobDescriptor, 0, len(dbDescriptors))
for _, d := range dbDescriptors {
descriptors = append(descriptors, &BlobDescriptor{
URL: d.URL,
SHA256: d.SHA256,
Size: d.Size,
Type: d.Type,
Uploaded: d.Uploaded,
NIP94: d.NIP94,
})
}
return descriptors, nil
}
// GetBlobMetadata retrieves only metadata for a blob.
func (s *Storage) GetBlobMetadata(sha256Hash []byte) (*BlobMetadata, error) {
dbMeta, err := s.db.GetBlobMetadata(sha256Hash)
if err != nil {
return nil, err
}
// Convert database.BlobMetadata to blossom.BlobMetadata
return &BlobMetadata{
Pubkey: dbMeta.Pubkey,
MimeType: dbMeta.MimeType,
Uploaded: dbMeta.Uploaded,
Size: dbMeta.Size,
Extension: dbMeta.Extension,
}, nil
}
// GetTotalStorageUsed calculates total storage used by a pubkey in MB.
func (s *Storage) GetTotalStorageUsed(pubkey []byte) (totalMB int64, err error) {
return s.db.GetTotalBlobStorageUsed(pubkey)
}
// SaveReport stores a report for a blob (BUD-09).
func (s *Storage) SaveReport(sha256Hash []byte, reportData []byte) error {
return s.db.SaveBlobReport(sha256Hash, reportData)
}
// ListAllUserStats returns storage statistics for all users who have uploaded blobs.
func (s *Storage) ListAllUserStats() ([]*UserBlobStats, error) {
dbStats, err := s.db.ListAllBlobUserStats()
if err != nil {
return nil, err
}
// Convert database.UserBlobStats to blossom.UserBlobStats
stats := make([]*UserBlobStats, 0, len(dbStats))
for _, s := range dbStats {
stats = append(stats, &UserBlobStats{
PubkeyHex: s.PubkeyHex,
BlobCount: s.BlobCount,
TotalSizeBytes: s.TotalSizeBytes,
})
}
return stats, nil
}
// UserBlobStats represents storage statistics for a single user.
// This mirrors database.UserBlobStats for API compatibility.
type UserBlobStats struct {
PubkeyHex string `json:"pubkey"`
BlobCount int64 `json:"blob_count"`
TotalSizeBytes int64 `json:"total_size_bytes"`
}