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} }