statbot/statbotweb.go

169 lines
4.1 KiB
Go
Raw Normal View History

package main
import (
"fmt"
"log"
"net/http"
"os"
"text/template"
"github.com/gorilla/context"
"github.com/gorilla/mux"
"github.com/gorilla/sessions"
)
// SiteData is the basic data needed for the site/pages
type SiteData struct {
Title string
SubTitle string
Port int
SessionName string
Stylesheets []string
Scripts []string
Flash flashMessage // Quick message at top of page
Menu []menuItem // Top-aligned menu items
BottomMenu []menuItem // Bottom-aligned menu items
// Any other template data
TemplateData interface{}
}
type flashMessage struct {
Message string
Status string
}
type menuItem struct {
Text string
Link string
Active bool
}
var site SiteData
var sessionStore = sessions.NewCookieStore([]byte("gostatbot secret cookie nobody will guess"))
var r *mux.Router
// This is the main function for the web server
func statWebMain(slack *Slack) {
site.Title = "stat_bot"
site.SubTitle = ""
site.Port = 3000
site.SessionName = "statbot"
r = mux.NewRouter()
r.StrictSlash(true)
assetHandler := http.FileServer(http.Dir("./assets/"))
http.Handle("/assets/", http.StripPrefix("/assets/", assetHandler))
r.HandleFunc("/", handleStats)
http.Handle("/", r)
go func() {
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", site.Port), context.ClearHandler(http.DefaultServeMux)))
}()
}
func initRequest(w http.ResponseWriter, req *http.Request) {
site.SubTitle = ""
site.Stylesheets = make([]string, 0, 0)
site.Stylesheets = append(site.Stylesheets, "/assets/css/pure-min.css")
site.Stylesheets = append(site.Stylesheets, "/assets/css/statbot.css")
site.Stylesheets = append(site.Stylesheets, "https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css")
site.Scripts = make([]string, 0, 0)
site.Menu = make([]menuItem, 0, 0)
site.Menu = append(site.Menu, menuItem{Text: "Stats", Link: "/stats/"})
site.BottomMenu = make([]menuItem, 0, 0)
site.BottomMenu = append(site.BottomMenu, menuItem{Text: "Admin", Link: "/admin/"})
}
func handleStats(w http.ResponseWriter, req *http.Request) {
initRequest(w, req)
2015-10-30 13:10:05 +00:00
type StatData struct {
TotalChannelMessages int
Error string
2015-10-30 13:10:05 +00:00
}
2015-10-30 13:10:05 +00:00
// Get the global stats
var s StatData
if stats, err := getAllUsersStats(); err == nil {
s = StatData{TotalChannelMessages: stats["channel-message"], Error: ""}
} else {
s = StatData{TotalChannelMessages: -1, Error: fmt.Sprintf("%s", err)}
}
site.TemplateData = s
2015-10-30 13:10:05 +00:00
setMenuItemActive("Stats")
showPage("stats.html", site, w)
}
// showPage
// Load a template and all of the surrounding templates
func showPage(tmplName string, tmplData interface{}, w http.ResponseWriter) error {
for _, tmpl := range []string{
"htmlheader.html",
"menu.html",
"header.html",
tmplName,
"footer.html",
"htmlfooter.html",
} {
if err := outputTemplate(tmpl, tmplData, w); err != nil {
writeToLog(fmt.Sprintf("%s\n", err))
return err
}
}
return nil
}
// outputTemplate
// Spit out a template
func outputTemplate(tmplName string, tmplData interface{}, w http.ResponseWriter) error {
_, err := os.Stat("templates/" + tmplName)
if err == nil {
t := template.New(tmplName)
t, _ = t.ParseFiles("templates/" + tmplName)
return t.Execute(w, tmplData)
}
return fmt.Errorf("WebServer: Cannot load template (templates/%s): File not found", tmplName)
}
// setMenuItemActive
// Sets a menu item to active, all others to inactive
func setMenuItemActive(which string) {
for i := range site.Menu {
if site.Menu[i].Text == which {
site.Menu[i].Active = true
} else {
site.Menu[i].Active = false
}
}
}
func getSessionStringValue(key string, w http.ResponseWriter, req *http.Request) (string, error) {
session, err := sessionStore.Get(req, site.SessionName)
if err != nil {
return "", err
}
val := session.Values[key]
var retVal string
var ok bool
if retVal, ok = val.(string); !ok {
return "", fmt.Errorf("Unable to create string from %s", key)
}
return retVal, nil
}
func assertError(err error, w http.ResponseWriter) bool {
if err != nil {
http.Error(w, err.Error(), 500)
return true
}
return false
}