package webserver import ( "math/rand" irc "git.martyn.berlin/martyn/karaokards/internal/irc" "github.com/gorilla/handlers" "github.com/gorilla/mux" "fmt" "html/template" "net/http" "os" "strings" "time" ) //var store = sessions.NewCookieStore(os.Getenv("SESSION_KEY")) var ircBot *irc.KardBot func HealthHandler(response http.ResponseWriter, request *http.Request) { response.Header().Add("Content-type", "text/plain") fmt.Fprint(response, "I'm okay jack!") } func NotFoundHandler(response http.ResponseWriter, request *http.Request) { response.Header().Add("X-Template-File", "html"+request.URL.Path) response.WriteHeader(404) tmpl := template.Must(template.ParseFiles("web/404.html")) tmpl.Execute(response, nil) } func CSSHandler(response http.ResponseWriter, request *http.Request) { response.Header().Add("Content-type", "text/css") tmpl := template.Must(template.ParseFiles("web/cover.css")) tmpl.Execute(response, nil) } func RootHandler(response http.ResponseWriter, request *http.Request) { request.URL.Path = "/index.html" TemplateHandler(response, request) } func TemplateHandler(response http.ResponseWriter, request *http.Request) { response.Header().Add("X-Template-File", "web"+request.URL.Path) type TemplateData struct { Prompt string AvailCount int ChannelCount int MessageCount int } // tmpl, err := template.New("html"+request.URL.Path).Funcs(template.FuncMap{ // "ToUpper": strings.ToUpper, // "ToLower": strings.ToLower, // }).ParseFiles("html"+request.URL.Path) _ = strings.ToLower("Hello") if strings.Index(request.URL.Path, "/") < 0 { http.Error(response, "No slashes wat - "+request.URL.Path, http.StatusInternalServerError) return } basenameSlice := strings.Split(request.URL.Path, "/") basename := basenameSlice[len(basenameSlice)-1] //fmt.Fprintf(response, "%q", basenameSlice) tmpl, err := template.New(basename).Funcs(template.FuncMap{ "ToUpper": strings.ToUpper, "ToLower": strings.ToLower, }).ParseFiles("web" + request.URL.Path) if err != nil { http.Error(response, err.Error(), http.StatusInternalServerError) return // NotFoundHandler(response, request) // return } var td = TemplateData{ircBot.Prompts[rand.Intn(len(ircBot.Prompts))], len(ircBot.Prompts), len(ircBot.ChannelData), 0} err = tmpl.Execute(response, td) if err != nil { http.Error(response, err.Error(), http.StatusInternalServerError) return } } func LeaveHandler(response http.ResponseWriter, request *http.Request) { request.URL.Path = "/bye.html" TemplateHandler(response, request) } func AdminHandler(response http.ResponseWriter, request *http.Request) { vars := mux.Vars(request) if vars["key"] != ircBot.ChannelData[vars["channel"]].AdminKey { UnauthorizedHandler(response, request) return } type TemplateData struct { Channel string Command string ExtraStrings string SinceTime time.Time Leaving bool } channelData := ircBot.ChannelData[vars["channel"]] var td = TemplateData{channelData.Name, channelData.Command, channelData.ExtraStrings, channelData.JoinTime, false} if request.Method == "POST" { request.ParseForm() if strings.Join(request.PostForm["leave"], ",") == "Leave twitch channel" { td.Leaving = true } else if strings.Join(request.PostForm["reallyleave"], ",") == "Really leave twitch channel" { delete(ircBot.ChannelData, vars["channel"]) ircBot.Database.Delete("channelData", vars["channel"]) ircBot.LeaveChannel(vars["channel"]) LeaveHandler(response, request) return } sourceData := ircBot.ChannelData[vars["channel"]] if strings.Join(request.PostForm["Command"], ",") != "" { sourceData.Command = strings.Join(request.PostForm["Command"], ",") td.Command = sourceData.Command ircBot.ChannelData[vars["channel"]] = sourceData } if strings.Join(request.PostForm["ExtraStrings"], ",") != sourceData.ExtraStrings { sourceData.ExtraStrings = strings.Join(request.PostForm["ExtraStrings"], ",") td.ExtraStrings = sourceData.ExtraStrings ircBot.ChannelData[vars["channel"]] = sourceData } ircBot.Database.Write("channelData", vars["channel"], sourceData) } tmpl := template.Must(template.ParseFiles("web/admin.html")) tmpl.Execute(response, td) } func UnauthorizedHandler(response http.ResponseWriter, request *http.Request) { response.Header().Add("X-Template-File", "html"+request.URL.Path) response.WriteHeader(401) tmpl := template.Must(template.ParseFiles("web/401.html")) tmpl.Execute(response, nil) } func HandleHTTP(passedIrcBot *irc.KardBot) { ircBot = passedIrcBot r := mux.NewRouter() loggedRouter := handlers.LoggingHandler(os.Stdout, r) r.NotFoundHandler = http.HandlerFunc(NotFoundHandler) r.HandleFunc("/", RootHandler) r.HandleFunc("/healthz", HealthHandler) r.HandleFunc("/web/{.*}", TemplateHandler) r.PathPrefix("/static/").Handler(http.FileServer(http.Dir("./web/"))) r.HandleFunc("/cover.css", CSSHandler) r.HandleFunc("/admin/{channel}/{key}", AdminHandler) http.Handle("/", r) srv := &http.Server{ Handler: loggedRouter, Addr: "0.0.0.0:5353", WriteTimeout: 15 * time.Second, ReadTimeout: 15 * time.Second, } fmt.Println("Listening on 0.0.0.0:5353") srv.ListenAndServe() }