diff --git a/backend/app/rest/api/rss.go b/backend/app/rest/api/rss.go index b2d1fe3c..beba5aa9 100644 --- a/backend/app/rest/api/rss.go +++ b/backend/app/rest/api/rss.go @@ -159,6 +159,7 @@ func (s *rss) toRssFeed(url string, comments []store.Comment, description string parentComment, err := s.dataService.Get(c.Locator, c.ParentID, store.User{}) if err == nil { f.Title = fmt.Sprintf("%s > %s", c.User.Name, parentComment.User.Name) + f.Description = f.Description + "

" + parentComment.Snippet(300) + "" } else { log.Printf("[WARN] failed to get info about parent comment, %s", err) } diff --git a/backend/app/rest/api/rss_test.go b/backend/app/rest/api/rss_test.go index 306de8b9..fd368dc3 100644 --- a/backend/app/rest/api/rss_test.go +++ b/backend/app/rest/api/rss_test.go @@ -161,7 +161,7 @@ func TestServer_RssWithReply(t *testing.T) { developer one > developer one https://radio-t.com/blah10#remark42__comment-comment-id-2 - xyz test + xyz test<p><summary>test 123</summary> developer one comment-id-2 %s @@ -247,7 +247,7 @@ func TestServer_RssReplies(t *testing.T) { user3 > user1 https://radio-t.com/blah1#remark42__comment-comment-3 - reply to c1 from user3 + reply to c1 from user3<p><summary>c1</summary> user3 comment-3 %s @@ -255,7 +255,7 @@ func TestServer_RssReplies(t *testing.T) { user2 > user1 https://radio-t.com/blah1#remark42__comment-comment-2 - reply to c1 from user2 + reply to c1 from user2<p><summary>c1</summary> user2 comment-2 %s diff --git a/backend/app/store/comment.go b/backend/app/store/comment.go index a6241184..c7ac03ca 100644 --- a/backend/app/store/comment.go +++ b/backend/app/store/comment.go @@ -3,6 +3,7 @@ package store import ( "html/template" "regexp" + "strings" "time" "github.com/microcosm-cc/bluemonday" @@ -66,6 +67,7 @@ const ( // Maximum length for URL text shortening. const shortURLLen = 48 +const snippetLen = 200 // PrepareUntrusted pre-processes a comment received from untrusted source by clearing all // autogen fields and reset everything users not supposed to provide @@ -107,3 +109,24 @@ func (c *Comment) Sanitize() { c.User.Name = template.HTMLEscapeString(c.User.Name) c.User.Picture = p.Sanitize(c.User.Picture) } + +// Snippet from comment's text +func (c *Comment) Snippet(limit int) string { + if limit <= 0 { + limit = snippetLen + } + cleanText := strings.Replace(c.Text, "\n", " ", -1) + size := len([]rune(cleanText)) + if size < limit { + return cleanText + } + snippet := []rune(cleanText)[:size] + // go back in snippet and found the first space + for i := len(snippet) - 1; i >= 0; i-- { + if snippet[i] == ' ' { + snippet = snippet[:i] + break + } + } + return string(snippet) + " ..." +} diff --git a/backend/app/store/comment_test.go b/backend/app/store/comment_test.go index f84f570f..1e619735 100644 --- a/backend/app/store/comment_test.go +++ b/backend/app/store/comment_test.go @@ -1,6 +1,7 @@ package store import ( + "strconv" "testing" "time" @@ -128,3 +129,25 @@ func TestComment_SetDeletedHard(t *testing.T) { assert.False(t, comment.Pin) assert.Equal(t, User{Name: "deleted", ID: "deleted", Picture: "", Admin: false, Blocked: false, IP: ""}, comment.User) } + +func TestComment_Snippet(t *testing.T) { + tbl := []struct { + limit int + inp string + out string + }{ + {0, "", ""}, + {-1, "test\nblah", "test blah"}, + {5, "test\nblah", "test ..."}, + {5, "xyz12345 xxx", "xyz12345 ..."}, + {10, "xyz12345 xxx\ntest 123456", "xyz12345 xxx test ..."}, + } + + for i, tt := range tbl { + t.Run(strconv.Itoa(i), func(t *testing.T) { + c := Comment{Text: tt.inp} + out := c.Snippet(tt.limit) + assert.Equal(t, tt.out, out) + }) + } +}