diff --git a/feed/updates.rss b/feed/updates.rss index 7b580d7..07d35a5 100644 --- a/feed/updates.rss +++ b/feed/updates.rss @@ -29,7 +29,7 @@ v1.35.0 released [TOL,BYOL] New transaction type - Sat, 15 Sep 2024 10:00:00 +0000 + Sun, 15 Sep 2024 10:00:00 +0000 https://docs.upvest.co/news#version-1350-release https://docs.upvest.co/news#version-1350-release diff --git a/scripts/go.mod b/scripts/go.mod index bc6cf7d..18f205d 100644 --- a/scripts/go.mod +++ b/scripts/go.mod @@ -1 +1,5 @@ -module github.com/upvestco/documentation_assets \ No newline at end of file +module github.com/upvestco/documentation_assets + +go 1.22.0 + +toolchain go1.22.2 diff --git a/scripts/rss.go b/scripts/rss.go new file mode 100644 index 0000000..01b398d --- /dev/null +++ b/scripts/rss.go @@ -0,0 +1,107 @@ +package main + +import ( + "encoding/xml" + "errors" + "fmt" + "time" +) + +type RSS struct { + XMLName xml.Name `xml:"rss"` + Channel Channel `xml:"channel"` +} + +type Channel struct { + Title string `xml:"title"` + Description string `xml:"description"` + PubDate string `xml:"pubDate"` + Items []Item `xml:"item"` +} + +type Item struct { + Title string `xml:"title"` + Description string `xml:"description"` + PubDate string `xml:"pubDate"` + GUID string `xml:"guid"` +} + +func (r *RSS) Validate() error { + rules := []func() error{ + r.validatePubDate, + r.validateItemGUIDs, + r.validateItemDates, + r.validatePubDateUpdated, + } + var errs []error + for _, rule := range rules { + if err := rule(); err != nil { + errs = append(errs, err) + } + } + return errors.Join(errs...) +} + +func (r *RSS) validatePubDate() error { + err := validateRSSDate(r.Channel.PubDate) + if err != nil { + return fmt.Errorf("channel pub date: %v", err) + } + return nil +} + +func (r *RSS) validateItemDates() error { + for _, item := range r.Channel.Items { + err := validateRSSDate(item.PubDate) + if err != nil { + return fmt.Errorf("item '%s' pub date: %v", item.Title, err) + } + } + return nil +} + +func (r *RSS) validateItemGUIDs() error { + guids := make(map[string]bool) + for _, item := range r.Channel.Items { + if guids[item.GUID] { + return fmt.Errorf("duplicate GUID found: %s", item.GUID) + } + guids[item.GUID] = true + } + return nil +} + +func (r *RSS) validatePubDateUpdated() error { + if len(r.Channel.Items) == 0 { + return nil + } + + chanDate, err := time.Parse(time.RFC1123Z, r.Channel.PubDate) + if err != nil { + return fmt.Errorf("invalid date format in channel '%s'", r.Channel.PubDate) + } + + latestItem := r.Channel.Items[0] + itemDate, err := time.Parse(time.RFC1123Z, latestItem.PubDate) + if err != nil { + return fmt.Errorf("invalid date format in item '%s'", latestItem.PubDate) + } + + if !chanDate.Equal(itemDate) { + return fmt.Errorf("publication dates of channel and item do not match") + } + + return nil +} + +func validateRSSDate(str string) error { + t, err := time.Parse(time.RFC1123Z, str) + if err != nil { + return fmt.Errorf("invalid date format in %s", str) + } + // Check that day of week was set correctly, as it is ignored by time.Parse. + if str != t.Format(time.RFC1123Z) { + return fmt.Errorf("day of week is not correct: expected %s, got %s", t.Format(time.RFC1123Z), str) + } + return nil +} diff --git a/scripts/verify_rss.go b/scripts/verify_rss.go index c280370..25acd32 100644 --- a/scripts/verify_rss.go +++ b/scripts/verify_rss.go @@ -2,12 +2,10 @@ package main import ( "encoding/xml" - "errors" "fmt" "os" "path/filepath" "strings" - "time" ) func main() { @@ -34,105 +32,6 @@ func main() { } } -type RSS struct { - XMLName xml.Name `xml:"rss"` - Channel Channel `xml:"channel"` -} - -type Channel struct { - Title string `xml:"title"` - Description string `xml:"description"` - PubDate string `xml:"pubDate"` - Items []Item `xml:"item"` -} - -type Item struct { - Title string `xml:"title"` - Description string `xml:"description"` - PubDate string `xml:"pubDate"` - GUID string `xml:"guid"` -} - -func (r *RSS) Validate() error { - rules := []func() error{ - r.validatePubDate, - r.validateItemGUIDs, - r.validateItemDates, - r.validatePubDateUpdated, - } - var errs []error - for _, rule := range rules { - if err := rule(); err != nil { - errs = append(errs, err) - } - } - return errors.Join(errs...) -} - -func (r *RSS) validatePubDate() error { - err := validateRSSDate(r.Channel.PubDate) - if err != nil { - return fmt.Errorf("channel pub date: %v", err) - } - return nil -} - -func (r *RSS) validateItemDates() error { - for _, item := range r.Channel.Items { - err := validateRSSDate(item.PubDate) - if err != nil { - return fmt.Errorf("item '%s' pub date: %v", item.Title, err) - } - } - return nil -} - -func (r *RSS) validateItemGUIDs() error { - guids := make(map[string]bool) - for _, item := range r.Channel.Items { - if guids[item.GUID] { - return fmt.Errorf("duplicate GUID found: %s", item.GUID) - } - guids[item.GUID] = true - } - return nil -} - -func (r *RSS) validatePubDateUpdated() error { - if len(r.Channel.Items) == 0 { - return nil - } - - chanDate, err := time.Parse(time.RFC1123Z, r.Channel.PubDate) - if err != nil { - return fmt.Errorf("invalid date format in channel '%s'", r.Channel.PubDate) - } - - latestItem := r.Channel.Items[0] - itemDate, err := time.Parse(time.RFC1123Z, latestItem.PubDate) - if err != nil { - return fmt.Errorf("invalid date format in item '%s'", latestItem.PubDate) - } - - if !chanDate.Equal(itemDate) { - return fmt.Errorf("publication dates of channel and item do not match") - } - - return nil -} - -func validateRSSDate(str string) error { - t, err := time.Parse(time.RFC1123Z, str) - if err != nil { - return fmt.Errorf("invalid date format in %s", str) - } - // Check that day of week was set correctly, as it is ignored by time.Parse. - if str != t.Format(time.RFC1123Z) { - return fmt.Errorf("day of week is not correct: expected %s, got %s", t.Format(time.RFC1123Z), str) - } - return nil -} - func verifyRSS(filePath string) error { data, err := os.ReadFile(filePath) if err != nil {