91 lines
1.6 KiB
Go
91 lines
1.6 KiB
Go
package rss
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"local/rssmon3/config"
|
|
"net/http"
|
|
"net/url"
|
|
"regexp"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/mmcdole/gofeed"
|
|
)
|
|
|
|
const nsItems = "nsItems"
|
|
|
|
type Item struct {
|
|
Title string
|
|
Link string
|
|
Content string
|
|
TS time.Time
|
|
}
|
|
|
|
func newItem(i *gofeed.Item, contentFilter string) (*Item, error) {
|
|
item := &Item{
|
|
Title: i.Title,
|
|
Link: i.Link,
|
|
Content: i.Content,
|
|
TS: latestTSPtr(i.UpdatedParsed, i.PublishedParsed),
|
|
}
|
|
|
|
if item.Content == "" {
|
|
item.Content = i.Description
|
|
}
|
|
if item.Content == "" {
|
|
resp, err := http.Get(item.Link)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer resp.Body.Close()
|
|
b, err := ioutil.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
item.Content = string(b)
|
|
}
|
|
if unescaped, err := url.QueryUnescape(item.Content); err == nil {
|
|
item.Content = unescaped
|
|
}
|
|
|
|
if contentFilter == "" {
|
|
contentFilter = ".*"
|
|
}
|
|
item.Content = strings.Join(regexp.MustCompile(contentFilter).FindAllString(item.Content, -1), "<br>")
|
|
|
|
item.Content = fmt.Sprintf(`<a href="%s">%s</a><br>%s`, item.Link, item.Title, item.Content)
|
|
|
|
return item, nil
|
|
}
|
|
|
|
func (i *Item) Encode() ([]byte, error) {
|
|
return config.Encode(i)
|
|
}
|
|
|
|
func (i *Item) Decode(b []byte) error {
|
|
return config.Decode(b, i)
|
|
}
|
|
|
|
func (i *Item) save() error {
|
|
db := config.Values().DB
|
|
b, err := i.Encode()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return db.Set(i.Link, b, nsItems)
|
|
}
|
|
|
|
func (i *Item) load() error {
|
|
if i.Link == "" {
|
|
return errors.New("cannot load nil item")
|
|
}
|
|
db := config.Values().DB
|
|
b, err := db.Get(i.Link, nsItems)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return config.Decode(b, i)
|
|
}
|