160 lines
3.8 KiB
Go
160 lines
3.8 KiB
Go
package main
|
|
|
|
//go:generate esc -o assets.go assets templates songs
|
|
|
|
import (
|
|
"bufio"
|
|
"flag"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"log"
|
|
"net/http"
|
|
"os"
|
|
"strings"
|
|
|
|
"golang.org/x/crypto/ssh/terminal"
|
|
|
|
"github.com/gorilla/handlers"
|
|
"github.com/gorilla/mux"
|
|
"github.com/gorilla/sessions"
|
|
"github.com/justinas/alice"
|
|
)
|
|
|
|
var port int
|
|
var ip string
|
|
var dir string
|
|
|
|
var sessionSecret = "AChKj7na128CrKPPG0Rc"
|
|
var sessionStore = sessions.NewCookieStore([]byte(sessionSecret))
|
|
var r *mux.Router
|
|
var site *siteData
|
|
var model *model
|
|
|
|
type siteData struct {
|
|
Title string
|
|
DevMode bool
|
|
}
|
|
|
|
func init() {
|
|
const (
|
|
portDefault = 8080
|
|
portUsage = "the port to listen on"
|
|
ipDefault = "127.0.0.1"
|
|
ipUsage = "the ip mask to listen for connections from"
|
|
dirDefault = "./"
|
|
dirUsage = "the directory to serve the app out of\nThere should be a 'songs' directory here."
|
|
)
|
|
flag.StringVar(&ip, "ip", ipDefault, ipUsage)
|
|
flag.IntVar(&port, "port", portDefault, portUsage)
|
|
flag.StringVar(&dir, "dir", dirDefault, dirUsage)
|
|
if !strings.HasSuffix(dir, "/") {
|
|
dir = dir + "/"
|
|
}
|
|
}
|
|
|
|
func main() {
|
|
flag.Parse()
|
|
loadModel()
|
|
|
|
r := mux.NewRouter()
|
|
r.StrictSlash(true)
|
|
|
|
//r.PathPrefix("/assets/").Handler(http.FileServer(FS(site.DevMode)))
|
|
// Public Subrouter
|
|
pub := r.PathPrefix("/").Subrouter()
|
|
pub.HandleFunc("/", handleMain)
|
|
|
|
admin := r.PathPrefix("/admin").Subrouter()
|
|
admin.HandleFunc("/", handleAdmin)
|
|
admin.HandleFunc("/dologin", handleAdminDoLogin)
|
|
admin.HandleFunc("/dologout", handleAdminDoLogout)
|
|
admin.HandleFunc("/{action}", handleAdmin)
|
|
|
|
http.Handle("/", r)
|
|
|
|
chain := alice.New(loggingHandler).Then(r)
|
|
|
|
listenAt := fmt.Sprintf("%s:%d", ip, port)
|
|
fmt.Println("Songbook Server listening at", listenAt)
|
|
log.Fatal(http.ListenAndServe(listenAt, chain))
|
|
}
|
|
|
|
func loadModel() {
|
|
model := NewModel(dir)
|
|
site = new(siteData)
|
|
if !model.hasUser() {
|
|
reader := bufio.NewReader(os.Stdin)
|
|
fmt.Println("Create new Admin user")
|
|
fmt.Print("Username: ")
|
|
un, _ := reader.ReadString('\n')
|
|
un = strings.TrimSpace(un)
|
|
var pw1, pw2 []byte
|
|
for string(pw1) != string(pw2) || string(pw1) == "" {
|
|
fmt.Print("Password: ")
|
|
pw1, _ = terminal.ReadPassword(0)
|
|
fmt.Println("")
|
|
fmt.Print("Repeat Password: ")
|
|
pw2, _ = terminal.ReadPassword(0)
|
|
fmt.Println("")
|
|
if string(pw1) != string(pw2) {
|
|
fmt.Println("Entered Passwords don't match!")
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
func handleMain(w http.ResponseWriter, req *http.Request) {
|
|
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
|
output, err := ioutil.ReadFile(dir + "currentsongs.html")
|
|
if err != nil {
|
|
output = []byte("Error reading current songs")
|
|
}
|
|
fmt.Fprint(w, string(output))
|
|
}
|
|
|
|
func initPageData(w http.ResponseWriter, req *http.Request) *pageData {
|
|
if site.DevMode {
|
|
w.Header().Set("Cache-Control", "no-cache")
|
|
}
|
|
p := new(pageData)
|
|
// Get the session
|
|
var err error
|
|
var s *sessions.Session
|
|
if s, err = sessionStore.Get(req, "songbook"); err != nil {
|
|
http.Error(w, err.Error(), 500)
|
|
return p
|
|
}
|
|
p.session = new(pageSession)
|
|
p.session.session = s
|
|
p.session.req = req
|
|
p.session.w = w
|
|
|
|
// First check if we're logged in
|
|
userName, _ := p.session.getStringValue("name")
|
|
_ = userName
|
|
|
|
p.Site = site
|
|
p.SubTitle = "Songbook"
|
|
p.Stylesheets = make([]string, 0, 0)
|
|
p.Stylesheets = append(p.Stylesheets, "/assets/vendor/css/pure-min.css")
|
|
p.Stylesheets = append(p.Stylesheets, "/assets/vendor/css/grids-responsive-min.css")
|
|
p.Stylesheets = append(p.Stylesheets, "/assets/vendor/font-awesome/css/font-awesome.min.css")
|
|
p.Stylesheets = append(p.Stylesheets, "/assets/css/gjvote.css")
|
|
|
|
p.HeaderScripts = make([]string, 0, 0)
|
|
|
|
p.Scripts = make([]string, 0, 0)
|
|
|
|
p.FlashMessage, p.FlashClass = p.session.getFlashMessage()
|
|
if p.FlashClass == "" {
|
|
p.FlashClass = "hidden"
|
|
}
|
|
|
|
return p
|
|
}
|
|
|
|
func loggingHandler(h http.Handler) http.Handler {
|
|
return handlers.LoggingHandler(os.Stdout, h)
|
|
}
|