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.IsValid32ByteHex(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 }