1
0
mirror of https://github.com/fiatjaf/nak.git synced 2025-08-20 17:40:47 -04:00

fs: pass NostrRoot everywhere with a signer only if it can actually sign.

This commit is contained in:
fiatjaf
2025-03-11 13:18:33 -03:00
parent bfe1e6ca94
commit c87371208e
6 changed files with 119 additions and 137 deletions

13
fs.go

@@ -22,7 +22,7 @@ var fsCmd = &cli.Command{
Usage: "mount a FUSE filesystem that exposes Nostr events as files.",
Description: `(experimental)`,
ArgsUsage: "<mountpoint>",
Flags: []cli.Flag{
Flags: append(defaultKeyFlags,
&cli.StringFlag{
Name: "pubkey",
Usage: "public key from where to to prepopulate directories",
@@ -33,7 +33,7 @@ var fsCmd = &cli.Command{
return fmt.Errorf("invalid public key '%s'", pk)
},
},
},
),
DisableSliceFlagSeparator: true,
Action: func(ctx context.Context, c *cli.Command) error {
mountpoint := c.Args().First()
@@ -41,10 +41,17 @@ var fsCmd = &cli.Command{
return fmt.Errorf("must be called with a directory path to serve as the mountpoint as an argument")
}
var kr nostr.User
if signer, _, err := gatherKeyerFromArguments(ctx, c); err == nil {
kr = signer
} else {
kr = keyer.NewReadOnlyUser(c.String("pubkey"))
}
root := nostrfs.NewNostrRoot(
context.WithValue(ctx, "log", log),
sys,
keyer.NewReadOnlyUser(c.String("pubkey")),
kr,
mountpoint,
)

@@ -42,36 +42,31 @@ func (e *EntityDir) Getattr(_ context.Context, f fs.FileHandle, out *fuse.AttrOu
return fs.OK
}
func FetchAndCreateEntityDir(
ctx context.Context,
func (r *NostrRoot) FetchAndCreateEntityDir(
parent fs.InodeEmbedder,
wd string,
extension string,
sys *sdk.System,
pointer nostr.EntityPointer,
) (*fs.Inode, error) {
event, _, err := sys.FetchSpecificEvent(ctx, pointer, sdk.FetchSpecificEventParameters{
event, _, err := r.sys.FetchSpecificEvent(r.ctx, pointer, sdk.FetchSpecificEventParameters{
WithRelays: false,
})
if err != nil {
return nil, fmt.Errorf("failed to fetch: %w", err)
}
return CreateEntityDir(ctx, parent, wd, extension, event), nil
return r.CreateEntityDir(parent, extension, event), nil
}
func CreateEntityDir(
ctx context.Context,
func (r *NostrRoot) CreateEntityDir(
parent fs.InodeEmbedder,
wd string,
extension string,
event *nostr.Event,
) *fs.Inode {
log := ctx.Value("log").(func(msg string, args ...any))
log := r.ctx.Value("log").(func(msg string, args ...any))
h := parent.EmbeddedInode().NewPersistentInode(
ctx,
&EntityDir{ctx: ctx, wd: wd, evt: event},
r.ctx,
&EntityDir{ctx: r.ctx, wd: r.wd, evt: event},
fs.StableAttr{Mode: syscall.S_IFDIR, Ino: hexToUint64(event.ID)},
)
@@ -82,16 +77,16 @@ func CreateEntityDir(
npub, _ := nip19.EncodePublicKey(event.PubKey)
h.AddChild("@author", h.NewPersistentInode(
ctx,
r.ctx,
&fs.MemSymlink{
Data: []byte(wd + "/" + npub),
Data: []byte(r.wd + "/" + npub),
},
fs.StableAttr{Mode: syscall.S_IFLNK},
), true)
eventj, _ := json.MarshalIndent(event, "", " ")
h.AddChild("event.json", h.NewPersistentInode(
ctx,
r.ctx,
&fs.MemRegularFile{
Data: eventj,
Attr: fuse.Attr{
@@ -105,7 +100,7 @@ func CreateEntityDir(
), true)
h.AddChild("identifier", h.NewPersistentInode(
ctx,
r.ctx,
&fs.MemRegularFile{
Data: []byte(event.Tags.GetD()),
Attr: fuse.Attr{
@@ -120,7 +115,7 @@ func CreateEntityDir(
if tag := event.Tags.Find("title"); tag != nil {
h.AddChild("title", h.NewPersistentInode(
ctx,
r.ctx,
&fs.MemRegularFile{
Data: []byte(tag[1]),
Attr: fuse.Attr{
@@ -135,7 +130,7 @@ func CreateEntityDir(
}
h.AddChild("content"+extension, h.NewPersistentInode(
ctx,
r.ctx,
&fs.MemRegularFile{
Data: []byte(event.Content),
Attr: fuse.Attr{
@@ -153,13 +148,13 @@ func CreateEntityDir(
for ref := range nip27.ParseReferences(*event) {
i++
if refsdir == nil {
refsdir = h.NewPersistentInode(ctx, &fs.Inode{}, fs.StableAttr{Mode: syscall.S_IFDIR})
refsdir = h.NewPersistentInode(r.ctx, &fs.Inode{}, fs.StableAttr{Mode: syscall.S_IFDIR})
h.AddChild("references", refsdir, true)
}
refsdir.AddChild(fmt.Sprintf("ref_%02d", i), refsdir.NewPersistentInode(
ctx,
r.ctx,
&fs.MemSymlink{
Data: []byte(wd + "/" + nip19.EncodePointer(ref.Pointer)),
Data: []byte(r.wd + "/" + nip19.EncodePointer(ref.Pointer)),
},
fs.StableAttr{Mode: syscall.S_IFLNK},
), true)
@@ -169,15 +164,15 @@ func CreateEntityDir(
addImage := func(url string) {
if imagesdir == nil {
in := &fs.Inode{}
imagesdir = h.NewPersistentInode(ctx, in, fs.StableAttr{Mode: syscall.S_IFDIR})
imagesdir = h.NewPersistentInode(r.ctx, in, fs.StableAttr{Mode: syscall.S_IFDIR})
h.AddChild("images", imagesdir, true)
}
imagesdir.AddChild(filepath.Base(url), imagesdir.NewPersistentInode(
ctx,
r.ctx,
&AsyncFile{
ctx: ctx,
ctx: r.ctx,
load: func() ([]byte, nostr.Timestamp) {
ctx, cancel := context.WithTimeout(ctx, time.Second*20)
ctx, cancel := context.WithTimeout(r.ctx, time.Second*20)
defer cancel()
r, err := http.NewRequestWithContext(ctx, "GET", url, nil)
if err != nil {

@@ -36,47 +36,42 @@ func (e *EventDir) Getattr(_ context.Context, f fs.FileHandle, out *fuse.AttrOut
return fs.OK
}
func FetchAndCreateEventDir(
ctx context.Context,
func (r *NostrRoot) FetchAndCreateEventDir(
parent fs.InodeEmbedder,
wd string,
sys *sdk.System,
pointer nostr.EventPointer,
) (*fs.Inode, error) {
event, _, err := sys.FetchSpecificEvent(ctx, pointer, sdk.FetchSpecificEventParameters{
event, _, err := r.sys.FetchSpecificEvent(r.ctx, pointer, sdk.FetchSpecificEventParameters{
WithRelays: false,
})
if err != nil {
return nil, fmt.Errorf("failed to fetch: %w", err)
}
return CreateEventDir(ctx, parent, wd, event), nil
return r.CreateEventDir(parent, event), nil
}
func CreateEventDir(
ctx context.Context,
func (r *NostrRoot) CreateEventDir(
parent fs.InodeEmbedder,
wd string,
event *nostr.Event,
) *fs.Inode {
h := parent.EmbeddedInode().NewPersistentInode(
ctx,
&EventDir{ctx: ctx, wd: wd, evt: event},
r.ctx,
&EventDir{ctx: r.ctx, wd: r.wd, evt: event},
fs.StableAttr{Mode: syscall.S_IFDIR, Ino: hexToUint64(event.ID)},
)
npub, _ := nip19.EncodePublicKey(event.PubKey)
h.AddChild("@author", h.NewPersistentInode(
ctx,
r.ctx,
&fs.MemSymlink{
Data: []byte(wd + "/" + npub),
Data: []byte(r.wd + "/" + npub),
},
fs.StableAttr{Mode: syscall.S_IFLNK},
), true)
eventj, _ := json.MarshalIndent(event, "", " ")
h.AddChild("event.json", h.NewPersistentInode(
ctx,
r.ctx,
&fs.MemRegularFile{
Data: eventj,
Attr: fuse.Attr{
@@ -90,7 +85,7 @@ func CreateEventDir(
), true)
h.AddChild("id", h.NewPersistentInode(
ctx,
r.ctx,
&fs.MemRegularFile{
Data: []byte(event.ID),
Attr: fuse.Attr{
@@ -104,7 +99,7 @@ func CreateEventDir(
), true)
h.AddChild("content.txt", h.NewPersistentInode(
ctx,
r.ctx,
&fs.MemRegularFile{
Data: []byte(event.Content),
Attr: fuse.Attr{
@@ -122,13 +117,13 @@ func CreateEventDir(
for ref := range nip27.ParseReferences(*event) {
i++
if refsdir == nil {
refsdir = h.NewPersistentInode(ctx, &fs.Inode{}, fs.StableAttr{Mode: syscall.S_IFDIR})
refsdir = h.NewPersistentInode(r.ctx, &fs.Inode{}, fs.StableAttr{Mode: syscall.S_IFDIR})
h.AddChild("references", refsdir, true)
}
refsdir.AddChild(fmt.Sprintf("ref_%02d", i), refsdir.NewPersistentInode(
ctx,
r.ctx,
&fs.MemSymlink{
Data: []byte(wd + "/" + nip19.EncodePointer(ref.Pointer)),
Data: []byte(r.wd + "/" + nip19.EncodePointer(ref.Pointer)),
},
fs.StableAttr{Mode: syscall.S_IFLNK},
), true)
@@ -142,15 +137,15 @@ func CreateEventDir(
}
if imagesdir == nil {
in := &fs.Inode{}
imagesdir = h.NewPersistentInode(ctx, in, fs.StableAttr{Mode: syscall.S_IFDIR})
imagesdir = h.NewPersistentInode(r.ctx, in, fs.StableAttr{Mode: syscall.S_IFDIR})
h.AddChild("images", imagesdir, true)
}
imagesdir.AddChild(filepath.Base(imeta.URL), imagesdir.NewPersistentInode(
ctx,
r.ctx,
&AsyncFile{
ctx: ctx,
ctx: r.ctx,
load: func() ([]byte, nostr.Timestamp) {
ctx, cancel := context.WithTimeout(ctx, time.Second*20)
ctx, cancel := context.WithTimeout(r.ctx, time.Second*20)
defer cancel()
r, err := http.NewRequestWithContext(ctx, "GET", imeta.URL, nil)
if err != nil {
@@ -177,9 +172,9 @@ func CreateEventDir(
if pointer := nip10.GetThreadRoot(event.Tags); pointer != nil {
nevent := nip19.EncodePointer(*pointer)
h.AddChild("@root", h.NewPersistentInode(
ctx,
r.ctx,
&fs.MemSymlink{
Data: []byte(wd + "/" + nevent),
Data: []byte(r.wd + "/" + nevent),
},
fs.StableAttr{Mode: syscall.S_IFLNK},
), true)
@@ -187,9 +182,9 @@ func CreateEventDir(
if pointer := nip10.GetImmediateParent(event.Tags); pointer != nil {
nevent := nip19.EncodePointer(*pointer)
h.AddChild("@parent", h.NewPersistentInode(
ctx,
r.ctx,
&fs.MemSymlink{
Data: []byte(wd + "/" + nevent),
Data: []byte(r.wd + "/" + nevent),
},
fs.StableAttr{Mode: syscall.S_IFLNK},
), true)
@@ -198,7 +193,7 @@ func CreateEventDir(
if pointer := nip22.GetThreadRoot(event.Tags); pointer != nil {
if xp, ok := pointer.(nostr.ExternalPointer); ok {
h.AddChild("@root", h.NewPersistentInode(
ctx,
r.ctx,
&fs.MemRegularFile{
Data: []byte(`<!doctype html><meta http-equiv="refresh" content="0; url=` + xp.Thing + `" />`),
},
@@ -207,9 +202,9 @@ func CreateEventDir(
} else {
nevent := nip19.EncodePointer(pointer)
h.AddChild("@parent", h.NewPersistentInode(
ctx,
r.ctx,
&fs.MemSymlink{
Data: []byte(wd + "/" + nevent),
Data: []byte(r.wd + "/" + nevent),
},
fs.StableAttr{Mode: syscall.S_IFLNK},
), true)
@@ -218,7 +213,7 @@ func CreateEventDir(
if pointer := nip22.GetImmediateParent(event.Tags); pointer != nil {
if xp, ok := pointer.(nostr.ExternalPointer); ok {
h.AddChild("@parent", h.NewPersistentInode(
ctx,
r.ctx,
&fs.MemRegularFile{
Data: []byte(`<!doctype html><meta http-equiv="refresh" content="0; url=` + xp.Thing + `" />`),
},
@@ -227,9 +222,9 @@ func CreateEventDir(
} else {
nevent := nip19.EncodePointer(pointer)
h.AddChild("@parent", h.NewPersistentInode(
ctx,
r.ctx,
&fs.MemSymlink{
Data: []byte(wd + "/" + nevent),
Data: []byte(r.wd + "/" + nevent),
},
fs.StableAttr{Mode: syscall.S_IFLNK},
), true)

@@ -14,41 +14,37 @@ import (
"github.com/hanwen/go-fuse/v2/fuse"
"github.com/liamg/magic"
"github.com/nbd-wtf/go-nostr"
sdk "github.com/nbd-wtf/go-nostr/sdk"
)
type NpubDir struct {
sys *sdk.System
fs.Inode
root *NostrRoot
pointer nostr.ProfilePointer
ctx context.Context
fetched atomic.Bool
}
func CreateNpubDir(
ctx context.Context,
sys *sdk.System,
func (r *NostrRoot) CreateNpubDir(
parent fs.InodeEmbedder,
wd string,
pointer nostr.ProfilePointer,
signer nostr.Signer,
) *fs.Inode {
npubdir := &NpubDir{ctx: ctx, sys: sys, pointer: pointer}
npubdir := &NpubDir{root: r, pointer: pointer}
h := parent.EmbeddedInode().NewPersistentInode(
ctx,
r.ctx,
npubdir,
fs.StableAttr{Mode: syscall.S_IFDIR, Ino: hexToUint64(pointer.PublicKey)},
)
relays := sys.FetchOutboxRelays(ctx, pointer.PublicKey, 2)
relays := r.sys.FetchOutboxRelays(r.ctx, pointer.PublicKey, 2)
h.AddChild("pubkey", h.NewPersistentInode(
ctx,
r.ctx,
&fs.MemRegularFile{Data: []byte(pointer.PublicKey + "\n"), Attr: fuse.Attr{Mode: 0444}},
fs.StableAttr{},
), true)
go func() {
pm := sys.FetchProfileMetadata(ctx, pointer.PublicKey)
pm := r.sys.FetchProfileMetadata(r.ctx, pointer.PublicKey)
if pm.Event == nil {
return
}
@@ -57,7 +53,7 @@ func CreateNpubDir(
h.AddChild(
"metadata.json",
h.NewPersistentInode(
ctx,
r.ctx,
&fs.MemRegularFile{
Data: metadataj,
Attr: fuse.Attr{
@@ -70,7 +66,7 @@ func CreateNpubDir(
true,
)
ctx, cancel := context.WithTimeout(ctx, time.Second*20)
ctx, cancel := context.WithTimeout(r.ctx, time.Second*20)
defer cancel()
r, err := http.NewRequestWithContext(ctx, "GET", pm.Picture, nil)
if err == nil {
@@ -105,19 +101,17 @@ func CreateNpubDir(
h.AddChild(
"notes",
h.NewPersistentInode(
ctx,
r.ctx,
&ViewDir{
ctx: ctx,
sys: sys,
wd: wd,
root: r,
filter: nostr.Filter{
Kinds: []int{1},
Authors: []string{pointer.PublicKey},
},
paginate: true,
relays: relays,
create: func(ctx context.Context, n *ViewDir, event *nostr.Event) (string, *fs.Inode) {
return event.ID, CreateEventDir(ctx, n, n.wd, event)
create: func(n *ViewDir, event *nostr.Event) (string, *fs.Inode) {
return event.ID, r.CreateEventDir(n, event)
},
},
fs.StableAttr{Mode: syscall.S_IFDIR},
@@ -128,19 +122,17 @@ func CreateNpubDir(
h.AddChild(
"comments",
h.NewPersistentInode(
ctx,
r.ctx,
&ViewDir{
ctx: ctx,
sys: sys,
wd: wd,
root: r,
filter: nostr.Filter{
Kinds: []int{1111},
Authors: []string{pointer.PublicKey},
},
paginate: true,
relays: relays,
create: func(ctx context.Context, n *ViewDir, event *nostr.Event) (string, *fs.Inode) {
return event.ID, CreateEventDir(ctx, n, n.wd, event)
create: func(n *ViewDir, event *nostr.Event) (string, *fs.Inode) {
return event.ID, r.CreateEventDir(n, event)
},
},
fs.StableAttr{Mode: syscall.S_IFDIR},
@@ -151,19 +143,17 @@ func CreateNpubDir(
h.AddChild(
"photos",
h.NewPersistentInode(
ctx,
r.ctx,
&ViewDir{
ctx: ctx,
sys: sys,
wd: wd,
root: r,
filter: nostr.Filter{
Kinds: []int{20},
Authors: []string{pointer.PublicKey},
},
paginate: true,
relays: relays,
create: func(ctx context.Context, n *ViewDir, event *nostr.Event) (string, *fs.Inode) {
return event.ID, CreateEventDir(ctx, n, n.wd, event)
create: func(n *ViewDir, event *nostr.Event) (string, *fs.Inode) {
return event.ID, r.CreateEventDir(n, event)
},
},
fs.StableAttr{Mode: syscall.S_IFDIR},
@@ -174,19 +164,17 @@ func CreateNpubDir(
h.AddChild(
"videos",
h.NewPersistentInode(
ctx,
r.ctx,
&ViewDir{
ctx: ctx,
sys: sys,
wd: wd,
root: r,
filter: nostr.Filter{
Kinds: []int{21, 22},
Authors: []string{pointer.PublicKey},
},
paginate: false,
relays: relays,
create: func(ctx context.Context, n *ViewDir, event *nostr.Event) (string, *fs.Inode) {
return event.ID, CreateEventDir(ctx, n, n.wd, event)
create: func(n *ViewDir, event *nostr.Event) (string, *fs.Inode) {
return event.ID, r.CreateEventDir(n, event)
},
},
fs.StableAttr{Mode: syscall.S_IFDIR},
@@ -197,19 +185,17 @@ func CreateNpubDir(
h.AddChild(
"highlights",
h.NewPersistentInode(
ctx,
r.ctx,
&ViewDir{
ctx: ctx,
sys: sys,
wd: wd,
root: r,
filter: nostr.Filter{
Kinds: []int{9802},
Authors: []string{pointer.PublicKey},
},
paginate: false,
relays: relays,
create: func(ctx context.Context, n *ViewDir, event *nostr.Event) (string, *fs.Inode) {
return event.ID, CreateEventDir(ctx, n, n.wd, event)
create: func(n *ViewDir, event *nostr.Event) (string, *fs.Inode) {
return event.ID, r.CreateEventDir(n, event)
},
},
fs.StableAttr{Mode: syscall.S_IFDIR},
@@ -220,23 +206,21 @@ func CreateNpubDir(
h.AddChild(
"articles",
h.NewPersistentInode(
ctx,
r.ctx,
&ViewDir{
ctx: ctx,
sys: sys,
wd: wd,
root: r,
filter: nostr.Filter{
Kinds: []int{30023},
Authors: []string{pointer.PublicKey},
},
paginate: false,
relays: relays,
create: func(ctx context.Context, n *ViewDir, event *nostr.Event) (string, *fs.Inode) {
create: func(n *ViewDir, event *nostr.Event) (string, *fs.Inode) {
d := event.Tags.GetD()
if d == "" {
d = "_"
}
return d, CreateEntityDir(ctx, n, n.wd, ".md", event)
return d, r.CreateEntityDir(n, ".md", event)
},
},
fs.StableAttr{Mode: syscall.S_IFDIR},
@@ -247,23 +231,21 @@ func CreateNpubDir(
h.AddChild(
"wiki",
h.NewPersistentInode(
ctx,
r.ctx,
&ViewDir{
ctx: ctx,
sys: sys,
wd: wd,
root: r,
filter: nostr.Filter{
Kinds: []int{30818},
Authors: []string{pointer.PublicKey},
},
paginate: false,
relays: relays,
create: func(ctx context.Context, n *ViewDir, event *nostr.Event) (string, *fs.Inode) {
create: func(n *ViewDir, event *nostr.Event) (string, *fs.Inode) {
d := event.Tags.GetD()
if d == "" {
d = "_"
}
return d, CreateEntityDir(ctx, n, n.wd, ".adoc", event)
return d, r.CreateEntityDir(n, ".adoc", event)
},
},
fs.StableAttr{Mode: syscall.S_IFDIR},

@@ -28,9 +28,13 @@ var _ = (fs.NodeOnAdder)((*NostrRoot)(nil))
func NewNostrRoot(ctx context.Context, sys *sdk.System, user nostr.User, mountpoint string) *NostrRoot {
pubkey, _ := user.GetPublicKey(ctx)
signer, _ := user.(nostr.Signer)
abs, _ := filepath.Abs(mountpoint)
var signer nostr.Signer
if user != nil {
signer, _ = user.(nostr.Signer)
}
return &NostrRoot{
ctx: ctx,
sys: sys,
@@ -52,7 +56,7 @@ func (r *NostrRoot) OnAdd(_ context.Context) {
npub, _ := nip19.EncodePublicKey(f.Pubkey)
r.AddChild(
npub,
CreateNpubDir(r.ctx, r.sys, r, r.wd, pointer),
r.CreateNpubDir(r, pointer, nil),
true,
)
}
@@ -61,9 +65,10 @@ func (r *NostrRoot) OnAdd(_ context.Context) {
npub, _ := nip19.EncodePublicKey(r.rootPubKey)
if r.GetChild(npub) == nil {
pointer := nostr.ProfilePointer{PublicKey: r.rootPubKey}
r.AddChild(
npub,
CreateNpubDir(r.ctx, r.sys, r, r.wd, pointer),
r.CreateNpubDir(r, pointer, r.signer),
true,
)
}
@@ -85,8 +90,11 @@ func (r *NostrRoot) Lookup(_ context.Context, name string, out *fuse.EntryOut) (
}
if pp, err := nip05.QueryIdentifier(r.ctx, name); err == nil {
npubdir := CreateNpubDir(r.ctx, r.sys, r, r.wd, *pp)
return npubdir, fs.OK
return r.NewPersistentInode(
r.ctx,
&fs.MemSymlink{Data: []byte(r.wd + "/" + nip19.EncodePointer(*pp))},
fs.StableAttr{Mode: syscall.S_IFLNK},
), fs.OK
}
pointer, err := nip19.ToPointer(name)
@@ -96,10 +104,10 @@ func (r *NostrRoot) Lookup(_ context.Context, name string, out *fuse.EntryOut) (
switch p := pointer.(type) {
case nostr.ProfilePointer:
npubdir := CreateNpubDir(r.ctx, r.sys, r, r.wd, p)
npubdir := r.CreateNpubDir(r, p, nil)
return npubdir, fs.OK
case nostr.EventPointer:
eventdir, err := FetchAndCreateEventDir(r.ctx, r, r.wd, r.sys, p)
eventdir, err := r.FetchAndCreateEventDir(r, p)
if err != nil {
return nil, syscall.ENOENT
}

@@ -8,19 +8,16 @@ import (
"github.com/hanwen/go-fuse/v2/fs"
"github.com/hanwen/go-fuse/v2/fuse"
"github.com/nbd-wtf/go-nostr"
sdk "github.com/nbd-wtf/go-nostr/sdk"
)
type ViewDir struct {
fs.Inode
ctx context.Context
sys *sdk.System
wd string
root *NostrRoot
fetched atomic.Bool
filter nostr.Filter
paginate bool
relays []string
create func(context.Context, *ViewDir, *nostr.Event) (string, *fs.Inode)
create func(*ViewDir, *nostr.Event) (string, *fs.Inode)
}
var (
@@ -52,8 +49,8 @@ func (n *ViewDir) Opendir(_ context.Context) syscall.Errno {
aMonthAgo := now - 30*24*60*60
n.filter.Since = &aMonthAgo
for ie := range n.sys.Pool.FetchMany(n.ctx, n.relays, n.filter, nostr.WithLabel("nakfs")) {
basename, inode := n.create(n.ctx, n, ie.Event)
for ie := range n.root.sys.Pool.FetchMany(n.root.ctx, n.relays, n.filter, nostr.WithLabel("nakfs")) {
basename, inode := n.create(n, ie.Event)
n.AddChild(basename, inode, true)
}
@@ -61,19 +58,17 @@ func (n *ViewDir) Opendir(_ context.Context) syscall.Errno {
filter.Until = &aMonthAgo
n.AddChild("@previous", n.NewPersistentInode(
n.ctx,
n.root.ctx,
&ViewDir{
ctx: n.ctx,
sys: n.sys,
root: n.root,
filter: filter,
wd: n.wd,
relays: n.relays,
},
fs.StableAttr{Mode: syscall.S_IFDIR},
), true)
} else {
for ie := range n.sys.Pool.FetchMany(n.ctx, n.relays, n.filter, nostr.WithLabel("nakfs")) {
basename, inode := n.create(n.ctx, n, ie.Event)
for ie := range n.root.sys.Pool.FetchMany(n.root.ctx, n.relays, n.filter, nostr.WithLabel("nakfs")) {
basename, inode := n.create(n, ie.Event)
n.AddChild(basename, inode, true)
}
}