atom/atom.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
package atom
import (
"bufio"
"fmt"
"log"
"net/http"
"os"
"path/filepath"
"strings"
"time"
)
const maxFeed = 10
type post struct {
title string
updated string
link string
// starting with content disabled because a lot of my content is nonsensical
// to any reasonable xml parser tbh
// content string
}
func Handler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/atom+xml")
posts, err := getPosts("thought/*")
if err != nil {
log.Println(err)
}
// TODO: sort them by date, then
if len(posts) > maxFeed {
posts = posts[:maxFeed]
}
var updated string
if len(posts) > 0 {
updated = posts[0].updated
}
// SET HEADER TYPE TBH
fmt.Fprintf(w, `<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>j3s.sh</title>
<link rel="self" href="https://j3s.sh/feed.atom" />
<link href="https://j3s.sh/" />
<updated>%s</updated>
<author>
<name>Jes Olson</name>
</author>
<id>https://j3s.sh/</id>
`, updated)
for _, p := range posts {
// add content in future? idk prob not
fmt.Fprintf(w, `
<entry>
<title>%s</title>
<link href="%s"/>
<id>%s</id>
<updated>%s</updated>
</entry>
`, p.title, p.link, p.link, p.updated)
}
fmt.Fprint(w, `
</feed>`)
}
func getPosts(dir string) ([]post, error) {
var posts []post
files, err := filepath.Glob(dir)
if err != nil {
return nil, err
}
for _, f := range files {
post, err := fileToPost(f)
if err != nil {
// this can be failed intentionally for drafts or posts too small for rss updoots
// add a print statement here if blog posts mysteriously vanish from the atom feed
//
// lmao
continue
}
posts = append(posts, post)
}
return posts, err
}
func fileToPost(file string) (post, error) {
var p post
f, err := os.Open(file)
if err != nil {
return p, err
}
defer f.Close()
scanner := bufio.NewScanner(f)
scanner.Scan() // this moves to the next token
// strip spaces
title := scanner.Text()
p.title = strings.TrimSpace(title)
scanner.Scan()
timestr := strings.TrimSpace(scanner.Text())
updated, err := time.Parse(timeLayoutPost, timestr)
if err != nil {
return p, err
}
// for scanner.Scan() {
// p.content = p.content + scanner.Text()
// }
p.updated = updated.Format(timeLayoutAtom)
p.link = "https://j3s.sh/" + file
return p, err
}
type TimeStr string
var timeLayoutPost = "2006-01-02"
var timeLayoutAtom = "2006-01-02T15:04:05.000Z"