move reply retrieval to service, fix incorrect RSS title for reply
This commit is contained in:
+26
-21
@@ -23,10 +23,10 @@ type rssStore interface {
|
||||
Find(locator store.Locator, sort string, user store.User) ([]store.Comment, error)
|
||||
Last(siteID string, limit int, since time.Time, user store.User) ([]store.Comment, error)
|
||||
Get(locator store.Locator, commentID string, user store.User) (store.Comment, error)
|
||||
UserReplies(siteID, userID string, limit int, duration time.Duration) ([]store.Comment, string, error)
|
||||
}
|
||||
|
||||
const maxRssItems = 20
|
||||
const maxLastCommentsReply = 5000
|
||||
const maxReplyDuration = 31 * 24 * time.Hour
|
||||
|
||||
// ui uses links like <post-url>#remark42__comment-<comment-id>
|
||||
@@ -100,31 +100,36 @@ func (s *rss) repliesCtrl(w http.ResponseWriter, r *http.Request) {
|
||||
siteID := r.URL.Query().Get("site")
|
||||
log.Printf("[DEBUG] get rss replies to user %s for site %s", userID, siteID)
|
||||
|
||||
userName := ""
|
||||
key := cache.NewKey(siteID).ID(URLKey(r)).Scopes(siteID, lastCommentsScope)
|
||||
data, err := s.cache.Get(key, func() (res []byte, e error) {
|
||||
comments, e := s.dataService.Last(siteID, maxLastCommentsReply, time.Time{}, rest.GetUserOrEmpty(r))
|
||||
|
||||
//comments, e := s.dataService.UserReplies(siteID, userID, maxRssItems, maxReplyDuration)
|
||||
//if e != nil {
|
||||
// return nil, errors.Wrap(e, "can't get last comments")
|
||||
//}
|
||||
//replies := []store.Comment{}
|
||||
//for _, c := range comments {
|
||||
// if len(replies) > maxRssItems || c.Timestamp.Add(maxReplyDuration).Before(time.Now()) {
|
||||
// break
|
||||
// }
|
||||
// if c.User.ID != userID {
|
||||
// userName = c.User.Name
|
||||
// }
|
||||
// if c.ParentID != "" && !c.Deleted && c.User.ID != userID { // not interested in replies to yourself
|
||||
// var pc store.Comment
|
||||
// if pc, e = s.dataService.Get(c.Locator, c.ParentID, rest.GetUserOrEmpty(r)); e != nil {
|
||||
// return nil, errors.Wrap(e, "can't get parent comment")
|
||||
// }
|
||||
// if pc.User.ID == userID {
|
||||
// replies = append(replies, c)
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
replies, userName, e := s.dataService.UserReplies(siteID, userID, maxRssItems, maxReplyDuration)
|
||||
if e != nil {
|
||||
return nil, errors.Wrap(e, "can't get last comments")
|
||||
}
|
||||
replies := []store.Comment{}
|
||||
for _, c := range comments {
|
||||
if len(replies) > maxRssItems || c.Timestamp.Add(maxReplyDuration).Before(time.Now()) {
|
||||
break
|
||||
}
|
||||
if c.User.ID != userID {
|
||||
userName = c.User.Name
|
||||
}
|
||||
if c.ParentID != "" && !c.Deleted && c.User.ID != userID { // not interested in replies to yourself
|
||||
var pc store.Comment
|
||||
if pc, e = s.dataService.Get(c.Locator, c.ParentID, rest.GetUserOrEmpty(r)); e != nil {
|
||||
return nil, errors.Wrap(e, "can't get parent comment")
|
||||
}
|
||||
if pc.User.ID == userID {
|
||||
replies = append(replies, c)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
feed, e := s.toRssFeed(siteID, replies, "replies to "+userName)
|
||||
if e != nil {
|
||||
|
||||
@@ -242,7 +242,7 @@ func TestServer_RssReplies(t *testing.T) {
|
||||
<channel>
|
||||
<title>Remark42 comments</title>
|
||||
<link>radio-t</link>
|
||||
<description>replies to user2</description>
|
||||
<description>replies to user1</description>
|
||||
<pubDate>%s</pubDate>
|
||||
<item>
|
||||
<title>user3 > user1</title>
|
||||
|
||||
@@ -64,11 +64,13 @@ type PostMetaData struct {
|
||||
}
|
||||
|
||||
const defaultCommentMaxSize = 2000
|
||||
const maxLastCommentsReply = 1000
|
||||
const maxLastCommentsReply = 5000
|
||||
|
||||
// UnlimitedVotes doesn't restrict MaxVotes
|
||||
const UnlimitedVotes = -1
|
||||
|
||||
var nonAdminUser = store.User{}
|
||||
|
||||
// ErrRestrictedWordsFound returned in case comment text contains restricted words
|
||||
var ErrRestrictedWordsFound = errors.New("comment contains restricted words")
|
||||
|
||||
@@ -351,6 +353,42 @@ func (s *DataStore) HasReplies(comment store.Comment) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// UserReplies returns list of all comments replied to given user
|
||||
func (s *DataStore) UserReplies(siteID, userID string, limit int, duration time.Duration) ([]store.Comment, string, error) {
|
||||
|
||||
comments, e := s.Last(siteID, maxLastCommentsReply, time.Time{}, nonAdminUser)
|
||||
if e != nil {
|
||||
return nil, "", errors.Wrap(e, "can't get last comments")
|
||||
}
|
||||
replies := []store.Comment{}
|
||||
|
||||
// get a comment for given userID in order to retrieve name
|
||||
userName := ""
|
||||
if cc, err := s.User(siteID, userID, 1, 0, nonAdminUser); err == nil && len(cc) > 0 {
|
||||
userName = cc[0].User.Name
|
||||
}
|
||||
|
||||
// collect replies
|
||||
for _, c := range comments {
|
||||
|
||||
if len(replies) > limit || time.Since(c.Timestamp) > duration {
|
||||
break
|
||||
}
|
||||
|
||||
if c.ParentID != "" && !c.Deleted && c.User.ID != userID { // not interested in replies to yourself
|
||||
var pc store.Comment
|
||||
if pc, e = s.Get(c.Locator, c.ParentID, nonAdminUser); e != nil {
|
||||
return nil, "", errors.Wrap(e, "can't get parent comment")
|
||||
}
|
||||
if pc.User.ID == userID {
|
||||
replies = append(replies, c)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return replies, userName, nil
|
||||
}
|
||||
|
||||
// SetTitle puts title from the locator.URL page and overwrites any existing title
|
||||
func (s *DataStore) SetTitle(locator store.Locator, commentID string) (comment store.Comment, err error) {
|
||||
if s.TitleExtractor == nil {
|
||||
|
||||
@@ -663,6 +663,83 @@ func TestService_HasReplies(t *testing.T) {
|
||||
assert.True(t, b.HasReplies(comment))
|
||||
}
|
||||
|
||||
func TestService_UserReplies(t *testing.T) {
|
||||
|
||||
defer teardown(t)
|
||||
|
||||
// two comments for https://radio-t.com, no reply
|
||||
b := DataStore{Interface: prepStoreEngine(t),
|
||||
AdminStore: admin.NewStaticStore("secret 123", []string{"user2"}, "user@email.com")}
|
||||
|
||||
c1 := store.Comment{
|
||||
ID: "comment-id-1",
|
||||
Text: "test 123",
|
||||
Locator: store.Locator{URL: "https://radio-t.com/blah10", SiteID: "radio-t"},
|
||||
User: store.User{ID: "u1", Name: "developer one u1"},
|
||||
}
|
||||
c2 := store.Comment{
|
||||
ID: "comment-id-2",
|
||||
ParentID: "comment-id-1",
|
||||
Text: "xyz test",
|
||||
Locator: store.Locator{URL: "https://radio-t.com/blah10", SiteID: "radio-t"},
|
||||
User: store.User{ID: "u2", Name: "developer one u2"},
|
||||
}
|
||||
c3 := store.Comment{
|
||||
ID: "comment-id-3",
|
||||
ParentID: "comment-id-1",
|
||||
Text: "xyz test",
|
||||
Locator: store.Locator{URL: "https://radio-t.com/blah10", SiteID: "radio-t"},
|
||||
User: store.User{ID: "u2", Name: "developer one u3"},
|
||||
}
|
||||
c4 := store.Comment{
|
||||
ID: "comment-id-4",
|
||||
ParentID: "",
|
||||
Text: "xyz test",
|
||||
Locator: store.Locator{URL: "https://radio-t.com/blah10", SiteID: "radio-t"},
|
||||
User: store.User{ID: "u4", Name: "developer one u4"},
|
||||
}
|
||||
|
||||
c5 := store.Comment{
|
||||
ID: "comment-id-5",
|
||||
ParentID: "comment-id-1",
|
||||
Text: "xyz test",
|
||||
Locator: store.Locator{URL: "https://radio-t.com/blah10", SiteID: "radio-t"},
|
||||
User: store.User{ID: "u2", Name: "developer one u2"},
|
||||
}
|
||||
|
||||
_, err := b.Create(c1)
|
||||
require.NoError(t, err)
|
||||
_, err = b.Create(c2)
|
||||
require.NoError(t, err)
|
||||
_, err = b.Create(c3)
|
||||
require.NoError(t, err)
|
||||
_, err = b.Create(c4)
|
||||
require.NoError(t, err)
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
_, err = b.Create(c5)
|
||||
require.NoError(t, err)
|
||||
|
||||
cc, u, err := b.UserReplies("radio-t", "u1", 10, time.Hour)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 3, len(cc), "3 replies to u1")
|
||||
assert.Equal(t, "developer one u1", u)
|
||||
|
||||
cc, u, err = b.UserReplies("radio-t", "u1", 10, time.Millisecond*50)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 1, len(cc), "1 reply to u1 in last 90ms")
|
||||
assert.Equal(t, "developer one u1", u)
|
||||
|
||||
cc, u, err = b.UserReplies("radio-t", "u2", 10, time.Hour)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 0, len(cc), "0 replies to u2")
|
||||
assert.Equal(t, "developer one u2", u)
|
||||
|
||||
cc, u, err = b.UserReplies("radio-t", "uxxx", 10, time.Hour)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 0, len(cc), "0 replies to uxxx")
|
||||
}
|
||||
|
||||
func TestService_Find(t *testing.T) {
|
||||
defer teardown(t)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user