WIP RSS renderer. #3
This commit is contained in:
parent
7a857e857f
commit
1b99eaa016
|
@ -56,6 +56,26 @@ func userIndexHandler(repo *owl.Repository) func(http.ResponseWriter, *http.Requ
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func userRSSHandler(repo *owl.Repository) func(http.ResponseWriter, *http.Request, httprouter.Params) {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||||
|
user, err := getUserFromRepo(repo, ps)
|
||||||
|
if err != nil {
|
||||||
|
println("Error getting user: ", err.Error())
|
||||||
|
notFoundHandler(repo)(w, r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
html, err := owl.RenderRSSFeed(user)
|
||||||
|
if err != nil {
|
||||||
|
println("Error rendering index page: ", err.Error())
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
w.Write([]byte("Internal server error"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
println("Rendering index page for user", user.Name())
|
||||||
|
w.Write([]byte(html))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func postHandler(repo *owl.Repository) func(http.ResponseWriter, *http.Request, httprouter.Params) {
|
func postHandler(repo *owl.Repository) func(http.ResponseWriter, *http.Request, httprouter.Params) {
|
||||||
return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||||
postId := ps.ByName("post")
|
postId := ps.ByName("post")
|
||||||
|
|
|
@ -14,6 +14,7 @@ func Router(repo *owl.Repository) http.Handler {
|
||||||
router.ServeFiles("/static/*filepath", http.Dir(repo.StaticDir()))
|
router.ServeFiles("/static/*filepath", http.Dir(repo.StaticDir()))
|
||||||
router.GET("/", repoIndexHandler(repo))
|
router.GET("/", repoIndexHandler(repo))
|
||||||
router.GET("/user/:user/", userIndexHandler(repo))
|
router.GET("/user/:user/", userIndexHandler(repo))
|
||||||
|
router.GET("/user/:user/index.xml", userRSSHandler(repo))
|
||||||
router.GET("/user/:user/posts/:post/", postHandler(repo))
|
router.GET("/user/:user/posts/:post/", postHandler(repo))
|
||||||
router.GET("/user/:user/posts/:post/media/*filepath", postMediaHandler(repo))
|
router.GET("/user/:user/posts/:post/media/*filepath", postMediaHandler(repo))
|
||||||
router.NotFound = http.HandlerFunc(notFoundHandler(repo))
|
router.NotFound = http.HandlerFunc(notFoundHandler(repo))
|
||||||
|
@ -24,6 +25,7 @@ func SingleUserRouter(repo *owl.Repository) http.Handler {
|
||||||
router := httprouter.New()
|
router := httprouter.New()
|
||||||
router.ServeFiles("/static/*filepath", http.Dir(repo.StaticDir()))
|
router.ServeFiles("/static/*filepath", http.Dir(repo.StaticDir()))
|
||||||
router.GET("/", userIndexHandler(repo))
|
router.GET("/", userIndexHandler(repo))
|
||||||
|
router.GET("/index.xml", userRSSHandler(repo))
|
||||||
router.GET("/posts/:post/", postHandler(repo))
|
router.GET("/posts/:post/", postHandler(repo))
|
||||||
router.GET("/posts/:post/media/*filepath", postMediaHandler(repo))
|
router.GET("/posts/:post/media/*filepath", postMediaHandler(repo))
|
||||||
return router
|
return router
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
domain: "http://localhost:8080"
|
|
@ -25,6 +25,10 @@ type Repository struct {
|
||||||
active_user string
|
active_user string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type RepoConfig struct {
|
||||||
|
Domain string `yaml:"domain"`
|
||||||
|
}
|
||||||
|
|
||||||
func CreateRepository(name string) (Repository, error) {
|
func CreateRepository(name string) (Repository, error) {
|
||||||
newRepo := Repository{name: name}
|
newRepo := Repository{name: name}
|
||||||
// check if repository already exists
|
// check if repository already exists
|
||||||
|
@ -46,9 +50,15 @@ func CreateRepository(name string) (Repository, error) {
|
||||||
os.WriteFile(newRepo.StaticDir()+"/"+file.Name(), src_data, 0644)
|
os.WriteFile(newRepo.StaticDir()+"/"+file.Name(), src_data, 0644)
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy repo_base.html to base.html
|
// copy repo/ to newRepo.Dir()
|
||||||
src_data, _ := static_files.ReadFile("embed/initial/repo_base.html")
|
init_files, _ := static_files.ReadDir("embed/initial/repo")
|
||||||
os.WriteFile(newRepo.Dir()+"/base.html", src_data, 0644)
|
for _, file := range init_files {
|
||||||
|
if file.IsDir() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
src_data, _ := static_files.ReadFile("embed/initial/repo/" + file.Name())
|
||||||
|
os.WriteFile(newRepo.Dir()+"/"+file.Name(), src_data, 0644)
|
||||||
|
}
|
||||||
return newRepo, nil
|
return newRepo, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,6 +113,11 @@ func (repo Repository) UserUrlPath(user User) string {
|
||||||
return "/user/" + user.name + "/"
|
return "/user/" + user.name + "/"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (repo Repository) FullUserUrl(user User) string {
|
||||||
|
config, _ := repo.Config()
|
||||||
|
return config.Domain + repo.UserUrlPath(user)
|
||||||
|
}
|
||||||
|
|
||||||
func (repo Repository) Template() (string, error) {
|
func (repo Repository) Template() (string, error) {
|
||||||
// load base.html
|
// load base.html
|
||||||
path := path.Join(repo.Dir(), "base.html")
|
path := path.Join(repo.Dir(), "base.html")
|
||||||
|
@ -179,3 +194,17 @@ func (repo Repository) PostAliases() (map[string]*Post, error) {
|
||||||
}
|
}
|
||||||
return aliases, nil
|
return aliases, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (repo Repository) Config() (RepoConfig, error) {
|
||||||
|
config_path := path.Join(repo.Dir(), "config.yml")
|
||||||
|
config_data, err := ioutil.ReadFile(config_path)
|
||||||
|
if err != nil {
|
||||||
|
return RepoConfig{}, err
|
||||||
|
}
|
||||||
|
var meta RepoConfig
|
||||||
|
err = yaml.Unmarshal(config_data, &meta)
|
||||||
|
if err != nil {
|
||||||
|
return RepoConfig{}, err
|
||||||
|
}
|
||||||
|
return meta, nil
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
package owl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/xml"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RSS struct {
|
||||||
|
XMLName xml.Name `xml:"rss"`
|
||||||
|
Version string `xml:"version,attr"`
|
||||||
|
Channel RSSChannel `xml:"channel"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type RSSChannel struct {
|
||||||
|
Title string `xml:"title"`
|
||||||
|
Link string `xml:"link"`
|
||||||
|
Description string `xml:"description"`
|
||||||
|
Items []RSSItem `xml:"item"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type RSSItem struct {
|
||||||
|
Title string `xml:"title"`
|
||||||
|
Link string `xml:"link"`
|
||||||
|
Description string `xml:"description"`
|
||||||
|
PubDate string `xml:"pubDate"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func RenderRSSFeed(user User) (string, error) {
|
||||||
|
|
||||||
|
config, _ := user.Config()
|
||||||
|
|
||||||
|
rss := RSS{
|
||||||
|
Version: "2.0",
|
||||||
|
Channel: RSSChannel{
|
||||||
|
Title: config.Title,
|
||||||
|
Link: user.repo.FullUserUrl(user),
|
||||||
|
Description: config.SubTitle,
|
||||||
|
Items: make([]RSSItem, 0),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// posts, _ := user.Posts()
|
||||||
|
// for _, post := range posts {
|
||||||
|
// rss.Channel.Items = append(rss.Channel.Items, RSSItem{
|
||||||
|
// Title: post.Title(),
|
||||||
|
// Link: post.Link(),
|
||||||
|
// Description: post.Description(),
|
||||||
|
// PubDate: post.PubDate(),
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
err := xml.NewEncoder(buf).Encode(rss)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return xml.Header + buf.String(), nil
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
package owl_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"h4kor/owl-blogs"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestRenderRSSFeedMeta(t *testing.T) {
|
||||||
|
user := getTestUser()
|
||||||
|
user.SetConfig(owl.UserConfig{
|
||||||
|
Title: "Test Title",
|
||||||
|
SubTitle: "Test SubTitle",
|
||||||
|
})
|
||||||
|
res, err := owl.RenderRSSFeed(user)
|
||||||
|
if err != nil {
|
||||||
|
t.Error("Error rendering RSS feed: " + err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !strings.Contains(res, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>") {
|
||||||
|
t.Error("xml version not rendered. Got: " + res)
|
||||||
|
}
|
||||||
|
if !strings.Contains(res, "<rss version=\"2.0\">") {
|
||||||
|
t.Error("rss version not rendered. Got: " + res)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRenderRSSFeedUserData(t *testing.T) {
|
||||||
|
user := getTestUser()
|
||||||
|
user.SetConfig(owl.UserConfig{
|
||||||
|
Title: "Test Title",
|
||||||
|
SubTitle: "Test SubTitle",
|
||||||
|
})
|
||||||
|
res, err := owl.RenderRSSFeed(user)
|
||||||
|
if err != nil {
|
||||||
|
t.Error("Error rendering RSS feed: " + err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !strings.Contains(res, "Test Title") {
|
||||||
|
t.Error("Title not rendered. Got: " + res)
|
||||||
|
}
|
||||||
|
if !strings.Contains(res, "Test SubTitle") {
|
||||||
|
t.Error("SubTitle not rendered. Got: " + res)
|
||||||
|
}
|
||||||
|
if !strings.Contains(res, "http://localhost:8080/user/") {
|
||||||
|
t.Error("SubTitle not rendered. Got: " + res)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue