feat: order items deterministically by local date desc, hoise rss-to-link conv
This commit is contained in:
parent
fa3ff3094e
commit
b028cc1c6d
5 changed files with 37 additions and 14 deletions
|
@ -22,7 +22,12 @@ func fetchFeed(url string) {
|
||||||
|
|
||||||
d := ParseFeed(b)
|
d := ParseFeed(b)
|
||||||
|
|
||||||
b, _ = json.Marshal(d.Channel.ItemsToLinks())
|
links := []Link{}
|
||||||
|
|
||||||
|
for _, feedItem := range d.Channel.Items {
|
||||||
|
links = append(links, Link{Url: feedItem.Link, Title: feedItem.Title, PublishedDate: feedItem.GetPublishedDate()})
|
||||||
|
}
|
||||||
|
b, _ = json.Marshal(links)
|
||||||
cacheKey := fmt.Sprintf("feeds:%s", url)
|
cacheKey := fmt.Sprintf("feeds:%s", url)
|
||||||
SharedCache.Set(cacheKey, string(b))
|
SharedCache.Set(cacheKey, string(b))
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ import (
|
||||||
|
|
||||||
type RenderMeta struct {
|
type RenderMeta struct {
|
||||||
RenderStart time.Time
|
RenderStart time.Time
|
||||||
|
Location string
|
||||||
}
|
}
|
||||||
|
|
||||||
type RenderContext struct {
|
type RenderContext struct {
|
||||||
|
@ -51,7 +52,7 @@ func Render(w io.Writer, templateName string, data interface{}) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
renderContext := RenderContext{Data: data, Meta: RenderMeta{RenderStart: start}}
|
renderContext := RenderContext{Data: data, Meta: RenderMeta{RenderStart: start, Location: "America/New_York"}}
|
||||||
|
|
||||||
return tmpl.ExecuteTemplate(w, "base", renderContext)
|
return tmpl.ExecuteTemplate(w, "base", renderContext)
|
||||||
}
|
}
|
||||||
|
|
24
routes.go
24
routes.go
|
@ -5,12 +5,22 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"slices"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Link struct {
|
type Link struct {
|
||||||
Url string `json:"url"`
|
Url string `json:"url"`
|
||||||
PublishedDate string `json:"publishedDate"`
|
PublishedDate time.Time `json:"publishedDate"`
|
||||||
Title string `json:"title"`
|
Title string `json:"title"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l Link) GetLocalizedPublishedDate(loc string) time.Time {
|
||||||
|
if loc == "" {
|
||||||
|
loc = "America/New_York"
|
||||||
|
}
|
||||||
|
location, _ := time.LoadLocation(loc)
|
||||||
|
return l.PublishedDate.In(location)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Healthcheck route
|
// Healthcheck route
|
||||||
|
@ -39,6 +49,14 @@ func listContent(w http.ResponseWriter, r *http.Request) {
|
||||||
links = append(links, formattedItems...)
|
links = append(links, formattedItems...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
slices.SortStableFunc(links, func(a Link, b Link) int {
|
||||||
|
if a.PublishedDate.After(b.PublishedDate) {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1
|
||||||
|
})
|
||||||
|
|
||||||
Render(w, "index", links)
|
Render(w, "index", links)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
15
rss.go
15
rss.go
|
@ -2,6 +2,7 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Document struct {
|
type Document struct {
|
||||||
|
@ -12,7 +13,8 @@ type Item struct {
|
||||||
Title string `xml:"title"`
|
Title string `xml:"title"`
|
||||||
Link string `xml:"link"`
|
Link string `xml:"link"`
|
||||||
Description string `xml:"description"`
|
Description string `xml:"description"`
|
||||||
PublishedDate string `xml:"pubDate"`
|
PubDate string `xml:"pubDate"`
|
||||||
|
PublishedDate time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
type Channel struct {
|
type Channel struct {
|
||||||
|
@ -21,14 +23,11 @@ type Channel struct {
|
||||||
Items []Item `xml:"item"`
|
Items []Item `xml:"item"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c Channel) ItemsToLinks() []Link {
|
const DATE_FORMAT = "Mon, 02 Jan 2006 15:04:05 -0700"
|
||||||
formattedItems := []Link{}
|
|
||||||
|
|
||||||
for _, feedItem := range c.Items {
|
func (i Item) GetPublishedDate() time.Time {
|
||||||
formattedItems = append(formattedItems, Link{Url: feedItem.Link, Title: feedItem.Title, PublishedDate: feedItem.PublishedDate})
|
published, _ := time.Parse(DATE_FORMAT, i.PubDate)
|
||||||
}
|
return published
|
||||||
|
|
||||||
return formattedItems
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseFeed(raw []byte) Document {
|
func ParseFeed(raw []byte) Document {
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
{{ range .Data }}
|
{{ range .Data }}
|
||||||
<li>
|
<li>
|
||||||
<a href="{{ .Url }}">{{ .Title }}</a>
|
<a href="{{ .Url }}">{{ .Title }}</a>
|
||||||
<span>{{ .PublishedDate }}</span>
|
<span>{{ .GetLocalizedPublishedDate $.Meta.Location }}</span>
|
||||||
</li>
|
</li>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
Loading…
Reference in a new issue