diff --git a/nip31/nip31.go b/nip31/nip31.go new file mode 100644 index 0000000..b508340 --- /dev/null +++ b/nip31/nip31.go @@ -0,0 +1,12 @@ +package nip31 + +import "github.com/nbd-wtf/go-nostr" + +func GetAlt(event nostr.Event) string { + for _, tag := range event.Tags { + if len(tag) >= 2 && tag[0] == "alt" { + return tag[1] + } + } + return "" +} diff --git a/nip52/calendar_event.go b/nip52/calendar_event.go new file mode 100644 index 0000000..de07e0a --- /dev/null +++ b/nip52/calendar_event.go @@ -0,0 +1,130 @@ +package nip52 + +import ( + "strconv" + "time" + + "github.com/nbd-wtf/go-nostr" +) + +type CalendarEventKind int + +const ( + TimeBased = 31923 + DateBased = 31922 +) + +type CalendarEvent struct { + CalendarEventKind + Identifier string + Title string + Start, End time.Time + Locations []string + Geohashes []string + Participants []Participant + References []string + Hashtags []string +} + +type Participant struct { + PubKey string + Relay string + Role string +} + +func ParseCalendarEvent(event nostr.Event) CalendarEvent { + calev := CalendarEvent{ + CalendarEventKind: CalendarEventKind(event.Kind), + } + for _, tag := range event.Tags { + if len(tag) < 2 { + continue + } + switch tag[0] { + case "d": + calev.Identifier = tag[1] + case "title": + calev.Title = tag[1] + case "start", "end": + var v time.Time + switch calev.CalendarEventKind { + case TimeBased: + i, err := strconv.ParseInt(tag[1], 10, 64) + if err != nil { + continue + } + v = time.Unix(i, 0) + case DateBased: + var err error + v, err = time.Parse(DateFormat, tag[1]) + if err != nil { + continue + } + } + switch tag[0] { + case "start": + calev.Start = v + case "end": + calev.End = v + } + case "location": + calev.Locations = append(calev.Locations, tag[1]) + case "g": + calev.Geohashes = append(calev.Geohashes, tag[1]) + case "p": + if nostr.IsValidPublicKeyHex(tag[1]) { + part := Participant{ + PubKey: tag[1], + } + if len(tag) > 2 { + part.Relay = tag[2] + if len(tag) > 3 { + part.Role = tag[3] + } + } + calev.Participants = append(calev.Participants, part) + } + case "r": + calev.References = append(calev.References, tag[1]) + case "t": + calev.Hashtags = append(calev.Hashtags, tag[1]) + } + } + return calev +} + +func (calev CalendarEvent) ToHashtags() nostr.Tags { + tags := make(nostr.Tags, 0, 12) + tags = append(tags, nostr.Tag{"d", calev.Identifier}) + tags = append(tags, nostr.Tag{"title", calev.Title}) + + if calev.CalendarEventKind == TimeBased { + tags = append(tags, nostr.Tag{"start", strconv.FormatInt(calev.Start.Unix(), 10)}) + if !calev.End.IsZero() { + tags = append(tags, nostr.Tag{"end", strconv.FormatInt(calev.End.Unix(), 10)}) + } + } else if calev.CalendarEventKind == DateBased { + tags = append(tags, nostr.Tag{"start", calev.Start.Format(DateFormat)}) + if !calev.End.IsZero() { + tags = append(tags, nostr.Tag{"end", calev.End.Format(DateFormat)}) + } + } + + for _, location := range calev.Locations { + tags = append(tags, nostr.Tag{"location", location}) + } + for _, geohash := range calev.Geohashes { + tags = append(tags, nostr.Tag{"g", geohash}) + } + for _, part := range calev.Participants { + tags = append(tags, nostr.Tag{"p", part.PubKey, part.Relay, part.Role}) + } + for _, reference := range calev.References { + tags = append(tags, nostr.Tag{"r", reference}) + } + for _, hashtag := range calev.Hashtags { + tags = append(tags, nostr.Tag{"t", hashtag}) + } + + return tags +} diff --git a/nip52/nip52.go b/nip52/nip52.go new file mode 100644 index 0000000..ca43c63 --- /dev/null +++ b/nip52/nip52.go @@ -0,0 +1,3 @@ +package nip52 + +const DateFormat = "2006-01-02" diff --git a/nip94/nip94.go b/nip94/nip94.go new file mode 100644 index 0000000..15ef6a3 --- /dev/null +++ b/nip94/nip94.go @@ -0,0 +1,107 @@ +package nip94 + +import ( + "strings" + + "github.com/nbd-wtf/go-nostr" +) + +func ParseFileMetadata(event nostr.Event) FileMetadata { + fm := FileMetadata{} + for _, tag := range event.Tags { + if len(tag) < 2 { + continue + } + switch tag[0] { + case "url": + fm.URL = tag[1] + case "x": + fm.X = tag[1] + case "ox": + fm.OX = tag[1] + case "size": + fm.Size = tag[1] + case "dim": + fm.Dim = tag[1] + case "magnet": + fm.Magnet = tag[1] + case "i": + fm.TorrentInfoHash = tag[1] + case "blurhash": + fm.Blurhash = tag[1] + case "thumb": + fm.Image = tag[1] + case "summary": + fm.Summary = tag[1] + } + } + return fm +} + +type FileMetadata struct { + Magnet string + Dim string + Size string + Summary string + Image string + URL string + M string + X string + OX string + TorrentInfoHash string + Blurhash string + Thumb string +} + +func (fm FileMetadata) IsVideo() bool { return strings.Split(fm.M, "/")[0] == "video" } +func (fm FileMetadata) IsImage() bool { return strings.Split(fm.M, "/")[0] == "image" } +func (fm FileMetadata) DisplayImage() string { + if fm.Image != "" { + return fm.Image + } else if fm.IsImage() { + return fm.URL + } else { + return "" + } +} + +func (fm FileMetadata) ToTags() nostr.Tags { + tags := make(nostr.Tags, 0, 12) + if fm.URL != "" { + tags = append(tags, nostr.Tag{"url", fm.URL}) + } + if fm.M != "" { + tags = append(tags, nostr.Tag{"m", fm.M}) + } + if fm.X != "" { + tags = append(tags, nostr.Tag{"x", fm.X}) + } + if fm.OX != "" { + tags = append(tags, nostr.Tag{"ox", fm.OX}) + } + if fm.Size != "" { + tags = append(tags, nostr.Tag{"size", fm.Size}) + } + if fm.Dim != "" { + tags = append(tags, nostr.Tag{"dim", fm.Dim}) + } + if fm.Magnet != "" { + tags = append(tags, nostr.Tag{"magnet", fm.Magnet}) + } + if fm.TorrentInfoHash != "" { + tags = append(tags, nostr.Tag{"i", fm.TorrentInfoHash}) + } + if fm.Blurhash != "" { + tags = append(tags, nostr.Tag{"blurhash", fm.Blurhash}) + } + if fm.Thumb != "" { + tags = append(tags, nostr.Tag{"thumb", fm.Thumb}) + } + if fm.Image != "" { + tags = append(tags, nostr.Tag{"image", fm.Image}) + } + if fm.Summary != "" { + tags = append(tags, nostr.Tag{"summary", fm.Summary}) + } + return tags +}