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
126
127
128
129
130
131
132
133
134
|
package main
import (
"errors"
"flag"
"html/template"
"log"
"net/http"
"os"
"path"
"strings"
"time"
)
var porn EarthPorn
var weather Weather
var sun Sun
func trylater(ch chan<- bool) {
log.Println("Will try again later...")
time.Sleep(1 * time.Minute)
ch <- true
}
func earthPornUpdater(ch chan bool) {
for _ = range ch {
newporn, err := GetEarthPorn()
if err != nil {
log.Printf("Failed getting fap material: %s", err)
go trylater(ch)
}
porn = newporn
log.Println("New fap material!")
}
}
func weatherUpdater(ch chan bool) {
for _ = range ch {
newW, newS, err := CurrentWeather()
if err != nil {
log.Printf("Failed getting latest weather data: %s", err)
go trylater(ch)
}
weather = newW
sun = newS
log.Println("New weather data")
}
}
func intervalUpdates(d time.Duration, stopch <-chan bool, chans ...chan<- bool) {
send := func(chans ...chan<- bool) {
for _, ch := range chans {
go func(ch chan<- bool) {
ch <- true
}(ch)
}
}
send(chans...)
tick := time.NewTicker(d)
for {
select {
case <-tick.C:
send(chans...)
case <-stopch:
tick.Stop()
for _, ch := range chans {
close(ch)
}
return
}
}
}
var tpl *template.Template
func loadTemplate() {
gopaths := strings.Split(os.Getenv("GOPATH"), ":")
for _, p := range gopaths {
var err error
tpl, err = template.ParseFiles(path.Join(p, "src", "github.com", "kch42", "startpage", "template.html"))
if err == nil {
return
}
}
panic(errors.New("could not find template in $GOPATH/src/github.com/kch42/startpage"))
}
func main() {
laddr := flag.String("laddr", ":25145", "Listen on this port")
flag.Parse()
loadTemplate()
pornch := make(chan bool)
weatherch := make(chan bool)
stopch := make(chan bool)
go intervalUpdates(30*time.Minute, stopch, pornch, weatherch)
go weatherUpdater(weatherch)
go earthPornUpdater(pornch)
defer func(stopch chan<- bool) {
stopch <- true
}(stopch)
http.HandleFunc("/", startpage)
log.Fatal(http.ListenAndServe(*laddr, nil))
}
type TplData struct {
Porn *EarthPorn
Weather *Weather
Links []Link
LCols int
}
func startpage(rw http.ResponseWriter, req *http.Request) {
links := GetLinks()
lcols := len(links) / 3
if lcols < 1 {
lcols = 1
} else if lcols > 4 {
lcols = 4
}
if err := tpl.Execute(rw, &TplData{&porn, &weather, links, lcols}); err != nil {
log.Printf("Failed executing template: %s\n", err)
}
}
|