diff options
Diffstat (limited to 'notes/note.go')
| -rw-r--r-- | notes/note.go | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/notes/note.go b/notes/note.go new file mode 100644 index 0000000..15f6f67 --- /dev/null +++ b/notes/note.go @@ -0,0 +1,80 @@ +package notes + +import ( + "time" +) + +type Media struct { + URL string `json:"url"` + Alt string `json:"alt"` + Width int `json:"width,omitempty"` + Height int `json:"height,omitempty"` +} + +type Note struct { + URI string `json:"uri"` + AuthorDID string `json:"authorDID"` + AuthorHandle string `json:"authorHandle"` + AuthorName string `json:"authorName"` + AuthorNoUnauth bool `json:"authorNoUnauth"` // author has !no-unauthenticated label + AvatarURL string `json:"avatarURL"` + Text string `json:"text"` + CreatedAt time.Time `json:"createdAt"` + ReplyTo *string `json:"replyTo,omitempty"` + Facets []Facet `json:"facets,omitempty"` + Parents []Note `json:"parents,omitempty"` + Media []Media `json:"media,omitempty"` +} + +type Facet struct { + ByteStart int `json:"byteStart"` + ByteEnd int `json:"byteEnd"` + Type string `json:"type"` + Value string `json:"value"` // the link destination, whether url, profile or tag +} + +func MissingNote(uri string) *Note { + return &Note{ + URI: uri, + AuthorDID: "MISSING", + Text: "This post could not be fetched. It may have been deleted.", + CreatedAt: time.Time{}, + } +} + +func isChainContained(smallChainPost, bigChainPost Note) bool { + if len(smallChainPost.Parents) > len(bigChainPost.Parents) { + return false + } + + // if the thread is going to differ at any post, it's going to be at the end + // thus if the posts match their parents MUST match too + // (not that I expect to ever compare a post to itself but this way it won't break if I do. And technically a thread contains itself) + if len(smallChainPost.Parents) == len(bigChainPost.Parents) { + return smallChainPost.URI == bigChainPost.URI + } + + // check if the last post of the smaller chain is the (n+1)-th post of the bigger chain + // where n is the number of parents in the smaller reply chain + offset := len(bigChainPost.Parents) - len(smallChainPost.Parents) + return smallChainPost.URI == bigChainPost.Parents[offset-1].URI +} + +func DeduplicateThreads(posts []Note) []Note { + filtered := []Note{} + for _, post := range posts { + isRedundant := false + for _, kept := range filtered { + // check if this post's chain is contained in any kept post + if isChainContained(post, kept) { + isRedundant = true + break + } + } + if !isRedundant { + filtered = append(filtered, post) + } + } + + return filtered +} |
