package main import ( "html/template" "net/http" "strconv" ) var ( cachedTemplates = template.Must(template.ParseFiles("web/index.html")) songsChan chan *SongEntry ) func indexHandler(w http.ResponseWriter, r *http.Request) { if r.URL.Path != "/" { http.Error(w, "Not Found", http.StatusNotFound) return } alsoEmptySongs := SongsFile{ Songs: make([]*SongEntry, 52), } for week := 1; week <= 52; week++ { alsoEmptySongs.Songs[week-1] = &SongEntry{Week: week} } username := "" session, err := getSession(r) if session != nil { songs, err := loadDb() if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } for _, song := range songs.Songs { alsoEmptySongs.Songs[song.Week-1] = song } username = session.username } var templates = cachedTemplates if true { templates = template.Must(template.ParseFiles("web/index.html")) } data := struct { Username string Songs []*SongEntry }{ username, alsoEmptySongs.Songs, } err = templates.ExecuteTemplate(w, "index.html", data) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } } func updateHandler(w http.ResponseWriter, r *http.Request) { if r.URL.Path != "/update" { http.Error(w, "Forbidden", http.StatusForbidden) return } err := r.ParseForm() if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } week, err := strconv.Atoi(r.Form.Get("week")) if err != nil { http.Error(w, "week parameter not provided", http.StatusBadRequest) return } artist := r.Form.Get("artist") title := r.Form.Get("title") url := r.Form.Get("url") sync := r.Form.Get("sync") songs, err := loadDb() if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } matched := false for _, song := range songs.Songs { if song.Week == week { song.Artist = artist song.Title = title song.URL = url if song.Sync && sync != "on" { song.Sync = false } songsChan <- song matched = true } } if !matched { song := &SongEntry{ Artist: artist, Title: title, URL: url, Week: week, } songs.Songs = append(songs.Songs, song) songsChan <- song } err = saveDb(songs) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } http.Redirect(w, r, "/", http.StatusTemporaryRedirect) } func loginHandler(w http.ResponseWriter, r *http.Request) { err := r.ParseForm() if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } username := r.Form.Get("username") password := r.Form.Get("password") remember := r.Form.Get("remember") longer := remember == "remember-me" cookie, err := tryLogin(username, password, longer) if err != nil { http.Error(w, err.Error(), http.StatusForbidden) return } http.SetCookie(w, &cookie) http.Redirect(w, r, "/", http.StatusTemporaryRedirect) } func webStart(modifiedSongChan chan *SongEntry) { songsChan = modifiedSongChan mux := http.NewServeMux() fs := http.FileServer(http.Dir("web")) mux.Handle("/css/", fs) mux.Handle("/fonts/", fs) mux.Handle("/js/", fs) mux.Handle("/favicon.ico", fs) mux.HandleFunc("/", indexHandler) mux.HandleFunc("/update", updateHandler) mux.HandleFunc("/login", loginHandler) http.ListenAndServe("localhost:8080", mux) }