2022-05-03 17:14:37 -04:00
|
|
|
package parser
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/xml"
|
|
|
|
"fmt"
|
|
|
|
)
|
|
|
|
|
|
|
|
type FeedType string
|
|
|
|
|
|
|
|
const (
|
|
|
|
Rss FeedType = "rss"
|
|
|
|
Atom FeedType = "atom"
|
|
|
|
)
|
|
|
|
|
|
|
|
type FeedEntry struct {
|
|
|
|
Link string
|
|
|
|
Content string
|
|
|
|
}
|
|
|
|
|
|
|
|
func ParseFeed(feedType FeedType, data []byte) ([]FeedEntry, error) {
|
|
|
|
switch feedType {
|
|
|
|
case Rss:
|
|
|
|
return parseRss(data)
|
|
|
|
case Atom:
|
|
|
|
return parseAtom(data)
|
|
|
|
}
|
2022-06-21 21:32:16 -04:00
|
|
|
return nil, fmt.Errorf("unknown feed type: %s", feedType)
|
2022-05-03 17:14:37 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
func parseAtom(data []byte) ([]FeedEntry, error) {
|
|
|
|
v := struct {
|
|
|
|
Items []struct {
|
|
|
|
Link struct {
|
|
|
|
Href string `xml:"href,attr"`
|
|
|
|
} `xml:"link"`
|
|
|
|
Content string `xml:",innerxml"`
|
|
|
|
} `xml:"entry"`
|
|
|
|
}{}
|
|
|
|
|
|
|
|
err := xml.Unmarshal(data, &v)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
var feedEntries []FeedEntry
|
|
|
|
for _, atomEntry := range v.Items {
|
|
|
|
feedEntries = append(feedEntries, FeedEntry{
|
|
|
|
Link: atomEntry.Link.Href,
|
|
|
|
Content: atomEntry.Content,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
return feedEntries, nil
|
|
|
|
}
|
|
|
|
func parseRss(data []byte) ([]FeedEntry, error) {
|
|
|
|
|
|
|
|
v := struct {
|
|
|
|
Items []struct {
|
|
|
|
Link string `xml:"link"`
|
|
|
|
Content string `xml:",innerxml"`
|
|
|
|
} `xml:"channel>item"`
|
|
|
|
}{}
|
|
|
|
|
|
|
|
err := xml.Unmarshal(data, &v)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
var feedEntries []FeedEntry
|
|
|
|
for _, rssEntry := range v.Items {
|
|
|
|
feedEntries = append(feedEntries, FeedEntry{
|
|
|
|
Link: rssEntry.Link,
|
|
|
|
Content: rssEntry.Content,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
return feedEntries, nil
|
|
|
|
}
|