diff --git a/nip53/nip53.go b/nip53/nip53.go new file mode 100644 index 0000000..ceb1b3d --- /dev/null +++ b/nip53/nip53.go @@ -0,0 +1,137 @@ +package nip53 + +import ( + "strconv" + "time" + + "github.com/nbd-wtf/go-nostr" +) + +type LiveEvent struct { + Identifier string + Title string + Summary string + Image string + Status string + CurrentParticipants int + TotalParticipants int + Streaming []string + Recording []string + Starts, Ends time.Time + Participants []Participant + Hashtags []string + Relays []string +} + +type Participant struct { + PubKey string + Relay string + Role string +} + +func ParseLiveEvent(event nostr.Event) LiveEvent { + liev := LiveEvent{} + for _, tag := range event.Tags { + if len(tag) < 2 { + continue + } + switch tag[0] { + case "d": + liev.Identifier = tag[1] + case "title": + liev.Title = tag[1] + case "summary": + liev.Summary = tag[1] + case "image": + liev.Image = tag[1] + case "status": + liev.Status = tag[1] + case "starts", "ends": + var v time.Time + i, err := strconv.ParseInt(tag[1], 10, 64) + if err != nil { + continue + } + v = time.Unix(i, 0) + switch tag[0] { + case "start": + liev.Starts = v + case "end": + liev.Ends = v + } + case "streaming": + liev.Streaming = append(liev.Streaming, tag[1]) + case "recording": + liev.Recording = append(liev.Recording, 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] + } + } + liev.Participants = append(liev.Participants, part) + } + case "relays": + liev.Relays = append(liev.Relays, tag[1]) + case "t": + liev.Hashtags = append(liev.Hashtags, tag[1]) + case "current_participants": + liev.CurrentParticipants, _ = strconv.Atoi(tag[1]) + case "total_participants": + liev.TotalParticipants, _ = strconv.Atoi(tag[1]) + } + } + return liev +} + +func (liev LiveEvent) GetHost() *Participant { + for _, part := range liev.Participants { + if part.Role == "host" { + return &part + } + } + return nil +} + +func (liev LiveEvent) ToHashtags() nostr.Tags { + tags := make(nostr.Tags, 0, 26) + tags = append(tags, nostr.Tag{"d", liev.Identifier}) + tags = append(tags, nostr.Tag{"title", liev.Title}) + if liev.Image != "" { + tags = append(tags, nostr.Tag{"image", liev.Title}) + } + + tags = append(tags, nostr.Tag{"start", strconv.FormatInt(liev.Starts.Unix(), 10)}) + if !liev.Ends.IsZero() { + tags = append(tags, nostr.Tag{"end", strconv.FormatInt(liev.Ends.Unix(), 10)}) + } + + for _, url := range liev.Streaming { + tags = append(tags, nostr.Tag{"streaming", url}) + } + for _, url := range liev.Recording { + tags = append(tags, nostr.Tag{"recording", url}) + } + for _, part := range liev.Participants { + tags = append(tags, nostr.Tag{"p", part.PubKey, part.Relay, part.Role}) + } + for _, hashtag := range liev.Hashtags { + tags = append(tags, nostr.Tag{"t", hashtag}) + } + if liev.CurrentParticipants != 0 { + tags = append(tags, nostr.Tag{"current_participants", strconv.Itoa(liev.CurrentParticipants)}) + } + if liev.TotalParticipants != 0 { + tags = append(tags, nostr.Tag{"total_participants", strconv.Itoa(liev.TotalParticipants)}) + } + for _, r := range liev.Relays { + tags = append(tags, nostr.Tag{"relay", r}) + } + + return tags +}