mirror of
https://github.com/nbd-wtf/go-nostr.git
synced 2025-08-23 20:22:06 +02:00
nip29: some more group helpers.
This commit is contained in:
@@ -2,12 +2,37 @@ package nip29
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/nbd-wtf/go-nostr"
|
"github.com/nbd-wtf/go-nostr"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type GroupAddress struct {
|
||||||
|
Relay string
|
||||||
|
ID string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gid GroupAddress) String() string { return fmt.Sprintf("%s'%s", gid.ID, gid.Relay) }
|
||||||
|
|
||||||
|
func (gid GroupAddress) IsValid() bool {
|
||||||
|
return gid.Relay != "" && gid.ID != ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gid GroupAddress) Equals(gid2 GroupAddress) bool {
|
||||||
|
return gid.Relay == gid2.Relay && gid.ID == gid2.ID
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseGroupAddress(raw string) (GroupAddress, error) {
|
||||||
|
spl := strings.Split(raw, "'")
|
||||||
|
if len(spl) != 2 {
|
||||||
|
return GroupAddress{}, fmt.Errorf("invalid group id")
|
||||||
|
}
|
||||||
|
return GroupAddress{ID: spl[0], Relay: nostr.NormalizeURL(spl[1])}, nil
|
||||||
|
}
|
||||||
|
|
||||||
type Group struct {
|
type Group struct {
|
||||||
ID string
|
Address GroupAddress
|
||||||
|
|
||||||
Name string
|
Name string
|
||||||
Picture string
|
Picture string
|
||||||
About string
|
About string
|
||||||
@@ -20,12 +45,17 @@ type Group struct {
|
|||||||
LastMembersUpdate nostr.Timestamp
|
LastMembersUpdate nostr.Timestamp
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGroup(id string) Group {
|
func NewGroup(id string) (Group, error) {
|
||||||
return Group{
|
gad, err := ParseGroupAddress(id)
|
||||||
ID: id,
|
if err != nil {
|
||||||
Name: id,
|
return Group{}, fmt.Errorf("invalid group id '%s': %w", id, err)
|
||||||
Members: make(map[string]*Role),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return Group{
|
||||||
|
Address: gad,
|
||||||
|
Name: gad.ID,
|
||||||
|
Members: make(map[string]*Role),
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (group Group) ToMetadataEvent() *nostr.Event {
|
func (group Group) ToMetadataEvent() *nostr.Event {
|
||||||
@@ -34,7 +64,7 @@ func (group Group) ToMetadataEvent() *nostr.Event {
|
|||||||
CreatedAt: group.LastMetadataUpdate,
|
CreatedAt: group.LastMetadataUpdate,
|
||||||
Content: group.About,
|
Content: group.About,
|
||||||
Tags: nostr.Tags{
|
Tags: nostr.Tags{
|
||||||
nostr.Tag{"d", group.ID},
|
nostr.Tag{"d", group.Address.ID},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if group.Name != "" {
|
if group.Name != "" {
|
||||||
@@ -68,7 +98,7 @@ func (group Group) ToAdminsEvent() *nostr.Event {
|
|||||||
CreatedAt: group.LastAdminsUpdate,
|
CreatedAt: group.LastAdminsUpdate,
|
||||||
Tags: make(nostr.Tags, 1, 1+len(group.Members)/3),
|
Tags: make(nostr.Tags, 1, 1+len(group.Members)/3),
|
||||||
}
|
}
|
||||||
evt.Tags[0] = nostr.Tag{"d", group.ID}
|
evt.Tags[0] = nostr.Tag{"d", group.Address.ID}
|
||||||
|
|
||||||
for member, role := range group.Members {
|
for member, role := range group.Members {
|
||||||
if role != nil {
|
if role != nil {
|
||||||
@@ -93,7 +123,7 @@ func (group Group) ToMembersEvent() *nostr.Event {
|
|||||||
CreatedAt: group.LastMembersUpdate,
|
CreatedAt: group.LastMembersUpdate,
|
||||||
Tags: make(nostr.Tags, 1, 1+len(group.Members)),
|
Tags: make(nostr.Tags, 1, 1+len(group.Members)),
|
||||||
}
|
}
|
||||||
evt.Tags[0] = nostr.Tag{"d", group.ID}
|
evt.Tags[0] = nostr.Tag{"d", group.Address.ID}
|
||||||
|
|
||||||
for member := range group.Members {
|
for member := range group.Members {
|
||||||
// include both admins and normal members
|
// include both admins and normal members
|
||||||
@@ -112,7 +142,7 @@ func (group *Group) MergeInMetadataEvent(evt *nostr.Event) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
group.LastMetadataUpdate = evt.CreatedAt
|
group.LastMetadataUpdate = evt.CreatedAt
|
||||||
group.Name = group.ID
|
group.Name = group.Address.ID
|
||||||
|
|
||||||
if tag := evt.Tags.GetFirst([]string{"name", ""}); tag != nil {
|
if tag := evt.Tags.GetFirst([]string{"name", ""}); tag != nil {
|
||||||
group.Name = (*tag)[1]
|
group.Name = (*tag)[1]
|
||||||
|
@@ -12,7 +12,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestGroupEventBackAndForth(t *testing.T) {
|
func TestGroupEventBackAndForth(t *testing.T) {
|
||||||
group1 := NewGroup("xyz")
|
group1, _ := NewGroup("xyz")
|
||||||
group1.Name = "banana"
|
group1.Name = "banana"
|
||||||
group1.Private = true
|
group1.Private = true
|
||||||
meta1 := group1.ToMetadataEvent()
|
meta1 := group1.ToMetadataEvent()
|
||||||
@@ -22,7 +22,7 @@ func TestGroupEventBackAndForth(t *testing.T) {
|
|||||||
t.Fatalf("translation of group1 to meta1data event failed")
|
t.Fatalf("translation of group1 to meta1data event failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
group2 := NewGroup("abc")
|
group2, _ := NewGroup("abc")
|
||||||
group2.Members[ALICE] = &Role{Name: "nada", Permissions: map[Permission]struct{}{PermAddUser: {}}}
|
group2.Members[ALICE] = &Role{Name: "nada", Permissions: map[Permission]struct{}{PermAddUser: {}}}
|
||||||
group2.Members[BOB] = &Role{Name: "nada", Permissions: map[Permission]struct{}{PermEditMetadata: {}}}
|
group2.Members[BOB] = &Role{Name: "nada", Permissions: map[Permission]struct{}{PermEditMetadata: {}}}
|
||||||
group2.Members[CAROL] = EmptyRole
|
group2.Members[CAROL] = EmptyRole
|
||||||
@@ -55,7 +55,7 @@ func TestGroupEventBackAndForth(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
group2.MergeInMetadataEvent(meta1)
|
group2.MergeInMetadataEvent(meta1)
|
||||||
if group2.Name != "banana" || group2.ID != "abc" {
|
if group2.Name != "banana" || group2.Address.ID != "abc" {
|
||||||
t.Fatalf("merge of meta1 into group2 failed")
|
t.Fatalf("merge of meta1 into group2 failed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user