diff --git a/cmd/owl/web/handler.go b/cmd/owl/web/handler.go index 253b6fe..3e14965 100644 --- a/cmd/owl/web/handler.go +++ b/cmd/owl/web/handler.go @@ -237,6 +237,26 @@ func postMediaHandler(repo *owl.Repository) func(http.ResponseWriter, *http.Requ } } +func userMediaHandler(repo *owl.Repository) func(http.ResponseWriter, *http.Request, httprouter.Params) { + return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { + filepath := ps.ByName("filepath") + + user, err := getUserFromRepo(repo, ps) + if err != nil { + println("Error getting user: ", err.Error()) + notFoundHandler(repo)(w, r) + return + } + filepath = path.Join(user.MediaDir(), filepath) + if _, err := os.Stat(filepath); err != nil { + println("Error getting file: ", err.Error()) + notFoundHandler(repo)(w, r) + return + } + http.ServeFile(w, r, filepath) + } +} + func notFoundHandler(repo *owl.Repository) func(http.ResponseWriter, *http.Request) { return func(w http.ResponseWriter, r *http.Request) { path := r.URL.Path diff --git a/cmd/owl/web/server.go b/cmd/owl/web/server.go index d64c051..81d3d3b 100644 --- a/cmd/owl/web/server.go +++ b/cmd/owl/web/server.go @@ -14,10 +14,11 @@ func Router(repo *owl.Repository) http.Handler { router.ServeFiles("/static/*filepath", http.Dir(repo.StaticDir())) router.GET("/", repoIndexHandler(repo)) router.GET("/user/:user/", userIndexHandler(repo)) - router.POST("/user/:user/webmention/", userWebmentionHandler(repo)) + router.GET("/user/:user/media/*filepath", userMediaHandler(repo)) router.GET("/user/:user/index.xml", userRSSHandler(repo)) router.GET("/user/:user/posts/:post/", postHandler(repo)) router.GET("/user/:user/posts/:post/media/*filepath", postMediaHandler(repo)) + router.POST("/user/:user/webmention/", userWebmentionHandler(repo)) router.NotFound = http.HandlerFunc(notFoundHandler(repo)) return router } @@ -26,10 +27,11 @@ func SingleUserRouter(repo *owl.Repository) http.Handler { router := httprouter.New() router.ServeFiles("/static/*filepath", http.Dir(repo.StaticDir())) router.GET("/", userIndexHandler(repo)) - router.POST("/webmention/", userWebmentionHandler(repo)) + router.GET("/media/*filepath", userMediaHandler(repo)) router.GET("/index.xml", userRSSHandler(repo)) router.GET("/posts/:post/", postHandler(repo)) router.GET("/posts/:post/media/*filepath", postMediaHandler(repo)) + router.POST("/webmention/", userWebmentionHandler(repo)) router.NotFound = http.HandlerFunc(notFoundHandler(repo)) return router } diff --git a/embed/initial/base.html b/embed/initial/base.html index 7e2ecb8..3c75e4e 100644 --- a/embed/initial/base.html +++ b/embed/initial/base.html @@ -18,6 +18,26 @@ border-color: #ccc; } + .avatar { + float: left; + margin-right: 1rem; + + } + + .header { + display: flex; + flex-flow: row wrap; + justify-content: space-between; + align-items: flex-start; + } + + .header-title { + order: 0; + } + + .header-profile { + order: 1; + } hgroup h2 a { color: inherit; } @@ -25,34 +45,34 @@
- +
+ {{ if .User.AvatarUrl }} + + {{ end }} +
+ {{ if .UserConfig.TwitterHandle}} +
  • @{{.UserConfig.TwitterHandle}} on Twitter +
  • + {{ end }} + {{ if .UserConfig.GitHubHandle}} +
  • @{{.UserConfig.GitHubHandle}} on GitHub +
  • + {{ end }} +
    +
    + +
    {{ .Content }}
    diff --git a/renderer_test.go b/renderer_test.go index 6607c0a..892bfa9 100644 --- a/renderer_test.go +++ b/renderer_test.go @@ -251,3 +251,13 @@ func TestRenderIncludesFullUrl(t *testing.T) { t.Error("Expected: " + post.FullUrl()) } } + +func TestAddAvatarIfExist(t *testing.T) { + user := getTestUser() + os.WriteFile(path.Join(user.MediaDir(), "avatar.png"), []byte("test"), 0644) + + result, _ := owl.RenderIndexPage(user) + if !strings.Contains(result, "avatar.png") { + t.Error("Avatar not rendered. Got: " + result) + } +} diff --git a/repository.go b/repository.go index 4c35124..b211568 100644 --- a/repository.go +++ b/repository.go @@ -136,9 +136,10 @@ func (repo *Repository) CreateUser(name string) (User, error) { // creates repo/name folder if it doesn't exist user_dir := new_user.Dir() os.Mkdir(user_dir, 0755) + // create folders os.Mkdir(path.Join(user_dir, "meta"), 0755) - // create public folder os.Mkdir(path.Join(user_dir, "public"), 0755) + os.Mkdir(path.Join(user_dir, "media"), 0755) // create Meta files os.WriteFile(path.Join(user_dir, "meta", "VERSION"), []byte(VERSION), 0644) diff --git a/user.go b/user.go index c158290..fbff29e 100644 --- a/user.go +++ b/user.go @@ -43,6 +43,11 @@ func (user User) WebmentionUrl() string { return url } +func (user User) MediaUrl() string { + url, _ := url.JoinPath(user.UrlPath(), "media") + return url +} + func (user User) PostDir() string { return path.Join(user.Dir(), "public") } @@ -51,6 +56,10 @@ func (user User) MetaDir() string { return path.Join(user.Dir(), "meta") } +func (user User) MediaDir() string { + return path.Join(user.Dir(), "media") +} + func (user User) ConfigFile() string { return path.Join(user.MetaDir(), "config.yml") } @@ -59,6 +68,16 @@ func (user User) Name() string { return user.name } +func (user User) AvatarUrl() string { + for _, ext := range []string{".jpg", ".jpeg", ".png", ".gif"} { + if fileExists(path.Join(user.MediaDir(), "avatar"+ext)) { + url, _ := url.JoinPath(user.MediaUrl(), "avatar"+ext) + return url + } + } + return "" +} + func (user User) Posts() ([]*Post, error) { postFiles := listDir(path.Join(user.Dir(), "public")) posts := make([]*Post, 0) diff --git a/user_test.go b/user_test.go index 7a4e800..3dacfdb 100644 --- a/user_test.go +++ b/user_test.go @@ -302,3 +302,18 @@ func TestPostsSortedByPublishingDateBrokenAtBottom(t *testing.T) { t.Error("Wrong Id, Got: " + posts[1].Id()) } } + +func TestAvatarEmptyIfNotExist(t *testing.T) { + user := getTestUser() + if user.AvatarUrl() != "" { + t.Error("Avatar should be empty") + } +} + +func TestAvatarSetIfFileExist(t *testing.T) { + user := getTestUser() + os.WriteFile(path.Join(user.MediaDir(), "avatar.png"), []byte("test"), 0644) + if user.AvatarUrl() == "" { + t.Error("Avatar should not be empty") + } +}