-
Notifications
You must be signed in to change notification settings - Fork 6
/
main.go
115 lines (98 loc) · 3.14 KB
/
main.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
package main
import (
"errors"
"fmt"
"net"
"net/http"
"os"
"strings"
"text/template"
"time"
"github.com/caarlos0/env"
"github.com/gobuffalo/packr"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/dewey/feedbridge/api"
"github.com/dewey/feedbridge/plugin"
"github.com/dewey/feedbridge/plugins/scmp"
"github.com/dewey/feedbridge/runner"
"github.com/dewey/feedbridge/store"
"github.com/go-chi/chi"
"github.com/go-kit/kit/log"
"github.com/go-kit/kit/log/level"
cache "github.com/patrickmn/go-cache"
)
var config struct {
RefreshInterval int `env:"REFRESH_INTERVAL" envDefault:"15"`
CacheExpiration int `env:"CACHE_EXPIRATION" envDefault:"30"`
CacheExpiredPurge int `env:"CACHE_EXPIRED_PURGE" envDefault:"60"`
Environment string `env:"ENVIRONMENT" envDefault:"develop"`
Port int `env:"PORT" envDefault:"8080"`
}
func main() {
err := env.Parse(&config)
if err != nil {
panic(err)
}
l := log.NewLogfmtLogger(log.NewSyncWriter(os.Stderr))
switch strings.ToLower(config.Environment) {
case "develop":
l = level.NewFilter(l, level.AllowInfo())
case "prod":
l = level.NewFilter(l, level.AllowError())
}
l = log.With(l, "ts", log.DefaultTimestampUTC, "caller", log.DefaultCaller)
cache := cache.New(time.Duration(config.CacheExpiration)*time.Minute, time.Duration(config.CacheExpiredPurge)*time.Minute)
storageRepo, err := store.NewMemRepository(cache)
if err != nil {
return
}
t := &http.Transport{
Dial: (&net.Dialer{
Timeout: 10 * time.Second,
}).Dial,
TLSHandshakeTimeout: 10 * time.Second,
}
c := &http.Client{
Timeout: time.Second * 15,
Transport: t,
}
pluginRepo := plugin.NewMemRepo()
pluginRepo.Install(scmp.NewPlugin(l, c))
runner := runner.NewRunner(l, pluginRepo, storageRepo, config.RefreshInterval)
go runner.Start()
apiService := api.NewService(l, storageRepo, pluginRepo)
templates := packr.NewBox("./ui/templates")
assets := packr.NewBox("./ui/assets")
r := chi.NewRouter()
r.Get("/", func(w http.ResponseWriter, r *http.Request) {
t, err := template.New("index.tmpl").Parse(templates.String("index.tmpl"))
if err != nil {
http.Error(w, errors.New("couldn't serve template").Error(), http.StatusInternalServerError)
return
}
data := struct {
Feeds []plugin.PluginMetadata
RefreshInterval int
}{
Feeds: apiService.ListFeeds(),
RefreshInterval: config.RefreshInterval,
}
if err := t.Execute(w, data); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
})
r.Handle("/static/*", http.StripPrefix("/static/", http.FileServer(assets)))
r.Handle("/metrics", promhttp.Handler())
// TODO(dewey): Switch to promhttp middleware instead of this deprecated one
r.Mount("/feed", prometheus.InstrumentHandler("feed", api.NewHandler(*apiService)))
r.NotFound(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("nothing to see here"))
})
l.Log("msg", fmt.Sprintf("feedbridge listening on http://localhost:%d", config.Port))
err = http.ListenAndServe(fmt.Sprintf(":%d", config.Port), r)
if err != nil {
panic(err)
}
}