178 lines
3.9 KiB
Go
178 lines
3.9 KiB
Go
package mf
|
|
|
|
import (
|
|
"brainbaking.com/go-jamming/common"
|
|
"strings"
|
|
"time"
|
|
"willnorris.com/go/microformats"
|
|
)
|
|
|
|
const (
|
|
DateFormat = "2006-01-02T15:04:05"
|
|
)
|
|
|
|
type IndiewebAuthor struct {
|
|
Name string `json:"name"`
|
|
Picture string `json:"picture"`
|
|
}
|
|
|
|
type IndiewebDataResult struct {
|
|
Status string `json:"status"`
|
|
Data []*IndiewebData `json:"json"`
|
|
}
|
|
|
|
func ResultSuccess(data []*IndiewebData) IndiewebDataResult {
|
|
return IndiewebDataResult{
|
|
Status: "success",
|
|
Data: data,
|
|
}
|
|
}
|
|
|
|
type IndiewebData struct {
|
|
Author IndiewebAuthor `json:"author"`
|
|
Name string `json:"name"`
|
|
Content string `json:"content"`
|
|
Published string `json:"published"`
|
|
Url string `json:"url"`
|
|
IndiewebType MfType `json:"type"`
|
|
Source string `json:"source"`
|
|
Target string `json:"target"`
|
|
}
|
|
|
|
func (id *IndiewebData) AsMention() Mention {
|
|
return Mention{
|
|
Source: id.Source,
|
|
Target: id.Target,
|
|
}
|
|
}
|
|
|
|
func (id *IndiewebData) IsEmpty() bool {
|
|
return id.Url == ""
|
|
}
|
|
|
|
func PublishedNow(utcOffset int) string {
|
|
return common.Now().UTC().Add(time.Duration(utcOffset) * time.Minute).Format("2006-01-02T15:04:05")
|
|
}
|
|
|
|
func shorten(txt string) string {
|
|
if len(txt) <= 250 {
|
|
return txt
|
|
}
|
|
return txt[:250] + "..."
|
|
}
|
|
|
|
// Go stuff: entry.Properties["name"][0].(string),
|
|
// JS stuff: hEntry.properties?.name?.[0]
|
|
// The problem: convoluted syntax and no optional chaining!
|
|
func Str(mf *microformats.Microformat, key string) string {
|
|
val := mf.Properties[key]
|
|
if len(val) == 0 {
|
|
return ""
|
|
}
|
|
|
|
str, ok := val[0].(string)
|
|
if !ok {
|
|
// in very weird cases, it could be a map holding a value, like in mf2's "photo"
|
|
valMap, ok2 := val[0].(map[string]string)
|
|
if !ok2 {
|
|
str = ""
|
|
}
|
|
str = valMap["value"]
|
|
}
|
|
|
|
return str
|
|
}
|
|
|
|
func Map(mf *microformats.Microformat, key string) map[string]string {
|
|
val := mf.Properties[key]
|
|
if len(val) == 0 {
|
|
return map[string]string{}
|
|
}
|
|
mapVal, ok := val[0].(map[string]string)
|
|
if !ok {
|
|
return map[string]string{}
|
|
}
|
|
return mapVal
|
|
}
|
|
|
|
func HEntry(data *microformats.Data) *microformats.Microformat {
|
|
for _, itm := range data.Items {
|
|
if common.Includes(itm.Type, "h-entry") {
|
|
return itm
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func Prop(mf *microformats.Microformat, key string) *microformats.Microformat {
|
|
val := mf.Properties[key]
|
|
if len(val) == 0 {
|
|
return µformats.Microformat{
|
|
Properties: map[string][]interface{}{},
|
|
}
|
|
}
|
|
return val[0].(*microformats.Microformat)
|
|
}
|
|
|
|
func Published(hEntry *microformats.Microformat, utcOffset int) string {
|
|
publishedDate := Str(hEntry, "published")
|
|
if publishedDate == "" {
|
|
return PublishedNow(utcOffset)
|
|
}
|
|
return publishedDate
|
|
}
|
|
|
|
func DetermineAuthorName(hEntry *microformats.Microformat) string {
|
|
authorName := Str(Prop(hEntry, "author"), "name")
|
|
if authorName == "" {
|
|
return Prop(hEntry, "author").Value
|
|
}
|
|
return authorName
|
|
}
|
|
|
|
type MfType string
|
|
|
|
const (
|
|
TypeLike MfType = "like"
|
|
TypeBookmark MfType = "bookmark"
|
|
TypeMention MfType = "mention"
|
|
)
|
|
|
|
func Type(hEntry *microformats.Microformat) MfType {
|
|
likeOf := Str(hEntry, "like-of")
|
|
if likeOf != "" {
|
|
return TypeLike
|
|
}
|
|
bookmarkOf := Str(hEntry, "bookmark-of")
|
|
if bookmarkOf != "" {
|
|
return TypeBookmark
|
|
}
|
|
return TypeMention
|
|
}
|
|
|
|
// Mastodon uids start with "tag:server", but we do want indieweb uids from other sources
|
|
func Url(hEntry *microformats.Microformat, source string) string {
|
|
uid := Str(hEntry, "uid")
|
|
if uid != "" && strings.HasPrefix(uid, "http") {
|
|
return uid
|
|
}
|
|
url := Str(hEntry, "url")
|
|
if url != "" {
|
|
return url
|
|
}
|
|
return source
|
|
}
|
|
|
|
func Content(hEntry *microformats.Microformat) string {
|
|
bridgyTwitterContent := Str(hEntry, "bridgy-twitter-content")
|
|
if bridgyTwitterContent != "" {
|
|
return shorten(bridgyTwitterContent)
|
|
}
|
|
summary := Str(hEntry, "summary")
|
|
if summary != "" {
|
|
return shorten(summary)
|
|
}
|
|
contentEntry := Map(hEntry, "content")["value"]
|
|
return shorten(contentEntry)
|
|
}
|