basic json feed parser

This commit is contained in:
Nazar Kanaev 2021-03-19 16:22:37 +00:00
parent 0a9beddef9
commit a895775f81
3 changed files with 141 additions and 0 deletions

77
src/feed/json.go Normal file
View File

@ -0,0 +1,77 @@
package feed
import (
"encoding/json"
"io"
)
type jsonFeed struct {
Version string `json:"version"`
Title string `json:"title"`
SiteURL string `json:"home_page_url"`
FeedURL string `json:"feed_url"`
Items []jsonItem `json:"items"`
}
type jsonItem struct {
ID string `json:"id"`
URL string `json:"url"`
Title string `json:"title"`
Summary string `json:"summary"`
Text string `json:"content_text"`
HTML string `json:"content_html"`
DatePublished string `json:"date_published"`
DateModified string `json:"date_modified"`
Attachments []jsonAttachment `json:"attachments"`
}
type jsonAttachment struct {
URL string `json:"url"`
MimeType string `json:"mime_type"`
Title string `json:"title"`
Size int64 `json:"size_in_bytes"`
Duration int `json:"duration_in_seconds"`
}
func first(vals ...string) string {
for _, val := range vals {
if len(val) > 0 {
return val
}
}
return ""
}
func (f *jsonFeed) convert(base string) *Feed {
feed := &Feed{
Title: f.Title,
SiteURL: f.SiteURL,
FeedURL: f.FeedURL,
}
for _, item := range f.Items {
//date := item.DatePublished
content := first(item.HTML, item.Text, item.Summary)
imageUrl := ""
podcastUrl := ""
feed.Items = append(feed.Items, Item{
GUID: item.ID,
Date: nil,
URL: item.URL,
Title: item.Title,
Content: content,
ImageURL: imageUrl,
PodcastURL: podcastUrl,
})
}
return feed
}
func ParseJSON(data io.Reader, base string) (*Feed, error) {
feed := new(jsonFeed)
decoder := json.NewDecoder(data)
if err := decoder.Decode(&feed); err != nil {
return nil, err
}
return feed.convert(base), nil
}

43
src/feed/json_test.go Normal file
View File

@ -0,0 +1,43 @@
package feed
import (
"reflect"
"strings"
"testing"
)
func TestJSONFeed(t *testing.T) {
have, _ := ParseJSON(strings.NewReader(`{
"version": "https://jsonfeed.org/version/1",
"title": "My Example Feed",
"home_page_url": "https://example.org/",
"feed_url": "https://example.org/feed.json",
"items": [
{
"id": "2",
"content_text": "This is a second item.",
"url": "https://example.org/second-item"
},
{
"id": "1",
"content_html": "<p>Hello, world!</p>",
"url": "https://example.org/initial-post"
}
]
}`), "https://example.com")
want := &Feed{
Title: "My Example Feed",
SiteURL: "https://example.org/",
FeedURL: "https://example.org/feed.json",
Items: []Item{
{GUID: "2", Content: "This is a second item.", URL: "https://example.org/second-item"},
{GUID: "1", Content: "<p>Hello, world!</p>", URL: "https://example.org/initial-post"},
},
}
if !reflect.DeepEqual(want, have) {
t.Logf("want: %#v", want)
t.Logf("have: %#v", have)
t.Fatal("invalid json")
}
}

21
src/feed/models.go Normal file
View File

@ -0,0 +1,21 @@
package feed
import "time"
type Feed struct {
Title string
SiteURL string
FeedURL string
Items []Item
}
type Item struct {
GUID string
Date *time.Time
URL string
Title string
Content string
ImageURL string
PodcastURL string
}