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)
}