/
main.go
147 lines (125 loc) · 3.24 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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
package main
import (
"bufio"
"encoding/json"
"flag"
"fmt"
"github.com/dillonhafer/otd/on_this_day"
"github.com/jackc/markovbot/markov"
"io"
"math/rand"
"net/http"
"os"
"strings"
"time"
)
const Version = "1.0.0"
var options struct {
httpAddr string
prefixSize int
maxOutputSize int
seed int64
version bool
}
func main() {
flag.Usage = func() {
fmt.Fprintf(os.Stderr, "usage: %s [options]\n", os.Args[0])
flag.PrintDefaults()
}
flag.IntVar(&options.prefixSize, "prefix", 2, "prefix size")
flag.StringVar(&options.httpAddr, "http", "", "HTTP listen address (e.g. 127.0.0.1:3000)")
flag.IntVar(&options.maxOutputSize, "output", 200, "max output size in words")
flag.Int64Var(&options.seed, "seed", -1, "seed for random number generator")
flag.BoolVar(&options.version, "version", false, "print version and exit")
flag.Parse()
if options.version {
fmt.Printf("historybot v%v\n", Version)
os.Exit(0)
}
if options.seed < 0 {
options.seed = time.Now().UnixNano()
fmt.Fprintln(os.Stderr, "seed:", options.seed)
}
rand.Seed(options.seed)
events := otd.Events()
serveAddress := "127.0.0.1:23000"
if options.httpAddr != "" {
serveAddress = options.httpAddr
}
fmt.Fprintln(os.Stderr, "Listening on:", serveAddress)
fmt.Fprintln(os.Stderr, "Use `--httpAddr` flag to change the default address")
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
var jsonResp struct {
Text string `json:"text"`
}
jsonResp.Text = otd.RandomEvent(events)
js, err := json.Marshal(jsonResp)
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
w.Write(js)
})
// Fringe Bot
http.HandleFunc("/fringe", func(w http.ResponseWriter, r *http.Request) {
var jsonResp struct {
Text string `json:"text"`
}
fringeEvents, err := readLines("events/fringe")
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
// Create input string
var nevents []string
var years []string
for _, text := range fringeEvents {
parts := strings.Split(text, "–")
if len(parts) > 1 {
nevents = append(nevents, parts[1])
years = append(years, strings.Replace(parts[0], "On this day in ", "", -1))
}
}
year := RandomYear(years)
jevents := strings.Join(nevents, "\n")
var in io.Reader
in = strings.NewReader(jevents)
// Build Markov chain
chain, err := markov.NewChain(in, options.prefixSize)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
// Write response
chainText := chain.Generate(options.maxOutputSize)
jsonResp.Text = fmt.Sprintf("In a parallel universe, on this day in %s- %s", year, chainText)
js, err := json.Marshal(jsonResp)
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
w.Write(js)
})
err := http.ListenAndServe(serveAddress, nil)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
func RandomYear(years []string) string {
totalYears := len(years) - 1
rand.Seed(time.Now().UnixNano())
y := rand.Intn(totalYears)
return years[y]
}
func readLines(path string) ([]string, error) {
file, err := os.Open(path)
if err != nil {
return nil, err
}
defer file.Close()
var lines []string
scanner := bufio.NewScanner(file)
for scanner.Scan() {
lines = append(lines, scanner.Text())
}
return lines, scanner.Err()
}