Add SPC provider parsing helpers
This commit is contained in:
81
internal/providers/spc/rss.go
Normal file
81
internal/providers/spc/rss.go
Normal file
@@ -0,0 +1,81 @@
|
||||
package spc
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// RSSFeed is a minimal view of the optional SPC RSS feed.
|
||||
type RSSFeed struct {
|
||||
Title string
|
||||
Link string
|
||||
Description string
|
||||
LastBuildDate *time.Time
|
||||
Items []RSSItem
|
||||
}
|
||||
|
||||
// RSSItem is a minimal view of one optional SPC RSS item.
|
||||
type RSSItem struct {
|
||||
Title string
|
||||
Link string
|
||||
Description string
|
||||
PubDate string
|
||||
GUID string
|
||||
}
|
||||
|
||||
// ParseRSSFeed decodes supplemental SPC RSS metadata.
|
||||
func ParseRSSFeed(raw string) (RSSFeed, error) {
|
||||
var doc struct {
|
||||
Channel struct {
|
||||
Title string `xml:"title"`
|
||||
Link string `xml:"link"`
|
||||
Description string `xml:"description"`
|
||||
LastBuildDate string `xml:"lastBuildDate"`
|
||||
Items []struct {
|
||||
Title string `xml:"title"`
|
||||
Link string `xml:"link"`
|
||||
Description string `xml:"description"`
|
||||
PubDate string `xml:"pubDate"`
|
||||
GUID string `xml:"guid"`
|
||||
} `xml:"item"`
|
||||
} `xml:"channel"`
|
||||
}
|
||||
if err := xml.Unmarshal([]byte(raw), &doc); err != nil {
|
||||
return RSSFeed{}, fmt.Errorf("decode rss: %w", err)
|
||||
}
|
||||
|
||||
feed := RSSFeed{
|
||||
Title: strings.TrimSpace(doc.Channel.Title),
|
||||
Link: strings.TrimSpace(doc.Channel.Link),
|
||||
Description: strings.TrimSpace(doc.Channel.Description),
|
||||
LastBuildDate: parseRSSDate(doc.Channel.LastBuildDate),
|
||||
Items: make([]RSSItem, 0, len(doc.Channel.Items)),
|
||||
}
|
||||
for _, item := range doc.Channel.Items {
|
||||
feed.Items = append(feed.Items, RSSItem{
|
||||
Title: strings.TrimSpace(item.Title),
|
||||
Link: strings.TrimSpace(item.Link),
|
||||
Description: strings.TrimSpace(item.Description),
|
||||
PubDate: strings.TrimSpace(item.PubDate),
|
||||
GUID: strings.TrimSpace(item.GUID),
|
||||
})
|
||||
}
|
||||
return feed, nil
|
||||
}
|
||||
|
||||
func parseRSSDate(value string) *time.Time {
|
||||
value = strings.TrimSpace(value)
|
||||
if value == "" {
|
||||
return nil
|
||||
}
|
||||
for _, layout := range []string{time.RFC1123Z, time.RFC1123} {
|
||||
t, err := time.Parse(layout, value)
|
||||
if err == nil {
|
||||
tt := t.UTC()
|
||||
return &tt
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user