Files
njump/data.go
dtonon 4cb5d6f5c7 Add basic wiki articles rendering
Wikilinks are broken
2024-07-25 15:21:34 +02:00

198 lines
5.8 KiB
Go

package main
import (
"context"
"fmt"
"html/template"
"strings"
"time"
"github.com/nbd-wtf/go-nostr/nip19"
"github.com/nbd-wtf/go-nostr/nip31"
"github.com/nbd-wtf/go-nostr/nip52"
"github.com/nbd-wtf/go-nostr/nip53"
"github.com/nbd-wtf/go-nostr/nip94"
)
type Data struct {
templateId TemplateID
event EnhancedEvent
nprofile string
nevent string
neventNaked string
naddr string
naddrNaked string
createdAt string
modifiedAt string
parentLink template.HTML
authorRelaysPretty []string
renderableLastNotes []EnhancedEvent
kindDescription string
kindNIP string
video string
videoType string
image string
cover string
content string
alt string
kind1063Metadata *Kind1063Metadata
kind30311Metadata *Kind30311Metadata
kind31922Or31923Metadata *Kind31922Or31923Metadata
Kind30818Metadata Kind30818Metadata
}
func grabData(ctx context.Context, code string, isProfileSitemap bool) (*Data, error) {
// code can be a nevent, nprofile, npub or nip05 identifier, in which case we try to fetch the associated event
event, relays, err := getEvent(ctx, code, nil)
if err != nil {
log.Warn().Err(err).Str("code", code).Msg("failed to fetch event for code")
return nil, fmt.Errorf("error fetching event: %w", err)
}
relaysForNip19 := make([]string, 0, 3)
c := 0
for _, relayUrl := range relays {
if isntRealRelay(relayUrl) {
continue
}
relaysForNip19 = append(relaysForNip19, relayUrl)
if c == 2 {
break
}
}
data := &Data{
event: NewEnhancedEvent(ctx, event, relays),
}
data.authorRelaysPretty = make([]string, 0, len(relays))
for _, url := range relaysForPubkey(ctx, event.PubKey) {
if isntRealRelay(url) {
continue
}
for _, excluded := range relayConfig.ExcludedRelays {
if strings.Contains(url, excluded) {
continue
}
}
data.authorRelaysPretty = append(data.authorRelaysPretty, trimProtocol(url))
}
data.authorRelaysPretty = unique(data.authorRelaysPretty)
data.nevent, _ = nip19.EncodeEvent(event.ID, relaysForNip19, event.PubKey)
data.neventNaked, _ = nip19.EncodeEvent(event.ID, nil, event.PubKey)
data.naddr = ""
data.naddrNaked = ""
data.createdAt = time.Unix(int64(event.CreatedAt), 0).Format("2006-01-02 15:04:05")
data.modifiedAt = time.Unix(int64(event.CreatedAt), 0).Format("2006-01-02T15:04:05Z07:00")
if event.Kind >= 30000 && event.Kind < 40000 {
if d := event.Tags.GetFirst([]string{"d", ""}); d != nil {
data.naddr, _ = nip19.EncodeEntity(event.PubKey, event.Kind, d.Value(), relaysForNip19)
data.naddrNaked, _ = nip19.EncodeEntity(event.PubKey, event.Kind, d.Value(), nil)
}
}
data.alt = nip31.GetAlt(*event)
switch event.Kind {
case 0:
data.templateId = Profile
lastNotes := authorLastNotes(ctx, event.PubKey, isProfileSitemap)
data.renderableLastNotes = make([]EnhancedEvent, len(lastNotes))
for i, levt := range lastNotes {
data.renderableLastNotes[i] = NewEnhancedEvent(ctx, levt, []string{})
}
if err != nil {
return nil, err
}
case 1, 7, 30023, 30024:
data.templateId = Note
data.content = event.Content
case 6:
data.templateId = Note
if reposted := event.Tags.GetFirst([]string{"e", ""}); reposted != nil {
originalNevent, _ := nip19.EncodeEvent((*reposted)[1], []string{}, "")
data.content = "Repost of nostr:" + originalNevent
}
case 1063:
data.templateId = FileMetadata
data.kind1063Metadata = &Kind1063Metadata{nip94.ParseFileMetadata(*event)}
case 30311:
data.templateId = LiveEvent
data.kind30311Metadata = &Kind30311Metadata{LiveEvent: nip53.ParseLiveEvent(*event)}
host := data.kind30311Metadata.GetHost()
if host != nil {
hostProfile := sys.FetchProfileMetadata(ctx, host.PubKey)
data.kind30311Metadata.Host = &hostProfile
}
case 1311:
data.templateId = LiveEventMessage
data.content = event.Content
case 31922, 31923:
data.templateId = CalendarEvent
data.kind31922Or31923Metadata = &Kind31922Or31923Metadata{CalendarEvent: nip52.ParseCalendarEvent(*event)}
data.content = event.Content
case 30818:
data.templateId = WikiEvent
data.Kind30818Metadata.Handle = event.Tags.GetFirst([]string{"d"}).Value()
data.Kind30818Metadata.Title = event.Tags.GetFirst([]string{"title"}).Value()
data.Kind30818Metadata.Summary = func() string {
if tag := event.Tags.GetFirst([]string{"summary"}); tag != nil {
value := tag.Value()
return value
}
return ""
}()
data.content = event.Content
default:
data.templateId = Other
}
data.nprofile, _ = nip19.EncodeProfile(event.PubKey, limitAt(relays, 2))
data.kindDescription = kindNames[event.Kind]
if data.kindDescription == "" {
data.kindDescription = fmt.Sprintf("Kind %d", event.Kind)
}
data.kindNIP = kindNIPs[event.Kind]
image := event.Tags.GetFirst([]string{"image", ""})
if event.Kind == 30023 && image != nil {
data.cover = (*image)[1]
}
if event.Kind == 1063 {
if data.kind1063Metadata.IsImage() {
data.image = data.kind1063Metadata.URL
} else if data.kind1063Metadata.IsVideo() {
data.video = data.kind1063Metadata.URL
data.videoType = strings.Split(data.kind1063Metadata.M, "/")[1]
}
} else {
urls := urlMatcher.FindAllString(event.Content, -1)
for _, url := range urls {
switch {
case imageExtensionMatcher.MatchString(url):
if data.image == "" {
data.image = url
}
case videoExtensionMatcher.MatchString(url):
if data.video == "" {
data.video = url
if strings.HasSuffix(data.video, "mp4") {
data.videoType = "mp4"
} else if strings.HasSuffix(data.video, "mov") {
data.videoType = "mov"
} else {
data.videoType = "webm"
}
}
}
}
}
return data, nil
}