2022-07-20 AuraGem's Go Code for Converting Gemsub Feed to Atom
There was recent talk about converting Gemsub Feeds to Atom Feeds:
So, I wanted to post some code I have. Well over a year ago, one of the first things I did on AuraGem (previously Ponix) was write code that converted a Gemsub Feed to an Atom Feed. Everytime someone clicks on AuraGem's Atom feed, it is automatically generated on-demand with the code below. It is extremely simple, and certainly can be improved, but it works for my uses. One thing that can be added is the subtitle line (marked by the second-level heading just under the feed title), as described in the Gemsub Feed companion spec.
type AtomPost struct {
link string
date time.Time
title string
}
func generateAtomFrom(file string, domain string, baseurl string, authorName string, authorEmail string) string {
feedTitle := ""
var posts []AtomPost
last_updated, _ := time.Parse("2006-01-02T15:04:05Z", "2006-01-02T15:04:05Z")
gemini, err := ioutil.ReadFile(file)
if err != nil {
panic(err)
}
geminiLines := strings.Split(strings.TrimSuffix(string(gemini), "\n"), "\n")
for _, line := range geminiLines {
if strings.HasPrefix(line, "=> ") {
parts := strings.SplitN(strings.Replace(line, "=> ", "", 1), " ", 3)
t, err := time.Parse(time.RFC3339, parts[1])
if err != nil {
t, err = time.Parse("2006-01-02", parts[1])
if err != nil {
continue
}
}
if t.After(last_updated) {
last_updated = t
}
if len(parts) >= 3 {
posts = append(posts, AtomPost{domain + parts[0], t, parts[2]})
}
} else if strings.HasPrefix(line, "# ") && feedTitle == "" {
feedTitle = strings.Replace(line, "# ", "", 1)
}
}
last_updated_string := last_updated.Format("2006-01-02T15:04:05Z")
var builder strings.Builder
fmt.Fprintf(&builder, `
%s
%s
%s
%s
%s
`, baseurl, html.EscapeString(feedTitle), last_updated_string, baseurl+"/atom.xml", html.EscapeString(authorName), html.EscapeString(authorEmail))
for _, post := range posts {
post_date_string := post.date.Format(time.RFC3339)
fmt.Fprintf(&builder,
`
%s
%s
%s
`, html.EscapeString(post.title), post.link, post.link, post_date_string)
}
fmt.Fprintf(&builder, ` `)
return builder.String()
}