artbound.go (view raw)
1package main
2
3import (
4 "bytes"
5 "encoding/json"
6 "html/template"
7 "log"
8 "net/http"
9 "net/url"
10 "os"
11 "time"
12
13 "github.com/joho/godotenv"
14)
15
16var spreadsheetId string
17var spreadsheetRange string
18
19var templatesDirectory = "templates/"
20var indexTemplate = template.Must(template.ParseFiles(templatesDirectory + "index.html"))
21var helpTemplate = template.Must(template.ParseFiles(templatesDirectory + "help.html"))
22
23type TemplateData struct {
24 Emoji EmojiDict
25 LastUpdated string
26 CurrentMonth string
27}
28
29func indexHandler(db *DB) http.HandlerFunc {
30 return func(w http.ResponseWriter, r *http.Request) {
31 if r.Method != http.MethodGet {
32 http.Error(w, "Please use GET.", http.StatusMethodNotAllowed)
33 return
34 }
35
36 lastUpdated := db.LastUpdated.Format("02/01/2006 15:04")
37 currentMonth := time.Now().Format("2006-01")
38 templateData := &TemplateData{defaultEmojis, lastUpdated, currentMonth}
39 buf := &bytes.Buffer{}
40 err := indexTemplate.Execute(buf, templateData)
41 if err != nil {
42 http.Error(w, err.Error(), http.StatusInternalServerError)
43 return
44 }
45 buf.WriteTo(w)
46 }
47}
48
49func helpHandler(w http.ResponseWriter, r *http.Request) {
50 if r.Method != http.MethodGet {
51 http.Error(w, "Please use GET.", http.StatusMethodNotAllowed)
52 return
53 }
54
55 buf := &bytes.Buffer{}
56 err := helpTemplate.Execute(buf, defaultEmojis)
57 if err != nil {
58 http.Error(w, err.Error(), http.StatusInternalServerError)
59 return
60 }
61 buf.WriteTo(w)
62}
63
64func clearHandler(db *DB) http.HandlerFunc {
65 return func(w http.ResponseWriter, r *http.Request) {
66 if r.Method != http.MethodPost {
67 http.Error(w, "Please use POST.", http.StatusMethodNotAllowed)
68 return
69 }
70 err := db.Clear()
71 if err != nil {
72 log.Fatal("Error:", err)
73 http.Error(w, "Could not delete cache.", http.StatusInternalServerError)
74 }
75 http.Error(w, "Done.", http.StatusOK)
76 }
77}
78
79func updateHandler(googleApi *GoogleAPI, db *DB) http.HandlerFunc {
80 return func(w http.ResponseWriter, r *http.Request) {
81 if r.Method != http.MethodPost {
82 http.Error(w, "Please use POST.", http.StatusMethodNotAllowed)
83 return
84 }
85 p := db.UpdateCall()
86 w.Header().Set("Content-Type", "application/json")
87 w.WriteHeader(http.StatusCreated)
88 json.NewEncoder(w).Encode(p)
89 }
90}
91
92func getHandler(googleApi *GoogleAPI, db *DB) http.HandlerFunc {
93 return func(w http.ResponseWriter, r *http.Request) {
94 u, err := url.Parse(r.URL.String())
95 if err != nil {
96 log.Fatal("Could not parse URL.")
97 http.Error(w, err.Error(), http.StatusInternalServerError)
98 return
99 }
100
101 month := u.Query().Get("month")
102 entries, err := db.GetEntries(month)
103 if err != nil {
104 log.Fatal("Could not get entries for month", month)
105 http.Error(w, err.Error(), http.StatusInternalServerError)
106 return
107 }
108
109 w.Header().Set("Content-Type", "application/json")
110 w.WriteHeader(http.StatusCreated)
111 json.NewEncoder(w).Encode(entries)
112 }
113}
114
115func main() {
116 err := godotenv.Load()
117 if err != nil {
118 log.Println("No .env file provided.")
119 }
120
121 port := os.Getenv("PORT")
122 if port == "" {
123 port = "3000"
124 }
125
126 spreadsheetId = os.Getenv("SPREADSHEET_ID")
127 if spreadsheetId == "" {
128 log.Fatal("Please fill out SPREADSHEET_ID in .env")
129 os.Exit(1)
130 }
131
132 spreadsheetRange = os.Getenv("SPREADSHEET_RANGE")
133 if spreadsheetRange == "" {
134 log.Fatal("Please fill out SPREADSHEET_RANGE in .env")
135 os.Exit(1)
136 }
137
138 fs := http.FileServer(http.Dir("./static"))
139
140 googleApi := initGoogleAPI()
141 db := initDB(googleApi)
142
143 r := http.NewServeMux()
144 r.HandleFunc("/", indexHandler(db))
145 r.HandleFunc("/clear", clearHandler(db))
146 r.HandleFunc("/help", helpHandler)
147 r.HandleFunc("/update", updateHandler(googleApi, db))
148 r.HandleFunc("/get", getHandler(googleApi, db))
149 r.Handle("/static/", http.StripPrefix("/static/", fs))
150
151 log.Println("Serving on port", port)
152 err = http.ListenAndServe(":"+port, r)
153 if err != nil {
154 log.Fatal(err)
155 }
156}