Sending Webmentions #10

Merged
h4kor merged 18 commits from webmention into master 2022-09-06 19:49:00 +00:00
4 changed files with 109 additions and 12 deletions
Showing only changes of commit 6e6d8005da - Show all commits

70
cmd/owl/webmention.go Normal file
View File

@ -0,0 +1,70 @@
package main
import (
"h4kor/owl-blogs"
"github.com/spf13/cobra"
)
func init() {
rootCmd.AddCommand(webmentionCmd)
}
var webmentionCmd = &cobra.Command{
Use: "webmention",
Short: "Send webmentions for posts, optionally for a specific user",
Long: `Send webmentions for posts, optionally for a specific user`,
Run: func(cmd *cobra.Command, args []string) {
repo, err := owl.OpenRepository(repoPath)
if err != nil {
println("Error opening repository: ", err.Error())
return
}
var users []owl.User
if user == "" {
// send webmentions for all users
users, err = repo.Users()
if err != nil {
println("Error getting users: ", err.Error())
return
}
} else {
// send webmentions for a specific user
user, err := repo.GetUser(user)
users = append(users, user)
if err != nil {
println("Error getting user: ", err.Error())
return
}
}
for _, user := range users {
posts, err := user.Posts()
if err != nil {
println("Error getting posts: ", err.Error())
}
for _, post := range posts {
println("Webmentions for post: ", post.Title())
err := post.ScanForLinks()
if err != nil {
println("Error scanning post for links: ", err.Error())
continue
}
webmentions := post.OutgoingWebmentions()
println("Found ", len(webmentions), " links")
for _, webmention := range webmentions {
err = post.SendWebmention(webmention)
if err != nil {
println("Error sending webmentions: ", err.Error())
} else {
println("Webmention sent to ", webmention.Target)
}
}
}
}
},
}

View File

@ -375,13 +375,12 @@ func (post *Post) SendWebmention(webmention WebmentionOut) error {
html, err := post.user.repo.HttpClient.Get(webmention.Target) html, err := post.user.repo.HttpClient.Get(webmention.Target)
if err != nil { if err != nil {
// TODO handle error
webmention.Supported = false webmention.Supported = false
return err return err
} }
endpoint, err := post.user.repo.Parser.GetWebmentionEndpoint(html) endpoint, err := post.user.repo.Parser.GetWebmentionEndpoint(html)
if err != nil { if err != nil {
// TODO handle error
webmention.Supported = false webmention.Supported = false
return err return err
} }
@ -394,7 +393,6 @@ func (post *Post) SendWebmention(webmention WebmentionOut) error {
_, err = post.user.repo.HttpClient.Post(endpoint, payload) _, err = post.user.repo.HttpClient.Post(endpoint, payload)
if err != nil { if err != nil {
// TODO handle error
return err return err
} }

View File

@ -3,6 +3,8 @@ package owl
import ( import (
"bytes" "bytes"
"errors" "errors"
"fmt"
"io"
"net/http" "net/http"
"net/url" "net/url"
"strings" "strings"
@ -46,13 +48,16 @@ type ParsedHEntry struct {
func (OwlHttpClient) Get(url string) ([]byte, error) { func (OwlHttpClient) Get(url string) ([]byte, error) {
resp, err := http.Get(url) resp, err := http.Get(url)
if resp.StatusCode < 200 || resp.StatusCode > 299 {
return make([]byte, 0), errors.New("Failed to get url. Status code: " + fmt.Sprint(resp.StatusCode))
}
if err != nil { if err != nil {
return []byte{}, err return []byte{}, err
} }
var data []byte defer resp.Body.Close()
_, err = resp.Body.Read(data) return io.ReadAll(resp.Body)
// TODO: encoding
return data, err
} }
func (OwlHttpClient) Post(url string, data url.Values) ([]byte, error) { func (OwlHttpClient) Post(url string, data url.Values) ([]byte, error) {
@ -60,10 +65,8 @@ func (OwlHttpClient) Post(url string, data url.Values) ([]byte, error) {
if err != nil { if err != nil {
return []byte{}, err return []byte{}, err
} }
var respData []byte defer resp.Body.Close()
_, err = resp.Body.Read(respData) return io.ReadAll(resp.Body)
return respData, err
} }
func collectText(n *html.Node, buf *bytes.Buffer) { func collectText(n *html.Node, buf *bytes.Buffer) {
@ -152,7 +155,7 @@ func (OwlHtmlParser) GetWebmentionEndpoint(data []byte) (string, error) {
var findEndpoint func(*html.Node) (string, error) var findEndpoint func(*html.Node) (string, error)
findEndpoint = func(n *html.Node) (string, error) { findEndpoint = func(n *html.Node) (string, error) {
if n.Type == html.ElementNode && n.Data == "link" { if n.Type == html.ElementNode && (n.Data == "link" || n.Data == "a") {
for _, attr := range n.Attr { for _, attr := range n.Attr {
if attr.Key == "rel" && attr.Val == "webmention" { if attr.Key == "rel" && attr.Val == "webmention" {
for _, attr := range n.Attr { for _, attr := range n.Attr {

View File

@ -34,3 +34,29 @@ func TestParseValidHEntryWithoutTitle(t *testing.T) {
t.Errorf("Wrong Title. Expected %v, got %v", "Foo", entry.Title) t.Errorf("Wrong Title. Expected %v, got %v", "Foo", entry.Title)
} }
} }
func TestGetWebmentionEndpointLink(t *testing.T) {
html := []byte("<link rel=\"webmention\" href=\"http://example.com/webmention\" />")
parser := &owl.OwlHtmlParser{}
endpoint, err := parser.GetWebmentionEndpoint(html)
if err != nil {
t.Errorf("Unable to parse feed: %v", err)
}
if endpoint != "http://example.com/webmention" {
t.Errorf("Wrong endpoint. Expected %v, got %v", "http://example.com/webmention", endpoint)
}
}
func TestGetWebmentionEndpointLinkA(t *testing.T) {
html := []byte("<a rel=\"webmention\" href=\"http://example.com/webmention\" />")
parser := &owl.OwlHtmlParser{}
endpoint, err := parser.GetWebmentionEndpoint(html)
if err != nil {
t.Errorf("Unable to parse feed: %v", err)
}
if endpoint != "http://example.com/webmention" {
t.Errorf("Wrong endpoint. Expected %v, got %v", "http://example.com/webmention", endpoint)
}
}