Files
nostrlib/khatru/blossom/eventstorewrapper.go

104 lines
2.4 KiB
Go

package blossom
import (
"context"
"iter"
"strconv"
"fiatjaf.com/nostr"
"fiatjaf.com/nostr/eventstore"
)
// EventStoreBlobIndexWrapper uses fake events to keep track of what blobs we have stored and who owns them
type EventStoreBlobIndexWrapper struct {
eventstore.Store
ServiceURL string
}
func (es EventStoreBlobIndexWrapper) Keep(ctx context.Context, blob BlobDescriptor, pubkey nostr.PubKey) error {
next, stop := iter.Pull(
es.Store.QueryEvents(nostr.Filter{Authors: []nostr.PubKey{pubkey}, Kinds: []nostr.Kind{24242}, Tags: nostr.TagMap{"x": []string{blob.SHA256}}}, 1),
)
defer stop()
if _, exists := next(); !exists {
// doesn't exist, save
evt := nostr.Event{
PubKey: pubkey,
Kind: 24242,
Tags: nostr.Tags{
{"x", blob.SHA256},
{"type", blob.Type},
{"size", strconv.Itoa(blob.Size)},
},
CreatedAt: blob.Uploaded,
}
evt.ID = evt.GetID()
es.Store.SaveEvent(evt)
}
return nil
}
func (es EventStoreBlobIndexWrapper) List(ctx context.Context, pubkey nostr.PubKey) iter.Seq[BlobDescriptor] {
return func(yield func(BlobDescriptor) bool) {
for evt := range es.Store.QueryEvents(nostr.Filter{
Authors: []nostr.PubKey{pubkey},
Kinds: []nostr.Kind{24242},
}, 1000) {
yield(es.parseEvent(evt))
}
}
}
func (es EventStoreBlobIndexWrapper) Get(ctx context.Context, sha256 string) (*BlobDescriptor, error) {
next, stop := iter.Pull(
es.Store.QueryEvents(nostr.Filter{Tags: nostr.TagMap{"x": []string{sha256}}, Kinds: []nostr.Kind{24242}, Limit: 1}, 1),
)
defer stop()
if evt, found := next(); found {
bd := es.parseEvent(evt)
return &bd, nil
}
return nil, nil
}
func (es EventStoreBlobIndexWrapper) Delete(ctx context.Context, sha256 string, pubkey nostr.PubKey) error {
next, stop := iter.Pull(
es.Store.QueryEvents(nostr.Filter{
Authors: []nostr.PubKey{pubkey},
Tags: nostr.TagMap{"x": []string{sha256}},
Kinds: []nostr.Kind{24242},
Limit: 1,
}, 1),
)
defer stop()
if evt, found := next(); found {
return es.Store.DeleteEvent(evt.ID)
}
return nil
}
func (es EventStoreBlobIndexWrapper) parseEvent(evt nostr.Event) BlobDescriptor {
hhash := evt.Tags[0][1]
mimetype := evt.Tags[1][1]
ext := getExtension(mimetype)
size, _ := strconv.Atoi(evt.Tags[2][1])
return BlobDescriptor{
Owner: evt.PubKey,
Uploaded: evt.CreatedAt,
URL: es.ServiceURL + "/" + hhash + ext,
SHA256: hhash,
Type: mimetype,
Size: size,
}
}