/
rssole.go
107 lines (82 loc) · 2.17 KB
/
rssole.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
package rssole
import (
"embed"
"fmt"
"io/fs"
"net/http"
"text/template"
"time"
"github.com/NYTimes/gziphandler"
"golang.org/x/exp/slog"
)
const (
templatesDir = "templates"
)
var Version = "dev"
var (
//go:embed templates/*
files embed.FS
templates map[string]*template.Template
//go:embed libs/*
wwwlibs embed.FS
)
var (
allFeeds = &feeds{}
readLut = &unreadLut{}
)
func loadTemplates() error {
if templates == nil {
templates = make(map[string]*template.Template)
}
tmplFiles, err := fs.ReadDir(files, templatesDir)
if err != nil {
return fmt.Errorf("loadTemplates readdir - %w", err)
}
for _, tmpl := range tmplFiles {
if tmpl.IsDir() {
continue
}
pt, err := template.ParseFS(files, templatesDir+"/"+tmpl.Name(), templatesDir+"/components/*.go.html")
if err != nil {
return fmt.Errorf("loadTemplates parsefs - %w", err)
}
templates[tmpl.Name()] = pt
}
return nil
}
func Start(configFilename, configReadCacheFilename, listenAddress string, updateTime time.Duration) error {
slog.Info("RiSSOLE", "version", Version)
err := loadTemplates()
if err != nil {
return err
}
readLut.Filename = configReadCacheFilename
readLut.loadReadLut()
readLut.startCleanupTicker()
if err := allFeeds.readFeedsFile(configFilename); err != nil {
return err
}
allFeeds.UpdateTime = updateTime
allFeeds.BeginFeedUpdates()
http.HandleFunc("/", index)
http.HandleFunc("/feeds", feedlist)
http.HandleFunc("/items", items)
http.HandleFunc("/item", item)
http.HandleFunc("/crudfeed", crudfeed)
http.HandleFunc("/settings", settings)
// As the static files won't change we force the browser to cache them.
httpFS := http.FileServer(http.FS(wwwlibs))
http.Handle("/libs/", forceCache(httpFS))
slog.Info("Listening", "address", listenAddress)
if err := http.ListenAndServe(listenAddress, gziphandler.GzipHandler(http.DefaultServeMux)); err != nil {
return fmt.Errorf("error during ListenAndServe - %w", err)
}
return nil
}
func forceCache(h http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Cache-Control", "max-age=86400") // 24 hours
h.ServeHTTP(w, r)
}
return http.HandlerFunc(fn)
}