refactoring webmention persistence
This commit is contained in:
parent
a5250eb01c
commit
73ec606b95
106
post.go
106
post.go
|
@ -4,6 +4,7 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
@ -147,32 +148,97 @@ func (post *Post) LoadMeta() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (post *Post) AddWebmention(source string) error {
|
func (post *Post) WebmentionFile(source string) string {
|
||||||
// ensure dir exists
|
|
||||||
os.MkdirAll(post.WebmentionDir(), 0755)
|
|
||||||
|
|
||||||
hash := sha256.Sum256([]byte(source))
|
hash := sha256.Sum256([]byte(source))
|
||||||
hashStr := base64.URLEncoding.EncodeToString(hash[:])
|
hashStr := base64.URLEncoding.EncodeToString(hash[:])
|
||||||
// Check if file already exists
|
return path.Join(post.WebmentionDir(), hashStr+".yml")
|
||||||
fileName := path.Join(post.WebmentionDir(), hashStr+".yml")
|
|
||||||
if fileExists(fileName) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
data := "source: " + source + "\n"
|
|
||||||
html, err := post.user.repo.Retriever.Get(source)
|
|
||||||
if err == nil {
|
|
||||||
entry, err := post.user.repo.Parser.ParseHEntry(html)
|
|
||||||
if err == nil {
|
|
||||||
data += "title: " + entry.Title + "\n"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return os.WriteFile(fileName, []byte(data), 0644)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (post *Post) Webmentions() []string {
|
func (post *Post) PersistWebmention(webmention Webmention) error {
|
||||||
// ensure dir exists
|
// ensure dir exists
|
||||||
os.MkdirAll(post.WebmentionDir(), 0755)
|
os.MkdirAll(post.WebmentionDir(), 0755)
|
||||||
|
|
||||||
return listDir(post.WebmentionDir())
|
// write to file
|
||||||
|
fileName := post.WebmentionFile(webmention.Source)
|
||||||
|
data, err := yaml.Marshal(webmention)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return os.WriteFile(fileName, data, 0644)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (post *Post) Webmention(source string) (Webmention, error) {
|
||||||
|
// ensure dir exists
|
||||||
|
os.MkdirAll(post.WebmentionDir(), 0755)
|
||||||
|
|
||||||
|
// Check if file exists
|
||||||
|
fileName := post.WebmentionFile(source)
|
||||||
|
if !fileExists(fileName) {
|
||||||
|
// return error if file doesn't exist
|
||||||
|
return Webmention{}, fmt.Errorf("Webmention file not found: %s", source)
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := os.ReadFile(fileName)
|
||||||
|
if err != nil {
|
||||||
|
return Webmention{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
mention := Webmention{}
|
||||||
|
err = yaml.Unmarshal(data, &mention)
|
||||||
|
if err != nil {
|
||||||
|
return Webmention{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return mention, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (post *Post) AddWebmention(source string) error {
|
||||||
|
// Check if file already exists
|
||||||
|
_, err := post.Webmention(source)
|
||||||
|
if err != nil {
|
||||||
|
webmention := Webmention{
|
||||||
|
Source: source,
|
||||||
|
}
|
||||||
|
defer post.EnrichWebmention(source)
|
||||||
|
return post.PersistWebmention(webmention)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (post *Post) EnrichWebmention(source string) error {
|
||||||
|
html, err := post.user.repo.Retriever.Get(source)
|
||||||
|
if err == nil {
|
||||||
|
webmention, err := post.Webmention(source)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
entry, err := post.user.repo.Parser.ParseHEntry(html)
|
||||||
|
if err == nil {
|
||||||
|
webmention.Title = entry.Title
|
||||||
|
return post.PersistWebmention(webmention)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (post *Post) Webmentions() []Webmention {
|
||||||
|
// ensure dir exists
|
||||||
|
os.MkdirAll(post.WebmentionDir(), 0755)
|
||||||
|
files := listDir(post.WebmentionDir())
|
||||||
|
webmentions := []Webmention{}
|
||||||
|
for _, file := range files {
|
||||||
|
data, err := os.ReadFile(path.Join(post.WebmentionDir(), file))
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
mention := Webmention{}
|
||||||
|
err = yaml.Unmarshal(data, &mention)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
webmentions = append(webmentions, mention)
|
||||||
|
}
|
||||||
|
|
||||||
|
return webmentions
|
||||||
}
|
}
|
||||||
|
|
35
post_test.go
35
post_test.go
|
@ -1,6 +1,7 @@
|
||||||
package owl_test
|
package owl_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"h4kor/owl-blogs"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -167,6 +168,27 @@ func TestLoadMeta(t *testing.T) {
|
||||||
/// Webmention
|
/// Webmention
|
||||||
///
|
///
|
||||||
|
|
||||||
|
func TestPersistWebmention(t *testing.T) {
|
||||||
|
repo := getTestRepo()
|
||||||
|
user, _ := repo.CreateUser("testuser")
|
||||||
|
post, _ := user.CreateNewPost("testpost")
|
||||||
|
webmention := owl.Webmention{
|
||||||
|
Source: "http://example.com/source",
|
||||||
|
}
|
||||||
|
err := post.PersistWebmention(webmention)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Got error: %v", err)
|
||||||
|
}
|
||||||
|
mentions := post.Webmentions()
|
||||||
|
if len(mentions) != 1 {
|
||||||
|
t.Errorf("Expected 1 webmention, got %d", len(mentions))
|
||||||
|
}
|
||||||
|
|
||||||
|
if mentions[0].Source != webmention.Source {
|
||||||
|
t.Errorf("Expected source: %s, got %s", webmention.Source, mentions[0].Source)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestAddWebmentionCreatesFile(t *testing.T) {
|
func TestAddWebmentionCreatesFile(t *testing.T) {
|
||||||
repo := getTestRepo()
|
repo := getTestRepo()
|
||||||
repo.Retriever = &MockHttpRetriever{}
|
repo.Retriever = &MockHttpRetriever{}
|
||||||
|
@ -174,13 +196,14 @@ func TestAddWebmentionCreatesFile(t *testing.T) {
|
||||||
user, _ := repo.CreateUser("testuser")
|
user, _ := repo.CreateUser("testuser")
|
||||||
post, _ := user.CreateNewPost("testpost")
|
post, _ := user.CreateNewPost("testpost")
|
||||||
|
|
||||||
post.AddWebmention("https://example.com")
|
err := post.AddWebmention("https://example.com")
|
||||||
dir, _ := os.Open(post.WebmentionDir())
|
if err != nil {
|
||||||
defer dir.Close()
|
t.Errorf("Got Error: %v", err)
|
||||||
files, _ := dir.Readdirnames(-1)
|
}
|
||||||
|
|
||||||
if len(files) != 1 {
|
mentions := post.Webmentions()
|
||||||
t.Error("No file created for webmention")
|
if len(mentions) != 1 {
|
||||||
|
t.Errorf("Expected 1 webmention, got %d", len(mentions))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,12 @@ import (
|
||||||
"golang.org/x/net/html"
|
"golang.org/x/net/html"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Webmention struct {
|
||||||
|
Source string `yaml:"source"`
|
||||||
|
Title string `yaml:"title"`
|
||||||
|
Approved bool `yaml:"approved"`
|
||||||
|
}
|
||||||
|
|
||||||
type HttpRetriever interface {
|
type HttpRetriever interface {
|
||||||
Get(url string) ([]byte, error)
|
Get(url string) ([]byte, error)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue