add paging to rss feeds

This commit is contained in:
skkiesel 2017-05-10 15:56:03 -04:00
parent 9c39e3cd41
commit 889372dcb4
2 changed files with 62 additions and 21 deletions

View File

@ -2,7 +2,6 @@ package rss
import ( import (
"fmt" "fmt"
"log"
"strings" "strings"
"time" "time"
@ -16,12 +15,38 @@ type RSSPlugin struct {
Bot bot.Bot Bot bot.Bot
cache map[string]*cacheItem cache map[string]*cacheItem
shelfLife time.Duration shelfLife time.Duration
maxLines int
} }
type cacheItem struct { type cacheItem struct {
key string key string
data string data []string
expiration time.Time currentLine int
expiration time.Time
}
func (c *cacheItem) getCurrentPage(maxLines int) string {
if len(c.data) <= maxLines {
return strings.Join(c.data, "\n")
}
start := c.currentLine
end := start + maxLines
if end > len(c.data) {
end = len(c.data)
}
page := strings.Join(c.data[start:end], "\n")
if end - start == maxLines {
c.currentLine = end
} else {
c.currentLine = maxLines-(end-start)
page += "\n"
page += strings.Join(c.data[0:c.currentLine], "\n")
}
return page
} }
func New(bot bot.Bot) *RSSPlugin { func New(bot bot.Bot) *RSSPlugin {
@ -29,6 +54,7 @@ func New(bot bot.Bot) *RSSPlugin {
Bot: bot, Bot: bot,
cache: map[string]*cacheItem{}, cache: map[string]*cacheItem{},
shelfLife: time.Minute * 20, shelfLife: time.Minute * 20,
maxLines: 5,
} }
} }
@ -37,9 +63,8 @@ func (p *RSSPlugin) Message(message msg.Message) bool {
numTokens := len(tokens) numTokens := len(tokens)
if numTokens == 2 && strings.ToLower(tokens[0]) == "rss" { if numTokens == 2 && strings.ToLower(tokens[0]) == "rss" {
if data, ok := p.cache[strings.ToLower(tokens[1])]; ok && time.Now().Before(data.expiration) { if item, ok := p.cache[strings.ToLower(tokens[1])]; ok && time.Now().Before(item.expiration) {
log.Printf("rss cache hit") p.Bot.SendMessage(message.Channel, item.getCurrentPage(p.maxLines))
p.Bot.SendMessage(message.Channel, data.data)
return true return true
} else { } else {
fp := gofeed.NewParser() fp := gofeed.NewParser()
@ -48,18 +73,20 @@ func (p *RSSPlugin) Message(message msg.Message) bool {
p.Bot.SendMessage(message.Channel, fmt.Sprintf("RSS error: %s", err.Error())) p.Bot.SendMessage(message.Channel, fmt.Sprintf("RSS error: %s", err.Error()))
return true return true
} }
response := feed.Title item := &cacheItem{
for _, item := range feed.Items { key: strings.ToLower(tokens[1]),
response += fmt.Sprintf("\n%s", item.Title) data: []string{feed.Title},
expiration: time.Now().Add(p.shelfLife),
currentLine: 0,
} }
p.cache[strings.ToLower(tokens[1])] = &cacheItem{ for _, feedItem := range feed.Items {
key: strings.ToLower(tokens[1]), item.data = append(item.data, feedItem.Title)
data: response,
expiration: time.Now().Add(p.shelfLife),
} }
p.Bot.SendMessage(message.Channel, response) p.cache[strings.ToLower(tokens[1])] = item
p.Bot.SendMessage(message.Channel, item.getCurrentPage(p.maxLines))
return true return true
} }
} }

View File

@ -1,6 +1,7 @@
package rss package rss
import ( import (
"fmt"
"strings" "strings"
"testing" "testing"
@ -32,13 +33,26 @@ func TestRSS(t *testing.T) {
assert.True(t, res) assert.True(t, res)
} }
func TestRSSCache(t *testing.T) { func TestRSSPaging(t *testing.T) {
mb := bot.NewMockBot() mb := bot.NewMockBot()
c := New(mb) c := New(mb)
assert.NotNil(t, c) assert.NotNil(t, c)
res := c.Message(makeMessage("!rss http://rss.cnn.com/rss/edition.rss")) for i := 0; i < 20; i++ {
assert.True(t, res) res := c.Message(makeMessage("!rss http://rss.cnn.com/rss/edition.rss"))
res = c.Message(makeMessage("!rss http://rss.cnn.com/rss/edition.rss")) assert.True(t, res)
assert.Len(t, mb.Messages, 2) }
assert.True(t, res)
assert.Len(t, mb.Messages, 20)
for i := 0; i < len(mb.Messages); i++ {
if i > 0 && strings.Contains(mb.Messages[i], "CNN.com - RSS Channel - Intl Homepage - News") {
fmt.Println("----------------")
fmt.Println(mb.Messages[i])
fmt.Println("----------------")
break
}
fmt.Println("----------------")
fmt.Println(mb.Messages[i])
fmt.Println("----------------")
}
} }