From c8808e21bff2f6cb1285d0d9e59811ab46401c0c Mon Sep 17 00:00:00 2001 From: Ben Visness Date: Fri, 9 Jun 2023 13:01:51 -0700 Subject: [PATCH] Add Atom feed (not yet linked) --- src/hmnurl/hmnurl_test.go | 6 +++ src/hmnurl/urls.go | 12 ++++++ .../src/layouts/timemachine_base.html | 2 + src/templates/src/timemachine_atom.xml | 36 +++++++++++++++++ .../src/timemachine_submissions.html | 4 ++ src/templates/templates.go | 3 ++ src/website/routes.go | 1 + src/website/time_machine.go | 39 +++++++++++++++++++ 8 files changed, 103 insertions(+) create mode 100644 src/templates/src/timemachine_atom.xml diff --git a/src/hmnurl/hmnurl_test.go b/src/hmnurl/hmnurl_test.go index e71f657..1fc502b 100644 --- a/src/hmnurl/hmnurl_test.go +++ b/src/hmnurl/hmnurl_test.go @@ -422,9 +422,15 @@ func TestTimeMachine(t *testing.T) { func TestTimeMachineSubmissions(t *testing.T) { AssertRegexMatch(t, BuildTimeMachineSubmissions(), RegexTimeMachineSubmissions, nil) + AssertRegexMatch(t, BuildTimeMachineSubmission(123), RegexTimeMachineSubmissions, nil) AssertSubdomain(t, BuildTimeMachineSubmissions(), "") } +func TestTimeMachineAtomFeed(t *testing.T) { + AssertRegexMatch(t, BuildTimeMachineAtomFeed(), RegexTimeMachineAtomFeed, nil) + AssertSubdomain(t, BuildTimeMachineAtomFeed(), "") +} + func TestTimeMachineForm(t *testing.T) { AssertRegexMatch(t, BuildTimeMachineForm(), RegexTimeMachineForm, nil) AssertSubdomain(t, BuildTimeMachineForm(), "") diff --git a/src/hmnurl/urls.go b/src/hmnurl/urls.go index 6d0eab0..f152722 100644 --- a/src/hmnurl/urls.go +++ b/src/hmnurl/urls.go @@ -126,6 +126,18 @@ func BuildTimeMachineSubmissions() string { return Url("/timemachine/submissions", nil) } +func BuildTimeMachineSubmission(id int) string { + defer CatchPanic() + return UrlWithFragment("/timemachine/submissions", nil, strconv.Itoa(id)) +} + +var RegexTimeMachineAtomFeed = regexp.MustCompile("^/timemachine/submissions/atom$") + +func BuildTimeMachineAtomFeed() string { + defer CatchPanic() + return Url("/timemachine/submissions/atom", nil) +} + var RegexTimeMachineForm = regexp.MustCompile("^/timemachine/submit$") func BuildTimeMachineForm() string { diff --git a/src/templates/src/layouts/timemachine_base.html b/src/templates/src/layouts/timemachine_base.html index 97e2f2e..64ee993 100644 --- a/src/templates/src/layouts/timemachine_base.html +++ b/src/templates/src/layouts/timemachine_base.html @@ -177,6 +177,8 @@ margin: 0.2rem 0; } + + {{ block "extrahead" . }}{{ end }} diff --git a/src/templates/src/timemachine_atom.xml b/src/templates/src/timemachine_atom.xml new file mode 100644 index 0000000..fe3dd75 --- /dev/null +++ b/src/templates/src/timemachine_atom.xml @@ -0,0 +1,36 @@ +{{ noescape "" }} + + https://handmade.network/timemachine/submissions + Time Machine | Handmade Network + This summer, dig out your old devices and see what they were actually like to use. + {{ rfc3339 .Updated }} + + + + + Handmade Network + team@handmade.network + https://handmade.network/ + + {{ .LogoUrl }} + © 2023 Handmade Network + {{ range .Submissions }} + + {{ .Permalink }} + {{ .Title }} + + {{ rfc3339 .Date }} + {{ rfc3339 .Date }} + + {{ with .Details }} + <ul> + {{ range . }} + <li><b>{{ .Name }}:</b> {{ yesescape .Content }}</li> + {{ end }} + </ul> + {{ end }} + {{ yesescape .Description }} + + + {{ end }} + diff --git a/src/templates/src/timemachine_submissions.html b/src/templates/src/timemachine_submissions.html index 041ab62..8f9a8c1 100644 --- a/src/templates/src/timemachine_submissions.html +++ b/src/templates/src/timemachine_submissions.html @@ -1,5 +1,9 @@ {{ template "timemachine_base.html" . }} +{{ define "extrahead" }} + +{{ end }} + {{ define "content" }}
diff --git a/src/templates/templates.go b/src/templates/templates.go index 4d03762..c399f2c 100644 --- a/src/templates/templates.go +++ b/src/templates/templates.go @@ -255,6 +255,9 @@ var HMNTemplateFuncs = template.FuncMap{ "noescape": func(str string) template.HTML { return template.HTML(str) }, + "yesescape": func(html template.HTML) string { + return string(html) + }, "filesize": func(numBytes int) string { scales := []string{ " bytes", diff --git a/src/website/routes.go b/src/website/routes.go index 966d4f2..395e2e4 100644 --- a/src/website/routes.go +++ b/src/website/routes.go @@ -72,6 +72,7 @@ func NewWebsiteRoutes(conn *pgxpool.Pool) http.Handler { hmnOnly.GET(hmnurl.RegexTimeMachine, TimeMachine) hmnOnly.GET(hmnurl.RegexTimeMachineSubmissions, TimeMachineSubmissions) + hmnOnly.GET(hmnurl.RegexTimeMachineAtomFeed, TimeMachineAtomFeed) hmnOnly.GET(hmnurl.RegexTimeMachineForm, needsAuth(TimeMachineForm)) hmnOnly.GET(hmnurl.RegexTimeMachineFormDone, needsAuth(TimeMachineFormDone)) hmnOnly.POST(hmnurl.RegexTimeMachineForm, needsAuth(csrfMiddleware(TimeMachineFormSubmit))) diff --git a/src/website/time_machine.go b/src/website/time_machine.go index 74fa354..e322ff5 100644 --- a/src/website/time_machine.go +++ b/src/website/time_machine.go @@ -4,6 +4,7 @@ import ( "html/template" "net/http" "strings" + "time" "git.handmade.network/hmn/hmn/src/email" "git.handmade.network/hmn/hmn/src/hmnurl" @@ -67,12 +68,14 @@ func TimeMachineSubmissions(c *RequestContext) ResponseData { templates.BaseData MainUrl string SubmitUrl string + AtomFeedUrl string Submissions []TimeMachineSubmission } tmpl := TemplateData{ BaseData: baseData, MainUrl: hmnurl.BuildTimeMachine(), SubmitUrl: hmnurl.BuildTimeMachineForm(), + AtomFeedUrl: hmnurl.BuildTimeMachineAtomFeed(), Submissions: tmSubmissions, } @@ -139,10 +142,39 @@ func TimeMachineFormDone(c *RequestContext) ResponseData { return res } +func TimeMachineAtomFeed(c *RequestContext) ResponseData { + type TemplateData struct { + Updated time.Time + TimeMachineUrl string + SubmissionsUrl string + AtomFeedUrl string + LogoUrl string + Submissions []TimeMachineSubmission + } + tmpl := TemplateData{ + Updated: tmSubmissions[0].Date, + TimeMachineUrl: hmnurl.BuildTimeMachine(), + SubmissionsUrl: hmnurl.BuildTimeMachineSubmissions(), + AtomFeedUrl: hmnurl.BuildTimeMachineAtomFeed(), + LogoUrl: hmnurl.BuildPublic("timemachine/twittercard.png", true), + Submissions: tmSubmissions, + } + + var res ResponseData + res.MustWriteTemplate( + "timemachine_atom.xml", + tmpl, + c.Perf, + ) + return res +} + type TimeMachineSubmission struct { + Date time.Time Title string Url string Thumbnail string + Permalink string // generated for feed Details []TimeMachineSubmissionDetail Description template.HTML } @@ -154,6 +186,7 @@ type TimeMachineSubmissionDetail struct { var tmSubmissions = []TimeMachineSubmission{ { + Date: time.Date(2023, 6, 6, 0, 0, 0, 0, time.UTC), Title: "2009 iPod Touch", Url: "https://youtu.be/2eBFk1yV6mE", Thumbnail: "timemachine/ipodtouch-dither.gif", @@ -188,3 +221,9 @@ var tmSubmissions = []TimeMachineSubmission{

`, }, } + +func init() { + for i := range tmSubmissions { + tmSubmissions[i].Permalink = hmnurl.BuildTimeMachineSubmission(len(tmSubmissions) - i) + } +}