|
@@ -5,14 +5,29 @@ import (
|
5
|
5
|
"html/template"
|
6
|
6
|
"log"
|
7
|
7
|
"net/http"
|
|
8
|
+ "strconv"
|
8
|
9
|
"strings"
|
9
|
10
|
"time"
|
10
|
11
|
)
|
11
|
12
|
|
12
|
13
|
var (
|
13
|
|
- cachedTemplates = template.Must(template.ParseFiles("web/index.html"))
|
|
14
|
+ cachedTemplates = template.Must(template.ParseFiles("web/index.html", "web/round.html"))
|
14
|
15
|
)
|
15
|
16
|
|
|
17
|
+func (s *WebService) serveTemplate(w http.ResponseWriter, data interface{}, templateName string) {
|
|
18
|
+ var templates = cachedTemplates
|
|
19
|
+ if s.noCache {
|
|
20
|
+ templates = template.Must(template.ParseFiles("web/index.html", "web/round.html"))
|
|
21
|
+ }
|
|
22
|
+
|
|
23
|
+ err := templates.ExecuteTemplate(w, templateName, data)
|
|
24
|
+ if err != nil {
|
|
25
|
+ log.Println("Error while rendering template", err)
|
|
26
|
+ http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
27
|
+ }
|
|
28
|
+
|
|
29
|
+}
|
|
30
|
+
|
16
|
31
|
func (s *WebService) IndexHandler(w http.ResponseWriter, r *http.Request) {
|
17
|
32
|
if r.URL.Path != "/" {
|
18
|
33
|
http.Error(w, "Not Found", http.StatusNotFound)
|
|
@@ -31,8 +46,9 @@ func (s *WebService) IndexHandler(w http.ResponseWriter, r *http.Request) {
|
31
|
46
|
make([]*Song, 0),
|
32
|
47
|
}
|
33
|
48
|
|
34
|
|
- session, err := getSession(r)
|
|
49
|
+ session, _ := getSession(r)
|
35
|
50
|
if session != nil {
|
|
51
|
+ log.Println("Find all songs for user", session.username)
|
36
|
52
|
songs, err := s.db.FindAllEntries(session.username)
|
37
|
53
|
if err != nil {
|
38
|
54
|
log.Println("Error while reading entries from database", err)
|
|
@@ -42,25 +58,15 @@ func (s *WebService) IndexHandler(w http.ResponseWriter, r *http.Request) {
|
42
|
58
|
data.Songs = songs
|
43
|
59
|
data.Username = session.username
|
44
|
60
|
data.Spotify = session.spotify
|
45
|
|
- }
|
46
|
61
|
|
47
|
|
- if s.spotify.client != nil {
|
48
|
|
- token, err := s.spotify.client.Token()
|
49
|
|
- if err == nil {
|
50
|
|
- data.SpotifyExpiry = token.Expiry.Format(time.RFC822Z)
|
|
62
|
+ if session.spotifyClient != nil {
|
|
63
|
+ token, err := session.spotifyClient.Token()
|
|
64
|
+ if err == nil {
|
|
65
|
+ data.SpotifyExpiry = token.Expiry.Format(time.RFC822Z)
|
|
66
|
+ }
|
51
|
67
|
}
|
52
|
68
|
}
|
53
|
|
-
|
54
|
|
- var templates = cachedTemplates
|
55
|
|
- if s.noCache {
|
56
|
|
- templates = template.Must(template.ParseFiles("web/index.html"))
|
57
|
|
- }
|
58
|
|
-
|
59
|
|
- err = templates.ExecuteTemplate(w, "index.html", data)
|
60
|
|
- if err != nil {
|
61
|
|
- log.Println("Error while rendering template", err)
|
62
|
|
- http.Error(w, err.Error(), http.StatusInternalServerError)
|
63
|
|
- }
|
|
69
|
+ s.serveTemplate(w, data, "index.html")
|
64
|
70
|
}
|
65
|
71
|
|
66
|
72
|
func getTrackID(url string) string {
|
|
@@ -96,11 +102,15 @@ func (s *WebService) UpdateHandler(w http.ResponseWriter, r *http.Request) {
|
96
|
102
|
url := r.Form.Get("url")
|
97
|
103
|
|
98
|
104
|
if artist == "" && title == "" && url != "" {
|
99
|
|
- if s.spotify.client == nil {
|
|
105
|
+ var client = s.spotify.client
|
|
106
|
+ if client == nil {
|
|
107
|
+ client = session.spotifyClient
|
|
108
|
+ }
|
|
109
|
+ if client == nil {
|
100
|
110
|
http.Error(w, "No Spotify token available", http.StatusInternalServerError)
|
101
|
111
|
return
|
102
|
112
|
}
|
103
|
|
- token, err := s.spotify.client.Token()
|
|
113
|
+ token, err := client.Token()
|
104
|
114
|
if err != nil {
|
105
|
115
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
106
|
116
|
return
|
|
@@ -111,7 +121,7 @@ func (s *WebService) UpdateHandler(w http.ResponseWriter, r *http.Request) {
|
111
|
121
|
|
112
|
122
|
log.Println("Resolving Spotify URL")
|
113
|
123
|
trackID := getTrackID(url)
|
114
|
|
- track, err := s.spotify.client.GetTrack(spotify.ID(trackID))
|
|
124
|
+ track, err := client.GetTrack(spotify.ID(trackID))
|
115
|
125
|
|
116
|
126
|
if err != nil {
|
117
|
127
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
@@ -182,20 +192,96 @@ func (s *WebService) CallbackHandler(w http.ResponseWriter, r *http.Request) {
|
182
|
192
|
http.Error(w, "Couldn't get token", http.StatusForbidden)
|
183
|
193
|
return
|
184
|
194
|
}
|
|
195
|
+ client := s.spotify.auth.NewClient(token)
|
|
196
|
+ profile, err := client.CurrentUser()
|
|
197
|
+ if err != nil {
|
|
198
|
+ http.Error(w, "Couldn't load profile from Spotify", http.StatusInternalServerError)
|
|
199
|
+ return
|
|
200
|
+ }
|
185
|
201
|
session, err := getSession(r)
|
|
202
|
+ if session == nil {
|
|
203
|
+ if err != nil {
|
|
204
|
+ log.Println("Error while trying to read current session", err)
|
|
205
|
+ }
|
|
206
|
+ log.Println("Trying to login with spotify ID", profile.ID)
|
|
207
|
+ cookie, err := tryLoginWithSpotify(s.db, profile.ID)
|
|
208
|
+ if err != nil {
|
|
209
|
+ http.Error(w, "Couldn't login with Spotify profile", http.StatusInternalServerError)
|
|
210
|
+ return
|
|
211
|
+ }
|
|
212
|
+ session, _ := getSessionById(cookie.Value)
|
|
213
|
+ session.spotifyClient = &client
|
|
214
|
+
|
|
215
|
+ log.Println("Logged in user spotify ID", profile.ID)
|
|
216
|
+ http.SetCookie(w, &cookie)
|
|
217
|
+ http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
|
|
218
|
+ return
|
|
219
|
+ } else {
|
|
220
|
+ session.spotify = profile.ID
|
|
221
|
+ session.spotifyClient = &client
|
|
222
|
+ http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
|
|
223
|
+ return
|
|
224
|
+ }
|
|
225
|
+ // TODO: when?
|
|
226
|
+ if profile.ID == "lamperi" {
|
|
227
|
+ s.spotify.client = &client
|
|
228
|
+ }
|
|
229
|
+}
|
|
230
|
+
|
|
231
|
+func (s *WebService) RoundHandler(w http.ResponseWriter, r *http.Request) {
|
|
232
|
+ data := struct {
|
|
233
|
+ Username string
|
|
234
|
+ Spotify string
|
|
235
|
+ SpotifyExpiry string
|
|
236
|
+ Songs []*Song
|
|
237
|
+ SubmitterPublic bool
|
|
238
|
+ RoundInfo *RoundInfo
|
|
239
|
+ }{
|
|
240
|
+ "",
|
|
241
|
+ "",
|
|
242
|
+ "",
|
|
243
|
+ make([]*Song, 0),
|
|
244
|
+ false,
|
|
245
|
+ nil,
|
|
246
|
+ }
|
|
247
|
+
|
|
248
|
+ round := strings.TrimPrefix(r.URL.Path, "/round/")
|
|
249
|
+ roundNum, err := strconv.Atoi(round)
|
186
|
250
|
if err != nil {
|
187
|
|
- http.Error(w, "Couldn't get session", http.StatusInternalServerError)
|
|
251
|
+ http.Error(w, err.Error(), http.StatusBadRequest)
|
188
|
252
|
return
|
189
|
253
|
}
|
190
|
|
- client := s.spotify.auth.NewClient(token)
|
191
|
|
- s.spotify.client = &client
|
192
|
|
- profile, err := s.spotify.client.CurrentUser()
|
|
254
|
+ roundInfo, err := s.db.FindRoundInfo(roundNum)
|
193
|
255
|
if err != nil {
|
194
|
|
- http.Error(w, "Couldn't load profile from Spotify", http.StatusInternalServerError)
|
|
256
|
+ http.Error(w, err.Error(), http.StatusInternalServerError)
|
195
|
257
|
return
|
196
|
258
|
}
|
197
|
|
- session.spotify = profile.ID
|
198
|
|
- http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
|
|
259
|
+ if roundInfo == nil {
|
|
260
|
+ http.Error(w, "No such panel", http.StatusNotFound)
|
|
261
|
+ return
|
|
262
|
+ }
|
|
263
|
+ data.RoundInfo = roundInfo
|
|
264
|
+ session, err := getSession(r)
|
|
265
|
+ if session != nil {
|
|
266
|
+ data.Username = session.username
|
|
267
|
+ data.Spotify = session.spotify
|
|
268
|
+ }
|
|
269
|
+ songs, err := s.db.FindAllRoundEntries(roundNum)
|
|
270
|
+ if err != nil {
|
|
271
|
+ log.Println("Error while reading entries from database", err)
|
|
272
|
+ http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
273
|
+ return
|
|
274
|
+ }
|
|
275
|
+ data.Songs = songs
|
|
276
|
+ data.SubmitterPublic = roundInfo.End.Before(time.Now())
|
|
277
|
+
|
|
278
|
+ if s.spotify.client != nil {
|
|
279
|
+ token, err := s.spotify.client.Token()
|
|
280
|
+ if err == nil {
|
|
281
|
+ data.SpotifyExpiry = token.Expiry.Format(time.RFC822Z)
|
|
282
|
+ }
|
|
283
|
+ }
|
|
284
|
+ s.serveTemplate(w, data, "round.html")
|
199
|
285
|
}
|
200
|
286
|
|
201
|
287
|
type WebService struct {
|
|
@@ -215,6 +301,7 @@ func webStart(listenAddr string, db *DB, spotify *AppSpotify) {
|
215
|
301
|
mux.Handle("/js/", fs)
|
216
|
302
|
mux.Handle("/favicon.ico", fs)
|
217
|
303
|
mux.HandleFunc("/", service.IndexHandler)
|
|
304
|
+ mux.HandleFunc("/round/", service.RoundHandler)
|
218
|
305
|
mux.HandleFunc("/update", service.UpdateHandler)
|
219
|
306
|
mux.HandleFunc("/login", service.LoginHandler)
|
220
|
307
|
mux.HandleFunc("/spotify", service.SpotifyHandler)
|