1
0
mirror of https://github.com/mrusme/neonmodem.git synced 2025-02-02 15:07:59 -05:00
2024-08-22 13:06:58 -05:00

285 lines
5.6 KiB
Go

package nostr
import (
"context"
"fmt"
"net/url"
"time"
"github.com/mrusme/neonmodem/models/forum"
"github.com/mrusme/neonmodem/models/post"
"github.com/mrusme/neonmodem/models/reply"
"github.com/mrusme/neonmodem/system/adapter"
"github.com/mrusme/neonmodem/system/nostr/nip51"
"github.com/nbd-wtf/go-nostr"
"github.com/nbd-wtf/go-nostr/nip19"
"go.uber.org/zap"
)
type System struct {
ID int
config map[string]interface{}
logger *zap.SugaredLogger
client *nostr.Relay
clientCtx context.Context
clientCcl context.CancelFunc
relayURL string
privateKey string
publicKey string
}
func (sys *System) GetID() int {
return sys.ID
}
func (sys *System) SetID(id int) {
sys.ID = id
}
func (sys *System) GetConfig() map[string]interface{} {
return sys.config
}
func (sys *System) SetConfig(cfg *map[string]interface{}) {
sys.config = *cfg
}
func (sys *System) SetLogger(logger *zap.SugaredLogger) {
sys.logger = logger
}
func (sys *System) GetCapabilities() adapter.Capabilities {
var caps []adapter.Capability
caps = append(caps,
// TODO
// adapter.Capability{
// ID: "connect:multiple",
// Name: "Connect Multiple",
// },
adapter.Capability{
ID: "list:forums",
Name: "List Forums",
},
adapter.Capability{
ID: "list:posts",
Name: "List Posts",
},
// TODO
// adapter.Capability{
// ID: "create:post",
// Name: "Create Post",
// },
adapter.Capability{
ID: "list:replies",
Name: "List Replies",
},
// TODO
// adapter.Capability{
// ID: "create:reply",
// Name: "Create Reply",
// },
)
return caps
}
func (sys *System) FilterValue() string {
return fmt.Sprintf(
"Nostr %s",
sys.config["url"],
)
}
func (sys *System) Title() string {
sysUrl := sys.config["url"].(string)
u, err := url.Parse(sysUrl)
if err != nil {
return sysUrl
}
return u.Hostname()
}
func (sys *System) Description() string {
return fmt.Sprintf(
"Nostr",
)
}
func (sys *System) Load() error {
var err error
url := sys.config["url"]
if url == nil {
return nil
}
sys.relayURL = url.(string)
credentials := make(map[string]string)
for k, v := range (sys.config["credentials"]).(map[string]interface{}) {
credentials[k] = v.(string)
}
_, pk, err := nip19.Decode(credentials["pk"])
sys.privateKey = pk.(string)
if sys.publicKey, err = nostr.GetPublicKey(sys.privateKey); err != nil {
sys.logger.Debugln("Nostr GetPublicKey error")
return err
}
sys.clientCtx, sys.clientCcl = context.WithCancel(context.Background())
if sys.client, err = nostr.RelayConnect(sys.clientCtx, sys.relayURL); err != nil {
sys.logger.Debugln("Nostr RelayConnect error")
return err
}
return nil
}
func (sys *System) ListForums() ([]forum.Forum, error) {
var models []forum.Forum
var sub *nostr.Subscription
var err error
var filters nostr.Filters
filters = []nostr.Filter{{
Kinds: []int{nip51.Deprecated},
Authors: []string{sys.publicKey},
Limit: 1,
}}
sys.logger.Debugln("Nostr ListForums")
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
if sub, err = sys.client.Subscribe(ctx, filters); err != nil {
return models, err
}
for ev := range sub.Events {
sys.logger.Debugf("%v\n", ev)
le := nip51.ParseListEvent(*ev, sys.privateKey, sys.publicKey)
if le.Identifier == "communities" {
for _, co := range le.Communities {
models = append(models, forum.Forum{
ID: co.Identifier,
Name: "n/" + co.Identifier,
Info: co.PubKey,
SysIDX: sys.ID,
})
}
}
}
return models, nil
}
func (sys *System) ListPosts(forumID string) ([]post.Post, error) {
var models []post.Post
// var err error
// for _, i := range *items {
// createdAt, err := dateparse.ParseAny(i.CreatedAt)
// if err != nil {
// createdAt = time.Now() // TODO: Errrr
// }
//
// models = append(models, post.Post{
// ID: i.ShortID,
//
// Subject: i.Title,
//
// Type: "url",
//
// Pinned: false,
// Closed: false,
//
// CreatedAt: createdAt,
// LastCommentedAt: createdAt, // TODO
//
// Author: author.Author{
// ID: i.SubmitterUser.Username,
// Name: i.SubmitterUser.Username,
// },
//
// Forum: forum.Forum{
// ID: i.Tags[0],
// Name: i.Tags[0], // TODO: Tag description
//
// SysIDX: sys.ID,
// },
//
// // TODO: Implement chunks loading
// TotalReplies: 0,
// CurrentRepliesStartIDX: -1,
//
// URL: i.ShortIDURL,
//
// SysIDX: sys.ID,
// })
// }
//
return models, nil
}
func (sys *System) LoadPost(p *post.Post) error {
// item, err := sys.client.Stories.Show(context.Background(), p.ID)
// if err != nil {
// return err
// }
//
// converter := md.NewConverter("", true, nil)
//
p.Replies = []reply.Reply{}
// for idx, i := range item.Comments {
// cookedMd, err := converter.ConvertString(i.Comment)
// if err != nil {
// cookedMd = i.CommentPlain
// }
//
// if idx == 0 {
// p.Body = cookedMd
// continue
// }
//
// createdAt, err := dateparse.ParseAny(i.CreatedAt)
// if err != nil {
// createdAt = time.Now() // TODO: Errrrrr
// }
//
// inReplyTo := i.ParentComment
// if inReplyTo == "" {
// inReplyTo = p.ID
// }
// p.Replies = append(p.Replies, reply.Reply{
// ID: i.ShortID,
// InReplyTo: inReplyTo,
//
// Body: cookedMd,
//
// CreatedAt: createdAt,
//
// Author: author.Author{
// ID: i.CommentingUser.Username,
// Name: i.CommentingUser.Username,
// },
//
// SysIDX: sys.ID,
// })
// }
return nil
}
func (sys *System) CreatePost(p *post.Post) error {
return nil
}
func (sys *System) CreateReply(r *reply.Reply) error {
return nil
}