mirror of
https://github.com/fiatjaf/nak.git
synced 2025-05-01 04:19:56 -04:00
132 lines
2.7 KiB
Go
132 lines
2.7 KiB
Go
package nostrfs
|
|
|
|
import (
|
|
"context"
|
|
"path/filepath"
|
|
"syscall"
|
|
"time"
|
|
|
|
"github.com/hanwen/go-fuse/v2/fs"
|
|
"github.com/hanwen/go-fuse/v2/fuse"
|
|
"github.com/nbd-wtf/go-nostr"
|
|
"github.com/nbd-wtf/go-nostr/nip05"
|
|
"github.com/nbd-wtf/go-nostr/nip19"
|
|
"github.com/nbd-wtf/go-nostr/sdk"
|
|
)
|
|
|
|
type Options struct {
|
|
AutoPublishNotesTimeout time.Duration
|
|
AutoPublishArticlesTimeout time.Duration
|
|
}
|
|
|
|
type NostrRoot struct {
|
|
fs.Inode
|
|
|
|
ctx context.Context
|
|
wd string
|
|
sys *sdk.System
|
|
rootPubKey string
|
|
signer nostr.Signer
|
|
|
|
opts Options
|
|
}
|
|
|
|
var _ = (fs.NodeOnAdder)((*NostrRoot)(nil))
|
|
|
|
func NewNostrRoot(ctx context.Context, sys *sdk.System, user nostr.User, mountpoint string, o Options) *NostrRoot {
|
|
pubkey, _ := user.GetPublicKey(ctx)
|
|
abs, _ := filepath.Abs(mountpoint)
|
|
|
|
var signer nostr.Signer
|
|
if user != nil {
|
|
signer, _ = user.(nostr.Signer)
|
|
}
|
|
|
|
return &NostrRoot{
|
|
ctx: ctx,
|
|
sys: sys,
|
|
rootPubKey: pubkey,
|
|
signer: signer,
|
|
wd: abs,
|
|
|
|
opts: o,
|
|
}
|
|
}
|
|
|
|
func (r *NostrRoot) OnAdd(_ context.Context) {
|
|
if r.rootPubKey == "" {
|
|
return
|
|
}
|
|
|
|
go func() {
|
|
time.Sleep(time.Millisecond * 100)
|
|
|
|
// add our contacts
|
|
fl := r.sys.FetchFollowList(r.ctx, r.rootPubKey)
|
|
for _, f := range fl.Items {
|
|
pointer := nostr.ProfilePointer{PublicKey: f.Pubkey, Relays: []string{f.Relay}}
|
|
npub, _ := nip19.EncodePublicKey(f.Pubkey)
|
|
r.AddChild(
|
|
npub,
|
|
r.CreateNpubDir(r, pointer, nil),
|
|
true,
|
|
)
|
|
}
|
|
|
|
// add ourselves
|
|
npub, _ := nip19.EncodePublicKey(r.rootPubKey)
|
|
if r.GetChild(npub) == nil {
|
|
pointer := nostr.ProfilePointer{PublicKey: r.rootPubKey}
|
|
|
|
r.AddChild(
|
|
npub,
|
|
r.CreateNpubDir(r, pointer, r.signer),
|
|
true,
|
|
)
|
|
}
|
|
|
|
// add a link to ourselves
|
|
r.AddChild("@me", r.NewPersistentInode(
|
|
r.ctx,
|
|
&fs.MemSymlink{Data: []byte(r.wd + "/" + npub)},
|
|
fs.StableAttr{Mode: syscall.S_IFLNK},
|
|
), true)
|
|
}()
|
|
}
|
|
|
|
func (r *NostrRoot) Lookup(_ context.Context, name string, out *fuse.EntryOut) (*fs.Inode, syscall.Errno) {
|
|
out.SetEntryTimeout(time.Minute * 5)
|
|
|
|
child := r.GetChild(name)
|
|
if child != nil {
|
|
return child, fs.OK
|
|
}
|
|
|
|
if pp, err := nip05.QueryIdentifier(r.ctx, name); err == nil {
|
|
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)
|
|
if err != nil {
|
|
return nil, syscall.ENOENT
|
|
}
|
|
|
|
switch p := pointer.(type) {
|
|
case nostr.ProfilePointer:
|
|
npubdir := r.CreateNpubDir(r, p, nil)
|
|
return npubdir, fs.OK
|
|
case nostr.EventPointer:
|
|
eventdir, err := r.FetchAndCreateEventDir(r, p)
|
|
if err != nil {
|
|
return nil, syscall.ENOENT
|
|
}
|
|
return eventdir, fs.OK
|
|
default:
|
|
return nil, syscall.ENOENT
|
|
}
|
|
}
|