package kinds import ( "net/url" "strings" "time" "mimicry/style" "fmt" "errors" "mimicry/render" ) type Post Dict // TODO: go through and remove all the trims, they // make things less predictable // TODO: make the Post references *Post because why not func (p Post) Kind() (string, error) { kind, err := Get[string](p, "type") return strings.ToLower(kind), err } func (p Post) Title() (string, error) { title, err := GetNatural(p, "name", "en") return strings.TrimSpace(title), err } func (p Post) Body() (string, error) { body, err := GetNatural(p, "content", "en") mediaType, err := Get[string](p, "mediaType") if err != nil { mediaType = "text/html" } return render.Render(body, mediaType) } func (p Post) BodyPreview() (string, error) { body, err := p.Body() // probably should convert to runes and just work with that if len(body) > 280*2 { // this is a bug because len counts bytes whereas later I work based on runes return fmt.Sprintf("%s…", string([]rune(body)[:280])), err } else { return body, err } } func (p Post) Identifier() (*url.URL, error) { return GetURL(p, "id") } func (p Post) Created() (time.Time, error) { return GetTime(p, "published") } func (p Post) Updated() (time.Time, error) { return GetTime(p, "updated") } func (p Post) Category() string { return "post" } func (p Post) Creators() ([]Actor, error) { return GetContent[Actor](p, "attributedTo") } func (p Post) Attachments() ([]Link, error) { return GetLinksLenient(p, "attachment") } // func (p Post) bestLink() (Link, error) { // } func (p Post) Link() (Link, error) { kind, err := p.Kind() if err != nil { return nil, err } links, err := GetLinksStrict(p, "url") if err != nil { return nil, err } switch kind { case "audio", "image", "video": return SelectBestLink(links, kind) case "article", "document", "note", "page": return SelectFirstLink(links) default: return nil, errors.New("Link extraction is not supported for type " + kind) } } func (p Post) String() (string, error) { output := "" if title, err := p.Title(); err == nil { output += style.Bold(title) output += "\n" } if body, err := p.Body(); err == nil { output += body output += "\n" } if created, err := p.Created(); err == nil { output += time.Now().Sub(created).String() } if creators, err := p.Creators(); err == nil { output += " " for _, creator := range creators { if name, err := creator.InlineName(); err == nil { output += style.Bold(name) + ", " } } } if link, err := p.Link(); err == nil { if linkStr, err := link.String(); err == nil { output += "\n" output += linkStr } } if attachments, err := p.Attachments(); err == nil { output += "\nAttachments:\n" for _, attachment := range attachments { if attachmentStr, err := attachment.String(); err == nil { output += attachmentStr + "\n" } else { continue } } } return strings.TrimSpace(output), nil }