diff --git a/README.md b/README.md index fe3b5060..ca3e5457 100644 --- a/README.md +++ b/README.md @@ -171,7 +171,13 @@ Sort can be `time` or `score`. Supported sort order with prefix -/+, i.e. `-time - `GET /api/v1/id/{id}?site=site-id` - get comment by `comment id` - `GET /api/v1/comments?site=site-id&user=id` - get comment by `user id` - `GET /api/v1/count?site=site-id&url=post-url` - get comment's count for `{url}` -- `GET /api/v1/list?site=site-id` - list commented posts +- `GET /api/v1/list?site=site-id` - list commented posts, returns array or `PostInfo` + ``` + type PostInfo struct { + URL string `json:"url"` + Count int `json:"count"` + } + ``` - `GET /api/v1/user` - get user info, _auth required_ - `PUT /api/v1/vote/{id}?site=site-id&url=post-url&vote=1` - vote for comment. `vote`=1 will increase score, -1 decrease. _auth required_ diff --git a/app/rest/server.go b/app/rest/server.go index b1159a8b..03a55654 100644 --- a/app/rest/server.go +++ b/app/rest/server.go @@ -277,10 +277,11 @@ func (s *Server) commentByIDCtrl(w http.ResponseWriter, r *http.Request) { id := chi.URLParam(r, "id") siteID := r.URL.Query().Get("site") + url := r.URL.Query().Get("url") - log.Printf("[DEBUG] get comments by id %s, %s", id, siteID) + log.Printf("[DEBUG] get comments by id %s, %s %s", id, siteID, url) - comment, err := s.DataService.GetByID(siteID, id) + comment, err := s.DataService.Get(store.Locator{SiteID: siteID, URL: url}, id) if err != nil { common.SendErrorJSON(w, r, http.StatusInternalServerError, err, "can't get comment by id") return @@ -293,11 +294,12 @@ func (s *Server) commentByIDCtrl(w http.ResponseWriter, r *http.Request) { func (s *Server) findUserCommentsCtrl(w http.ResponseWriter, r *http.Request) { userID := r.URL.Query().Get("user") + siteID := r.URL.Query().Get("site") - log.Printf("[DEBUG] get comments by userID %s", userID) + log.Printf("[DEBUG] get comments for userID %s, %s", userID, siteID) data, err := s.respCache.get(r.URL.String(), time.Hour, func() ([]byte, error) { - comments, e := s.DataService.GetByUser(r.URL.Query().Get("site"), userID) + comments, e := s.DataService.User(siteID, userID) if e != nil { return nil, e } diff --git a/app/store/bolt.go b/app/store/bolt.go index 5ad5c86d..25dbafcd 100644 --- a/app/store/bolt.go +++ b/app/store/bolt.go @@ -25,11 +25,14 @@ type BoltDB struct { } const ( + // top level buckets lastBucketName = "last" userBucketName = "users" blocksBucketName = "block" - lastLimit = 1000 - userLimit = 100 + + // limits + lastLimit = 1000 + userLimit = 100 ) // BoltSite defines single site param @@ -198,43 +201,6 @@ func (b *BoltDB) Find(locator Locator, sortFld string) (comments []Comment, err return comments, err } -// GetByID returns comment by id across posts -func (b *BoltDB) GetByID(siteID string, commentID string) (comment Comment, err error) { - - bdb, err := b.db(siteID) - if err != nil { - return comment, err - } - - err = bdb.View(func(tx *bolt.Tx) error { - - lastBucket := tx.Bucket([]byte(lastBucketName)) - if lastBucket == nil { - return errors.Errorf("no bucket %s in store", lastBucketName) - } - - c := lastBucket.Cursor() - for k, v := c.Last(); k != nil; k, v = c.Prev() { - url, foundID, e := refFromValue(v).parseValue() - if e != nil { - return e - } - - if foundID == commentID { - urlBucket := tx.Bucket([]byte(url)) - if urlBucket == nil { - return errors.Errorf("no bucket %s in store", url) - } - comment, e = b.load(urlBucket, []byte(commentID)) - return e - } - } - return errors.Errorf("no comment id %s", commentID) - }) - - return comment, err -} - // Last returns up to max last comments for given siteID func (b *BoltDB) Last(siteID string, max int) (comments []Comment, err error) { @@ -370,9 +336,9 @@ func (b BoltDB) List(siteID string) (list []PostInfo, err error) { return list, err } -// GetByUser extracts all comments for given site and given userID +// User extracts all comments for given site and given userID // "users" bucket has sub-bucket for each userID, and keeps it as ts:ref -func (b *BoltDB) GetByUser(siteID string, userID string) (comments []Comment, err error) { +func (b *BoltDB) User(siteID string, userID string) (comments []Comment, err error) { comments = []Comment{} commentRefs := []string{} diff --git a/app/store/bolt_test.go b/app/store/bolt_test.go index d32939a9..64fa7056 100644 --- a/app/store/bolt_test.go +++ b/app/store/bolt_test.go @@ -52,11 +52,11 @@ func TestBoltDB_GetByID(t *testing.T) { assert.Nil(t, err) assert.Equal(t, 2, len(res)) - comment, err := b.GetByID("radio-t", res[1].ID) + comment, err := b.Get(Locator{URL: "https://radio-t.com", SiteID: "radio-t"}, res[1].ID) assert.Nil(t, err) assert.Equal(t, "some text2", comment.Text) - comment, err = b.GetByID("radio-t", "1234567") + comment, err = b.Get(Locator{URL: "https://radio-t.com", SiteID: "radio-t"}, "1234567") assert.NotNil(t, err) } diff --git a/app/store/service_test.go b/app/store/service_test.go index 07c9007b..e41bf656 100644 --- a/app/store/service_test.go +++ b/app/store/service_test.go @@ -39,7 +39,6 @@ func TestService_Vote(t *testing.T) { assert.Equal(t, 2, len(res)) assert.Equal(t, 0, res[0].Score) assert.Equal(t, map[string]bool{}, res[0].Votes) - } func TestBoltDB_Pin(t *testing.T) { @@ -55,13 +54,13 @@ func TestBoltDB_Pin(t *testing.T) { err = b.SetPin(Locator{URL: "https://radio-t.com", SiteID: "radio-t"}, res[0].ID, true) assert.Nil(t, err) - c, err := b.GetByID("radio-t", res[0].ID) + c, err := b.Get(Locator{URL: "https://radio-t.com", SiteID: "radio-t"}, res[0].ID) assert.Nil(t, err) assert.Equal(t, true, c.Pin) err = b.SetPin(Locator{URL: "https://radio-t.com", SiteID: "radio-t"}, res[0].ID, false) assert.Nil(t, err) - c, err = b.GetByID("radio-t", res[0].ID) + c, err = b.Get(Locator{URL: "https://radio-t.com", SiteID: "radio-t"}, res[0].ID) assert.Nil(t, err) assert.Equal(t, false, c.Pin) } @@ -81,7 +80,7 @@ func TestBoltDB_EditComment(t *testing.T) { assert.Equal(t, "my edit", comment.Edit.Summary) assert.Equal(t, "xxx", comment.Text) - c, err := b.GetByID("radio-t", res[0].ID) + c, err := b.Get(Locator{URL: "https://radio-t.com", SiteID: "radio-t"}, res[0].ID) assert.Nil(t, err) assert.Equal(t, "my edit", c.Edit.Summary) assert.Equal(t, "xxx", c.Text) diff --git a/app/store/store.go b/app/store/store.go index 7f622381..cf7c7beb 100644 --- a/app/store/store.go +++ b/app/store/store.go @@ -65,13 +65,12 @@ type Interface interface { // Accessor defines all usual access ops avail for regular user type Accessor interface { - Create(comment Comment) (commentID string, err error) // create new comment, avoid dups by ID - Get(locator Locator, commentID string) (comment Comment, err error) // get comment by ID + Create(comment Comment) (commentID string, err error) // create new comment, avoid dups by id + Get(locator Locator, commentID string) (comment Comment, err error) // get comment by id Put(locator Locator, comment Comment) error // update comment, mutable parts only - Find(locator Locator, sort string) ([]Comment, error) // find comments for request - Last(siteID string, max int) ([]Comment, error) // last comments for given site - GetByID(siteID string, commentID string) (Comment, error) // comment by id - GetByUser(siteID string, userID string) ([]Comment, error) // comment by user + Find(locator Locator, sort string) ([]Comment, error) // find comments for locator + Last(siteID string, max int) ([]Comment, error) // last comments for given site, sorted by time + User(siteID string, userID string) ([]Comment, error) // comments by user, sorted by time Count(locator Locator) (int, error) // number of comments for the post List(siteID string) ([]PostInfo, error) // list of commented posts }