nlink/nomad/post.go

127 lines
2.3 KiB
Go

package nomad
import (
"bytes"
"errors"
"fmt"
"path/filepath"
"git.sr.ht/~thrrgilag/woodstock"
"github.com/anaskhan96/soup"
)
func nomadLink(url Source) string {
return fmt.Sprintf("[nomad.wntrmute.net](%s)", url.ID())
}
type sel struct {
selectors []string
}
func selector(selectors ...string) sel {
return sel{selectors: selectors}
}
func find(root soup.Root, attr string, selectors ...sel) (string, bool) {
result := root
for _, selector := range selectors {
result = result.Find(selector.selectors...)
if result.Pointer == nil {
return "", false
}
}
if attr == "" {
text := result.Text()
return text, text != ""
}
value, hasAttr := result.Attrs()[attr]
return value, hasAttr
}
type Post struct {
Image Source
Body string
URL Source
}
func NewPost(item Item) Post {
return Post{
Body: nomadLink(item.URL),
URL: item.URL,
}
}
func (p *Post) Fetch() error {
pageSource, err := p.URL.Fetch()
if err != nil {
return err
}
root := soup.HTMLParse(pageSource)
body, hasBody := find(root, "", selector("p", "class", "entry-body"))
if hasBody {
p.Body = body + " " + p.Body
}
imageURL, hasImageURL := find(
root, "src",
selector("div", "class", "entry-image"),
selector("img"))
if hasImageURL {
p.Image = NewURLSource(imageURL)
}
return nil
}
func (p Post) Post(client *woodstock.Client) error {
pnutPost := woodstock.NewPost{
Text: p.Body,
}
if p.Image != nil {
imageData, err := p.Image.FetchBytes()
if err != nil {
return err
}
params := map[string]string{
"name": filepath.Base(p.Image.ID()),
"is_public": "1",
"type": "photo",
}
r := bytes.NewBuffer(imageData)
file, err := client.CreateFile(params, r)
if err != nil {
panic(err.Error())
return err
}
pnutPost.Raw = []woodstock.Raw{pnutOembedRaw(file)}
}
result, err := client.Post(pnutPost)
if err != nil {
return err
}
if result.Meta.ErrorMessage != "" {
return errors.New("woodstock: " + result.Meta.ErrorMessage)
}
return nil
}
func pnutOembedRaw(file woodstock.FileResult) woodstock.Raw {
fval := map[string]string{
"file_id": file.Data.ID,
"file_token": file.Data.FileToken,
"format": "oembed",
}
value := map[string]map[string]string{"+io.pnut.core.file": fval}
return woodstock.Raw{Type: "io.pnut.core.oembed", Value: value}
}