go-nostr/nip52/calendar_event.go
2024-05-14 23:55:21 -03:00

143 lines
3.2 KiB
Go

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
Image string
Start, End time.Time
Locations []string
Geohashes []string
Participants []Participant
References []string
Hashtags []string
StartTzid string
EndTzid 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 "image":
calev.Image = 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.IsValid32ByteHex(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])
case "start_tzid":
calev.StartTzid = tag[1]
case "end_tzid":
calev.EndTzid = tag[1]
}
}
return calev
}
func (calev CalendarEvent) ToHashtags() nostr.Tags {
tags := make(nostr.Tags, 0, 26)
tags = append(tags, nostr.Tag{"d", calev.Identifier})
tags = append(tags, nostr.Tag{"title", calev.Title})
if calev.Image != "" {
tags = append(tags, nostr.Tag{"image", 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
}