diff --git a/cmd/owl/web/handler.go b/cmd/owl/web/handler.go index 6541b91..37f3791 100644 --- a/cmd/owl/web/handler.go +++ b/cmd/owl/web/handler.go @@ -144,7 +144,7 @@ func userWebmentionHandler(repo *owl.Repository) func(http.ResponseWriter, *http return } - tryAlias := func(target string) owl.IPost { + tryAlias := func(target string) owl.Post { parsedTarget, _ := url.Parse(target) aliases, _ := repo.PostAliases() fmt.Printf("aliases %v", aliases) @@ -155,7 +155,7 @@ func userWebmentionHandler(repo *owl.Repository) func(http.ResponseWriter, *http return nil } - var aliasPost owl.IPost + var aliasPost owl.Post parts := strings.Split(target[0], "/") if len(parts) < 2 { aliasPost = tryAlias(target[0]) diff --git a/cmd/owl/webmention.go b/cmd/owl/webmention.go index 3a61810..5c2dba1 100644 --- a/cmd/owl/webmention.go +++ b/cmd/owl/webmention.go @@ -46,7 +46,7 @@ var webmentionCmd = &cobra.Command{ } } - processPost := func(user owl.User, post owl.IPost) error { + processPost := func(user owl.User, post owl.Post) error { println("Webmentions for post: ", post.Title()) err := post.ScanForLinks() diff --git a/post.go b/post.go index 56bf49c..2c5e144 100644 --- a/post.go +++ b/post.go @@ -17,7 +17,7 @@ import ( "gopkg.in/yaml.v2" ) -type Post struct { +type GenericPost struct { user *User id string metaLoaded bool @@ -25,29 +25,33 @@ type Post struct { wmLock sync.Mutex } -func (post *Post) TemplateDir() string { +func (post *GenericPost) TemplateDir() string { return "article" } -type IPost interface { +type Post interface { TemplateDir() string - Id() string + // Actual Data User() *User - Dir() string - IncomingWebmentionsFile() string - OutgoingWebmentionsFile() string - MediaDir() string - UrlPath() string - FullUrl() string - UrlMediaPath(filename string) string + Id() string Title() string - ContentFile() string Meta() PostMeta Content() []byte RenderedContent() string Aliases() []string - LoadMeta() error + + // Filesystem + Dir() string + MediaDir() string + ContentFile() string + + // Urls + UrlPath() string + FullUrl() string + UrlMediaPath(filename string) string + + // Webmentions Support IncomingWebmentions() []WebmentionIn OutgoingWebmentions() []WebmentionOut PersistIncomingWebmention(webmention WebmentionIn) error @@ -151,64 +155,64 @@ type PostWebmetions struct { Outgoing []WebmentionOut `ymal:"outgoing"` } -func (post *Post) Id() string { +func (post *GenericPost) Id() string { return post.id } -func (post *Post) User() *User { +func (post *GenericPost) User() *User { return post.user } -func (post *Post) Dir() string { +func (post *GenericPost) Dir() string { return path.Join(post.user.Dir(), "public", post.id) } -func (post *Post) IncomingWebmentionsFile() string { +func (post *GenericPost) IncomingWebmentionsFile() string { return path.Join(post.Dir(), "incoming_webmentions.yml") } -func (post *Post) OutgoingWebmentionsFile() string { +func (post *GenericPost) OutgoingWebmentionsFile() string { return path.Join(post.Dir(), "outgoing_webmentions.yml") } -func (post *Post) MediaDir() string { +func (post *GenericPost) MediaDir() string { return path.Join(post.Dir(), "media") } -func (post *Post) UrlPath() string { +func (post *GenericPost) UrlPath() string { return post.user.UrlPath() + "posts/" + post.id + "/" } -func (post *Post) FullUrl() string { +func (post *GenericPost) FullUrl() string { return post.user.FullUrl() + "posts/" + post.id + "/" } -func (post *Post) UrlMediaPath(filename string) string { +func (post *GenericPost) UrlMediaPath(filename string) string { return post.UrlPath() + "media/" + filename } -func (post *Post) Title() string { +func (post *GenericPost) Title() string { return post.Meta().Title } -func (post *Post) ContentFile() string { +func (post *GenericPost) ContentFile() string { return path.Join(post.Dir(), "index.md") } -func (post *Post) Meta() PostMeta { +func (post *GenericPost) Meta() PostMeta { if !post.metaLoaded { post.LoadMeta() } return post.meta } -func (post *Post) Content() []byte { +func (post *GenericPost) Content() []byte { // read file data, _ := os.ReadFile(post.ContentFile()) return data } -func (post *Post) RenderedContent() string { +func (post *GenericPost) RenderedContent() string { data := post.Content() // trim yaml block @@ -250,11 +254,11 @@ func (post *Post) RenderedContent() string { } -func (post *Post) Aliases() []string { +func (post *GenericPost) Aliases() []string { return post.Meta().Aliases } -func (post *Post) LoadMeta() error { +func (post *GenericPost) LoadMeta() error { data := post.Content() // get yaml metadata block @@ -280,7 +284,7 @@ func (post *Post) LoadMeta() error { return nil } -func (post *Post) IncomingWebmentions() []WebmentionIn { +func (post *GenericPost) IncomingWebmentions() []WebmentionIn { // return parsed webmentions fileName := post.IncomingWebmentionsFile() if !fileExists(fileName) { @@ -293,7 +297,7 @@ func (post *Post) IncomingWebmentions() []WebmentionIn { return webmentions } -func (post *Post) OutgoingWebmentions() []WebmentionOut { +func (post *GenericPost) OutgoingWebmentions() []WebmentionOut { // return parsed webmentions fileName := post.OutgoingWebmentionsFile() if !fileExists(fileName) { @@ -307,7 +311,7 @@ func (post *Post) OutgoingWebmentions() []WebmentionOut { } // PersistWebmentionOutgoing persists incoming webmention -func (post *Post) PersistIncomingWebmention(webmention WebmentionIn) error { +func (post *GenericPost) PersistIncomingWebmention(webmention WebmentionIn) error { post.wmLock.Lock() defer post.wmLock.Unlock() @@ -336,7 +340,7 @@ func (post *Post) PersistIncomingWebmention(webmention WebmentionIn) error { } // PersistOutgoingWebmention persists a webmention to the webmention file. -func (post *Post) PersistOutgoingWebmention(webmention *WebmentionOut) error { +func (post *GenericPost) PersistOutgoingWebmention(webmention *WebmentionOut) error { post.wmLock.Lock() defer post.wmLock.Unlock() @@ -364,7 +368,7 @@ func (post *Post) PersistOutgoingWebmention(webmention *WebmentionOut) error { return nil } -func (post *Post) AddIncomingWebmention(source string) error { +func (post *GenericPost) AddIncomingWebmention(source string) error { // Check if file already exists wm := WebmentionIn{ Source: source, @@ -376,7 +380,7 @@ func (post *Post) AddIncomingWebmention(source string) error { return post.PersistIncomingWebmention(wm) } -func (post *Post) EnrichWebmention(webmention WebmentionIn) error { +func (post *GenericPost) EnrichWebmention(webmention WebmentionIn) error { resp, err := post.user.repo.HttpClient.Get(webmention.Source) if err == nil { entry, err := post.user.repo.Parser.ParseHEntry(resp) @@ -388,7 +392,7 @@ func (post *Post) EnrichWebmention(webmention WebmentionIn) error { return err } -func (post *Post) ApprovedIncomingWebmentions() []WebmentionIn { +func (post *GenericPost) ApprovedIncomingWebmentions() []WebmentionIn { webmentions := post.IncomingWebmentions() approved := []WebmentionIn{} for _, webmention := range webmentions { @@ -406,7 +410,7 @@ func (post *Post) ApprovedIncomingWebmentions() []WebmentionIn { // ScanForLinks scans the post content for links and adds them to the // `status.yml` file for the post. The links are not scanned by this function. -func (post *Post) ScanForLinks() error { +func (post *GenericPost) ScanForLinks() error { // this could be done in markdown parsing, but I don't want to // rely on goldmark for this (yet) postHtml := post.RenderedContent() @@ -423,7 +427,7 @@ func (post *Post) ScanForLinks() error { return nil } -func (post *Post) SendWebmention(webmention WebmentionOut) error { +func (post *GenericPost) SendWebmention(webmention WebmentionOut) error { defer post.PersistOutgoingWebmention(&webmention) // if last scan is less than 7 days ago, don't send webmention diff --git a/post_test.go b/post_test.go index ad23343..4f5c727 100644 --- a/post_test.go +++ b/post_test.go @@ -98,7 +98,7 @@ func TestRawHTMLIfAllowedByRepo(t *testing.T) { assertions.AssertContains(t, html, "\n" os.WriteFile(post.ContentFile(), []byte(content), 0644) - err := post.LoadMeta() - - assertions.AssertNoError(t, err, "Error loading meta") - assertions.AssertEqual(t, post.Meta().Title, "test") assertions.AssertLen(t, post.Meta().Aliases, 1) assertions.AssertEqual(t, post.Meta().Draft, true) diff --git a/post_types.go b/post_types.go index b70da67..4ca9f0d 100644 --- a/post_types.go +++ b/post_types.go @@ -1,7 +1,7 @@ package owl type Note struct { - Post + GenericPost } func (n *Note) TemplateDir() string { @@ -9,7 +9,7 @@ func (n *Note) TemplateDir() string { } type Article struct { - Post + GenericPost } func (a *Article) TemplateDir() string { @@ -17,7 +17,7 @@ func (a *Article) TemplateDir() string { } type Page struct { - Post + GenericPost } func (p *Page) TemplateDir() string { @@ -25,7 +25,7 @@ func (p *Page) TemplateDir() string { } type Bookmark struct { - Post + GenericPost } func (b *Bookmark) TemplateDir() string { @@ -33,7 +33,7 @@ func (b *Bookmark) TemplateDir() string { } type Reply struct { - Post + GenericPost } func (r *Reply) TemplateDir() string { diff --git a/renderer.go b/renderer.go index 754526c..bb195d8 100644 --- a/renderer.go +++ b/renderer.go @@ -18,7 +18,7 @@ type PageContent struct { type PostRenderData struct { Title string - Post IPost + Post Post Content template.HTML } @@ -119,7 +119,7 @@ func renderIntoBaseTemplate(user User, data PageContent) (string, error) { return html.String(), err } -func renderPostContent(post IPost) (string, error) { +func renderPostContent(post Post) (string, error) { buf := post.RenderedContent() postHtml, err := renderEmbedTemplate( fmt.Sprintf("embed/%s/detail.html", post.TemplateDir()), @@ -132,7 +132,7 @@ func renderPostContent(post IPost) (string, error) { return postHtml, err } -func RenderPost(post IPost) (string, error) { +func RenderPost(post Post) (string, error) { postHtml, err := renderPostContent(post) if err != nil { return "", err diff --git a/repository.go b/repository.go index 923d7c6..63d5584 100644 --- a/repository.go +++ b/repository.go @@ -158,12 +158,12 @@ func (repo Repository) GetUser(name string) (User, error) { return user, nil } -func (repo Repository) PostAliases() (map[string]IPost, error) { +func (repo Repository) PostAliases() (map[string]Post, error) { users, err := repo.Users() if err != nil { return nil, err } - aliases := make(map[string]IPost) + aliases := make(map[string]Post) for _, user := range users { user_aliases, err := user.PostAliases() if err != nil { diff --git a/repository_test.go b/repository_test.go index 6e7bacb..39352a0 100644 --- a/repository_test.go +++ b/repository_test.go @@ -213,7 +213,7 @@ func TestCanGetMapWithAllPostAliases(t *testing.T) { posts, _ := user.PublishedPosts() assertions.AssertLen(t, posts, 1) - var aliases map[string]owl.IPost + var aliases map[string]owl.Post aliases, err := repo.PostAliases() assertions.AssertNoError(t, err, "Error getting post aliases: ") assertions.AssertMapLen(t, aliases, 2) @@ -247,7 +247,7 @@ func TestAliasesHaveCorrectPost(t *testing.T) { posts, _ := user.PublishedPosts() assertions.AssertLen(t, posts, 2) - var aliases map[string]owl.IPost + var aliases map[string]owl.Post aliases, err := repo.PostAliases() assertions.AssertNoError(t, err, "Error getting post aliases: ") assertions.AssertMapLen(t, aliases, 2) diff --git a/user.go b/user.go index 8d3ef88..397c5de 100644 --- a/user.go +++ b/user.go @@ -197,9 +197,9 @@ func (user User) FaviconUrl() string { return "" } -func (user User) AllPosts() ([]IPost, error) { +func (user User) AllPosts() ([]Post, error) { postFiles := listDir(path.Join(user.Dir(), "public")) - posts := make([]IPost, 0) + posts := make([]Post, 0) for _, id := range postFiles { // if is a directory and has index.md, add to posts if dirExists(path.Join(user.Dir(), "public", id)) { @@ -211,7 +211,7 @@ func (user User) AllPosts() ([]IPost, error) { } type PostWithDate struct { - post IPost + post Post date time.Time } @@ -233,7 +233,7 @@ func (user User) AllPosts() ([]IPost, error) { return posts, nil } -func (user User) PublishedPosts() ([]IPost, error) { +func (user User) PublishedPosts() ([]Post, error) { posts, _ := user.AllPosts() // remove drafts @@ -249,7 +249,7 @@ func (user User) PublishedPosts() ([]IPost, error) { return posts, nil } -func (user User) PrimaryFeedPosts() ([]IPost, error) { +func (user User) PrimaryFeedPosts() ([]Post, error) { config := user.Config() include := config.PrimaryListInclude if len(include) == 0 { @@ -262,7 +262,7 @@ func (user User) PrimaryFeedPosts() ([]IPost, error) { }) } -func (user User) GetPostsOfList(list PostList) ([]IPost, error) { +func (user User) GetPostsOfList(list PostList) ([]Post, error) { posts, _ := user.PublishedPosts() // remove posts not included @@ -278,29 +278,29 @@ func (user User) GetPostsOfList(list PostList) ([]IPost, error) { return posts, nil } -func (user User) GetPost(id string) (IPost, error) { +func (user User) GetPost(id string) (Post, error) { // check if posts index.md exists if !fileExists(path.Join(user.Dir(), "public", id, "index.md")) { - return &Post{}, fmt.Errorf("post %s does not exist", id) + return &GenericPost{}, fmt.Errorf("post %s does not exist", id) } - post := Post{user: &user, id: id} + post := GenericPost{user: &user, id: id} switch post.Meta().Type { case "article": - return &Article{Post: post}, nil + return &Article{GenericPost: post}, nil case "note": - return &Note{Post: post}, nil + return &Note{GenericPost: post}, nil case "reply": - return &Reply{Post: post}, nil + return &Reply{GenericPost: post}, nil case "bookmark": - return &Bookmark{Post: post}, nil + return &Bookmark{GenericPost: post}, nil case "page": - return &Page{Post: post}, nil + return &Page{GenericPost: post}, nil } return &post, nil } -func (user User) CreateNewPost(meta PostMeta, content string) (IPost, error) { +func (user User) CreateNewPost(meta PostMeta, content string) (Post, error) { slugHint := meta.Title if slugHint == "" { slugHint = "note" @@ -319,7 +319,7 @@ func (user User) CreateNewPost(meta PostMeta, content string) (IPost, error) { break } } - post := Post{user: &user, id: folder_name} + post := GenericPost{user: &user, id: folder_name} // if date is not set, set it to now if meta.Date.IsZero() { @@ -331,7 +331,7 @@ func (user User) CreateNewPost(meta PostMeta, content string) (IPost, error) { // write meta meta_bytes, err := yaml.Marshal(meta) if err != nil { - return &Post{}, err + return &GenericPost{}, err } initial_content += string(meta_bytes) initial_content += "---\n" @@ -366,8 +366,8 @@ func (user User) SetConfig(new_config UserConfig) error { return saveToYaml(user.ConfigFile(), new_config) } -func (user User) PostAliases() (map[string]IPost, error) { - post_aliases := make(map[string]IPost) +func (user User) PostAliases() (map[string]Post, error) { + post_aliases := make(map[string]Post) posts, err := user.PublishedPosts() if err != nil { return post_aliases, err diff --git a/user_test.go b/user_test.go index 0b50a35..bdac4c3 100644 --- a/user_test.go +++ b/user_test.go @@ -225,7 +225,7 @@ func TestPostsSortedByPublishingDateLatestFirst(t *testing.T) { func TestPostsSortedByPublishingDateLatestFirst2(t *testing.T) { user := getTestUser() // Create a new post - posts := []owl.IPost{} + posts := []owl.Post{} for i := 59; i >= 0; i-- { post, _ := user.CreateNewPost(owl.PostMeta{Type: "article", Title: "testpost"}, "") content := "---\n"