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:
13
fs.go
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)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user