diff --git a/pkg/controllers/posts.go b/pkg/controllers/posts.go index 990d723..0f29334 100644 --- a/pkg/controllers/posts.go +++ b/pkg/controllers/posts.go @@ -41,6 +41,11 @@ func init() { Methods: []string{"GET"}, Handler: BlogArchive, }) + glue.Register(glue.Endpoint{ + Path: "/blog/random", + Methods: []string{"GET"}, + Handler: BlogRandom, + }) glue.Register(glue.Endpoint{ Path: "/blog/drafts", Middleware: []mux.MiddlewareFunc{ @@ -196,6 +201,17 @@ func BlogArchive(w http.ResponseWriter, r *http.Request) { responses.RenderTemplate(w, r, "_builtin/blog/archive.gohtml", v) } +// BlogRandom handles the /blog/random route and picks a random post. +func BlogRandom(w http.ResponseWriter, r *http.Request) { + post, err := models.Posts.LoadRandom(models.Public) + if err != nil { + responses.Error(w, r, http.StatusInternalServerError, err.Error()) + return + } + + responses.Redirect(w, r, "/"+post.Fragment) +} + // EditPost at "/blog/edit" func EditPost(w http.ResponseWriter, r *http.Request) { v := responses.NewTemplateVars(w, r) diff --git a/pkg/models/posts.go b/pkg/models/posts.go index 5d42e5b..8cf21be 100644 --- a/pkg/models/posts.go +++ b/pkg/models/posts.go @@ -12,6 +12,7 @@ import ( "git.kirsle.net/apps/gophertype/pkg/console" "git.kirsle.net/apps/gophertype/pkg/markdown" + "git.kirsle.net/apps/gophertype/pkg/rng" "github.com/albrow/forms" ) @@ -85,6 +86,21 @@ func (m postMan) LoadFragment(fragment string) (Post, error) { return post, r.Error } +// LoadRandom gets a random post for a given privacy setting. +func (m postMan) LoadRandom(privacy string) (Post, error) { + // Find all the post IDs. + var pp []Post + r := DB.Debug().Select("id").Where("privacy = ?", privacy).Find(&pp) + if r.Error != nil || len(pp) == 0 { + return Post{}, r.Error + } + + // Pick one at random. + randPost := pp[rng.Intn(len(pp))] + post, err := Posts.Load(randPost.ID) + return post, err +} + // GetIndex returns the index page of blog posts. func (m postMan) GetIndexPosts(privacy string, page, perPage int) (PagedPosts, error) { var pp = PagedPosts{ diff --git a/pkg/rng/rng.go b/pkg/rng/rng.go new file mode 100644 index 0000000..de808f2 --- /dev/null +++ b/pkg/rng/rng.go @@ -0,0 +1,16 @@ +// Package rng provides the random number generator for the app. +package rng + +import ( + "math/rand" + "time" +) + +func init() { + rand.Seed(time.Now().UnixNano()) +} + +// Intn returns a random number between 0 and n-1. +func Intn(v int) int { + return rand.Intn(v) +} diff --git a/pvt-www/_builtin/blog/edit.gohtml b/pvt-www/_builtin/blog/edit.gohtml index 306a337..37e6c36 100644 --- a/pvt-www/_builtin/blog/edit.gohtml +++ b/pvt-www/_builtin/blog/edit.gohtml @@ -15,6 +15,22 @@ {{ $Post := .V.post }} + +
{{ CSRF }} @@ -44,17 +60,38 @@
+ +
+
{{ $Post.Body }}
+
+ + +
+ +
@@ -141,7 +178,47 @@
+ + + +