From 6a3d6c01730647f9274f0e28d74b4bd7b5e73303 Mon Sep 17 00:00:00 2001 From: Umputun Date: Mon, 19 Feb 2018 13:00:08 -0600 Subject: [PATCH] add skip support for list of commented posts --- README.md | 2 +- app/migrator/remark.go | 2 +- app/rest/api/rest.go | 13 ++++++++----- app/store/bolt.go | 8 +++++++- app/store/bolt_test.go | 8 ++++++-- app/store/store.go | 2 +- remark.rest | 2 +- 7 files changed, 25 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index ccb3f0cd..2a56bc05 100644 --- a/README.md +++ b/README.md @@ -190,7 +190,7 @@ Sort can be `time` or `score`. Supported sort order with prefix -/+, i.e. `-time }{} ``` - `GET /api/v1/count?site=site-id&url=post-url` - get comment's count for `{url}` -- `GET /api/v1/list?site=site-id&limit=5` - list commented posts, returns array or `PostInfo`, limit=0 will return all posts +- `GET /api/v1/list?site=site-id&limit=5&skip=2` - list commented posts, returns array or `PostInfo`, limit=0 will return all posts ```go type PostInfo struct { URL string `json:"url"` diff --git a/app/migrator/remark.go b/app/migrator/remark.go index 25d3838a..77bf8046 100644 --- a/app/migrator/remark.go +++ b/app/migrator/remark.go @@ -19,7 +19,7 @@ type Remark struct { // Export all comments to writer as json strings. Each comment is one string, separated by "\n" func (r *Remark) Export(w io.Writer, siteID string) error { - topics, err := r.DataStore.List(siteID, 0) + topics, err := r.DataStore.List(siteID, 0, 0) if err != nil { return err } diff --git a/app/rest/api/rest.go b/app/rest/api/rest.go index db35eef9..be5a374c 100644 --- a/app/rest/api/rest.go +++ b/app/rest/api/rest.go @@ -375,18 +375,21 @@ func (s *Rest) countCtrl(w http.ResponseWriter, r *http.Request) { render.JSON(w, r, JSON{"count": count, "locator": locator}) } -// GET /list?site=siteID&limit=50 - list posts with comments +// GET /list?site=siteID&limit=50&skip=10 - list posts with comments func (s *Rest) listCtrl(w http.ResponseWriter, r *http.Request) { siteID := r.URL.Query().Get("site") - limit := 0 - limitStr := r.URL.Query().Get("limit") - if v, err := strconv.Atoi(limitStr); err == nil { + limit, skip := 0, 0 + + if v, err := strconv.Atoi(r.URL.Query().Get("limit")); err == nil { limit = v } + if v, err := strconv.Atoi(r.URL.Query().Get("skip")); err == nil { + skip = v + } data, err := s.Cache.Get(rest.URLKey(r), 8*time.Hour, func() ([]byte, error) { - posts, e := s.DataService.List(siteID, limit) + posts, e := s.DataService.List(siteID, limit, skip) if e != nil { return nil, e } diff --git a/app/store/bolt.go b/app/store/bolt.go index 7442bc16..ca6a865c 100644 --- a/app/store/bolt.go +++ b/app/store/bolt.go @@ -340,7 +340,7 @@ func (b *BoltDB) Blocked(siteID string) (users []BlockedUser, err error) { // List returns list of all commented posts with counters // uses count bucket to get number of comments -func (b BoltDB) List(siteID string, limit int) (list []PostInfo, err error) { +func (b BoltDB) List(siteID string, limit, skip int) (list []PostInfo, err error) { bdb, err := b.db(siteID) if err != nil { @@ -351,7 +351,12 @@ func (b BoltDB) List(siteID string, limit int) (list []PostInfo, err error) { postsBkt := tx.Bucket([]byte(postsBucketName)) c := postsBkt.Cursor() + n := 0 for k, _ := c.Last(); k != nil; k, _ = c.Prev() { + n++ + if skip > 0 && n <= skip { + continue + } postURL := string(k) count, e := b.count(tx, postURL, 0) if e != nil { @@ -361,6 +366,7 @@ func (b BoltDB) List(siteID string, limit int) (list []PostInfo, err error) { if limit > 0 && len(list) >= limit { break } + } return nil }) diff --git a/app/store/bolt_test.go b/app/store/bolt_test.go index 58785e2f..5303679b 100644 --- a/app/store/bolt_test.go +++ b/app/store/bolt_test.go @@ -160,13 +160,17 @@ func TestBoltDB_List(t *testing.T) { _, err := b.Create(comment) assert.Nil(t, err) - res, err := b.List("radio-t", 0) + res, err := b.List("radio-t", 0, 0) assert.Nil(t, err) assert.Equal(t, []PostInfo{{URL: "https://radio-t.com/2", Count: 1}, {URL: "https://radio-t.com", Count: 2}}, res) - res, err = b.List("radio-t", 1) + res, err = b.List("radio-t", 1, 0) assert.Nil(t, err) assert.Equal(t, []PostInfo{{URL: "https://radio-t.com/2", Count: 1}}, res) + + res, err = b.List("radio-t", 1, 1) + assert.Nil(t, err) + assert.Equal(t, []PostInfo{{URL: "https://radio-t.com", Count: 2}}, res) } func TestBoltDB_GetForUser(t *testing.T) { diff --git a/app/store/store.go b/app/store/store.go index 93fb901f..cfaf84f2 100644 --- a/app/store/store.go +++ b/app/store/store.go @@ -22,7 +22,7 @@ type Accessor interface { Last(siteID string, max int) ([]Comment, error) // last comments for given site, sorted by time User(siteID string, userID string) ([]Comment, int, error) // comments by user, sorted by time Count(locator Locator) (int, error) // number of comments for the post - List(siteID string, limit int) ([]PostInfo, error) // list of commented posts + List(siteID string, limit int, skip int) ([]PostInfo, error) // list of commented posts } // Admin defines all store ops avail for admin only diff --git a/remark.rest b/remark.rest index 6bea4403..2d0caea0 100644 --- a/remark.rest +++ b/remark.rest @@ -63,7 +63,7 @@ GET {{host}}/api/v1/comments?site=remark&user=disqus_umputun GET {{host}}/api/v1/count?site=remark&url=https://radio-t.com/p/2017/12/16/podcast-576/ ### list commented posts -GET {{host}}/api/v1/list?site=remark +GET {{host}}/api/v1/list?site=remark&limit=10&skip=5 ### get config GET {{host}}/api/v1/config