add /count request
This commit is contained in:
@@ -8,7 +8,7 @@ Comment engine
|
||||
|
||||
- `GET /login/{provider}?from=http://url` - perform "social" login with one of supported providers and redirect to `url`
|
||||
- `GET /logout` - logout
|
||||
- `GET /user` - get user info, _auth required_
|
||||
- `GET /api/v1/user` - get user info, _auth required_
|
||||
|
||||
```
|
||||
type User struct {
|
||||
@@ -24,7 +24,7 @@ _currently supported providers are `google` and `github`_
|
||||
|
||||
### Commenting
|
||||
|
||||
- `POST /comment` - add a comment. _auth required_
|
||||
- `POST /api/v1/comment` - add a comment. _auth required_
|
||||
|
||||
```
|
||||
type Comment struct {
|
||||
@@ -44,8 +44,9 @@ type Locator struct {
|
||||
}
|
||||
```
|
||||
|
||||
- `GET /find?url=post-url` - find all comments for given post returns list of `Comment`
|
||||
- `GET /last/{max}` - get last `{max}` comments
|
||||
- `GET /id/{id}` - get comment by `id`
|
||||
- `PUT /vote/{id}?url=post-url&vote=1` - vote for comment. `vote`=1 will increase score, -1 decreases. _auth required_
|
||||
- `DELETE /comment/{id}` - delete comment by `id`. _auth and admin required_
|
||||
- `GET /api/v1/find?url=post-url` - find all comments for given post returns list of `Comment`
|
||||
- `GET /api/v1/last/{max}` - get last `{max}` comments
|
||||
- `GET /api/v1/id/{id}` - get comment by `id`
|
||||
- `GET /api/v1/count?url=post-url` - get comment's count for `{url}`
|
||||
- `PUT /api/v1/vote/{id}?url=post-url&vote=1` - vote for comment. `vote`=1 will increase score, -1 decreases. _auth required_
|
||||
- `DELETE /api/v1/comment/{id}?url=post-url` - delete comment by `id`. _auth and admin required_
|
||||
+22
-8
@@ -41,15 +41,18 @@ func (s *Server) Run() {
|
||||
router.Get("/login/github", s.AuthGithub.LoginHandler)
|
||||
router.Get("/auth/github", s.AuthGithub.AuthHandler)
|
||||
|
||||
router.Get("/find", s.getURLComments)
|
||||
router.Get("/id/{id}", s.getByID)
|
||||
router.Get("/last/{max}", s.getLastComments)
|
||||
router.Route("/api/v1", func(rapi chi.Router) {
|
||||
rapi.Get("/find", s.getURLComments)
|
||||
rapi.Get("/id/{id}", s.getByID)
|
||||
rapi.Get("/last/{max}", s.getLastComments)
|
||||
rapi.Get("/count", s.getCountCtrl)
|
||||
|
||||
router.With(Auth(s.SessionStore, s.Admins)).Group(func(r chi.Router) {
|
||||
r.Post("/comment", s.createCommentCtrl)
|
||||
r.Get("/user", s.getUserInfo)
|
||||
r.Put("/vote/{id}", s.voteCtrl)
|
||||
r.With(AdminOnly).Delete("/comment/{id}", s.deleteCommentCtrl)
|
||||
rapi.With(Auth(s.SessionStore, s.Admins)).Group(func(r chi.Router) {
|
||||
r.Post("/comment", s.createCommentCtrl)
|
||||
r.Get("/user", s.getUserInfo)
|
||||
r.Put("/vote/{id}", s.voteCtrl)
|
||||
r.With(AdminOnly).Delete("/comment/{id}", s.deleteCommentCtrl)
|
||||
})
|
||||
})
|
||||
|
||||
log.Fatal(http.ListenAndServe(":8080", router))
|
||||
@@ -179,6 +182,17 @@ func (s *Server) getUserInfo(w http.ResponseWriter, r *http.Request) {
|
||||
render.JSON(w, r, user)
|
||||
}
|
||||
|
||||
// GET /count?url=post-url
|
||||
func (s *Server) getCountCtrl(w http.ResponseWriter, r *http.Request) {
|
||||
url := r.URL.Query().Get("url")
|
||||
count, err := s.Store.Count(store.Locator{URL: url})
|
||||
if err != nil {
|
||||
httpError(w, r, http.StatusBadRequest, err, "can't get count")
|
||||
return
|
||||
}
|
||||
render.JSON(w, r, JSON{"count": count, "url": url})
|
||||
}
|
||||
|
||||
// PUT /vote/{id}?url=post-url&vote=1
|
||||
func (s *Server) voteCtrl(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
|
||||
@@ -243,6 +243,20 @@ func (b *BoltDB) Vote(locator Locator, commentID int64, userID string, val bool)
|
||||
return comment, err
|
||||
}
|
||||
|
||||
func (b *BoltDB) Count(locator Locator) (count int, err error) {
|
||||
err = b.View(func(tx *bolt.Tx) error {
|
||||
bucket := tx.Bucket([]byte(locator.URL))
|
||||
if bucket == nil {
|
||||
return errors.Errorf("no bucket %s in store", locator.URL)
|
||||
}
|
||||
|
||||
count = bucket.Stats().KeyN
|
||||
return nil
|
||||
})
|
||||
|
||||
return count, err
|
||||
}
|
||||
|
||||
func (b *BoltDB) keyFromComment(comment Comment) []byte {
|
||||
return []byte(fmt.Sprintf("%22d", comment.ID))
|
||||
}
|
||||
|
||||
+10
-1
@@ -31,7 +31,7 @@ func TestBoltDB_Delete(t *testing.T) {
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 2, len(res))
|
||||
|
||||
err = b.Delete("https://radio-t.com", res[0].ID)
|
||||
err = b.Delete(Locator{URL: "https://radio-t.com"}, res[0].ID)
|
||||
assert.Nil(t, err)
|
||||
|
||||
res, err = b.Find(Request{Locator: Locator{URL: "https://radio-t.com"}})
|
||||
@@ -95,6 +95,15 @@ func TestBoltDB_Vote(t *testing.T) {
|
||||
assert.Equal(t, 1, res[0].Score)
|
||||
}
|
||||
|
||||
func TestBoltDB_Count(t *testing.T) {
|
||||
defer os.Remove(testDb)
|
||||
b := prep(t)
|
||||
|
||||
c, err := b.Count(Locator{URL: "https://radio-t.com"})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 2, c)
|
||||
}
|
||||
|
||||
// makes new boltdb, put two records
|
||||
func prep(t *testing.T) *BoltDB {
|
||||
b, err := NewBoltDB(testDb)
|
||||
|
||||
@@ -46,4 +46,5 @@ type Interface interface {
|
||||
Last(locator Locator, max int) ([]Comment, error)
|
||||
Get(locator Locator, id int64) (Comment, error)
|
||||
Vote(locator Locator, commentID int64, userID string, val bool) (Comment, error)
|
||||
Count(locator Locator) (int, error)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user