simplify code, smaller functions

This commit is contained in:
Umputun
2017-12-26 01:57:46 -06:00
parent 7b023099f9
commit 76d2d89c8d
6 changed files with 53 additions and 42 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
# remark [![Build Status](http://drone.umputun.com:9080/api/badges/umputun/remark/status.svg)](http://drone.umputun.com:9080/umputun/remark)
Remark ia a comment engine, self-hosted. Lightweight, simple (but functional) and doesn't spy on users.
Remark ia a comment engine, self-hosted, lightweight, simple (but functional) and doesn't spy on users.
- Supports social login via google and github
- Moderation allowing admins to remove comments and block users
+2 -2
View File
@@ -61,7 +61,7 @@ func initProvider(p Params, provider Provider) *Provider {
func (p Provider) LoginHandler(w http.ResponseWriter, r *http.Request) {
// make state (random) and store in session
state := randToken()
state := p.randToken()
session, err := p.Get(r, "remark")
if err != nil {
log.Printf("[DEBUG] can't get session, %s", err)
@@ -174,7 +174,7 @@ func (p Provider) LogoutHandler(w http.ResponseWriter, r *http.Request) {
log.Printf("[DEBUG] logout, %+v", session.Values)
}
func randToken() string {
func (p Provider) randToken() string {
b := make([]byte, 32)
if _, err := rand.Read(b); err != nil {
log.Fatalf("[ERROR] can't get randoms, %s", err)
+10 -8
View File
@@ -22,8 +22,16 @@ const (
Full // real auth
)
var devUser = store.User{
ID: "dev",
Name: "developer one",
Picture: "https://friends.radio-t.com/resources/images/rt_logo_64.png",
Profile: "https://radio-t.com/info/",
Admin: true,
}
// Auth middleware adds auth from session and populates user info
func Auth(sessionStore *sessions.FilesystemStore, admins []string, modes ...Mode) func(http.Handler) http.Handler {
func Auth(sessionStore *sessions.FilesystemStore, admins []string, modes []Mode) func(http.Handler) http.Handler {
inModes := func(mode Mode) bool {
for _, m := range modes {
@@ -39,13 +47,7 @@ func Auth(sessionStore *sessions.FilesystemStore, admins []string, modes ...Mode
// for dev mode skip all real auth, make dev admin user
if inModes(Developer) {
user := store.User{
ID: "dev",
Name: "developer one",
Picture: "https://friends.radio-t.com/resources/images/rt_logo_64.png",
Profile: "https://radio-t.com/info/",
Admin: true,
}
user := devUser
ctx := r.Context()
ctx = context.WithValue(ctx, contextKey("user"), user)
r = r.WithContext(ctx)
+33 -28
View File
@@ -7,7 +7,7 @@ import (
"github.com/umputun/remark/app/store"
)
// Tree is formatter as comment tree list of comments
// Tree is formatter making tree from list of comments
type Tree struct {
Nodes []*Node `json:"comments"`
}
@@ -19,40 +19,22 @@ type Node struct {
}
// MakeTree gets unsorted list of comments and produces Tree
func MakeTree(comments []store.Comment, sortType string) (res Tree) {
res = Tree{}
func MakeTree(comments []store.Comment, sortType string) *Tree {
res := Tree{}
repComments := res.filter(comments, func(c store.Comment) bool { return c.ParentID == "" })
repComments := res.filter(comments, "")
for _, rc := range repComments {
node := Node{Comment: rc}
res.Nodes = append(res.Nodes, res.proc(comments, &node, rc.ID))
}
// sort result according to sortType
sort.Slice(res.Nodes, func(i, j int) bool {
switch sortType {
case "+time", "-time", "time":
if strings.HasPrefix(sortType, "-") {
return res.Nodes[i].Comment.Timestamp.After(res.Nodes[j].Comment.Timestamp)
}
return res.Nodes[i].Comment.Timestamp.Before(res.Nodes[j].Comment.Timestamp)
case "+score", "-score", "score":
if strings.HasPrefix(sortType, "-") {
return res.Nodes[i].Comment.Score > res.Nodes[j].Comment.Score
}
return res.Nodes[i].Comment.Score < res.Nodes[j].Comment.Score
default:
return res.Nodes[i].Comment.Timestamp.Before(res.Nodes[j].Comment.Timestamp)
}
})
return res
res.sortNodes(sortType)
return &res
}
// proc makes tree for one top-level comment recursively
func (t *Tree) proc(comments []store.Comment, node *Node, parentID string) *Node {
repComments := t.filter(comments, func(c store.Comment) bool { return c.ParentID == parentID })
repComments := t.filter(comments, parentID)
for _, rc := range repComments {
rnode := &Node{Comment: rc, Replies: []*Node{}}
node.Replies = append(node.Replies, rnode)
@@ -66,11 +48,34 @@ func (t *Tree) proc(comments []store.Comment, node *Node, parentID string) *Node
return node
}
func (t *Tree) filter(comments []store.Comment, fn func(c store.Comment) bool) (f []store.Comment) {
// filter returns comments for parentID
func (t *Tree) filter(comments []store.Comment, parentID string) (f []store.Comment) {
for _, c := range comments {
if fn(c) {
if c.ParentID == parentID {
f = append(f, c)
}
}
return f
}
func (t *Tree) sortNodes(sortType string) {
sort.Slice(t.Nodes, func(i, j int) bool {
switch sortType {
case "+time", "-time", "time":
if strings.HasPrefix(sortType, "-") {
return t.Nodes[i].Comment.Timestamp.After(t.Nodes[j].Comment.Timestamp)
}
return t.Nodes[i].Comment.Timestamp.Before(t.Nodes[j].Comment.Timestamp)
case "+score", "-score", "score":
if strings.HasPrefix(sortType, "-") {
return t.Nodes[i].Comment.Score > t.Nodes[j].Comment.Score
}
return t.Nodes[i].Comment.Score < t.Nodes[j].Comment.Score
default:
return t.Nodes[i].Comment.Timestamp.Before(t.Nodes[j].Comment.Timestamp)
}
})
}
+1 -1
View File
@@ -36,7 +36,7 @@ func TestStore_MakeTree(t *testing.T) {
err := enc.Encode(res)
assert.Nil(t, err)
assert.Equal(t, expJSON, string(buf.Bytes()))
t.Log(string(buf.Bytes()))
// t.Log(string(buf.Bytes()))
}
const expJSON = `{
+6 -2
View File
@@ -14,6 +14,7 @@ import (
"github.com/go-chi/chi"
"github.com/go-chi/chi/middleware"
"github.com/go-chi/render"
"github.com/gorilla/context"
"github.com/gorilla/sessions"
"github.com/umputun/remark/app/migrator"
@@ -51,9 +52,12 @@ func (s *Server) Run() {
router := chi.NewRouter()
router.Use(middleware.RealIP, Recoverer)
router.Use(middleware.Throttle(1000), middleware.Timeout(60*time.Second))
router.Use(auth.Auth(s.SessionStore, s.Admins, applyDevMode(auth.Anonymous)...))
router.Use(auth.Auth(s.SessionStore, s.Admins, applyDevMode(auth.Anonymous)))
router.Use(Limiter(10), AppInfo("remark", s.Version), Ping, Logger(LogAll))
// If you aren't using gorilla/mux, you need to wrap your handlers with context.ClearHandler
router.Use(context.ClearHandler)
router.Get("/login/google", s.AuthGoogle.LoginHandler)
router.Get("/auth/google", s.AuthGoogle.AuthHandler)
router.Get("/logout", s.AuthGithub.LogoutHandler) // can hit any provider
@@ -66,7 +70,7 @@ func (s *Server) Run() {
rapi.Get("/last/{max}", s.lastCommentsCtrl)
rapi.Get("/count", s.countCtrl)
rapi.With(auth.Auth(s.SessionStore, s.Admins, applyDevMode(auth.Full)...)).Group(func(rauth chi.Router) {
rapi.With(auth.Auth(s.SessionStore, s.Admins, applyDevMode(auth.Full))).Group(func(rauth chi.Router) {
rauth.Post("/comment", s.createCommentCtrl)
rauth.Get("/user", s.userInfoCtrl)
rauth.Put("/vote/{id}", s.voteCtrl)