127 lines
2.3 KiB
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}
|
||
|
}
|